-
Compteur de contenus
25 878 -
Inscription
-
Dernière visite
-
Jours gagnés
1 257
Tout ce qui a été posté par Lazer
-
Bienvenue sur le forum
-
Voici 2 petits scripts LUA pour explorer les objets accessibles dans les QuickApps et les Scènes sur HC3. Quand on développe, il est toujours intéressant de découvrir des variables et fonctions non documentées, ou voir quelles fonctions sont disponibles dans les QuickApps ou dans les Scènes car il y a pas mal de différences. Cela permettra aussi de suivre les ajouts de fonctions par Fibaro au fur et à mesure des nouveaux firmwares. Les résultats donnés dans ce post sont été obtenus avec le firmware 5.031.33 QuickApps Créer un QA avec un seul bouton pour lancer l'exécution du code : function QuickApp:browse(racine, tableau) local variables, functions, objects = {}, {}, {} for k, v in pairs(tableau) do if type(v) == "table" then if v ~= _G then local variables2, functions2, objects2 = self:browse(racine .. k .. ".", v) for i = 1, #variables2 do variables[#variables+1] = variables2[i] end for i = 1, #functions2 do functions[#functions+1] = functions2[i] end for i = 1, #objects2 do objects[#objects+1] = objects2[i] end end elseif type(v) == "function" then functions[#functions+1] = racine .. k .. '()' elseif type(v) == "string" then variables[#variables+1] = racine .. k .. ' = "' .. v .. '"' elseif type(v) == "number" then variables[#variables+1] = racine .. k .. ' = ' .. tostring(v) elseif type(v) == "integer" then variables[#variables+1] = racine .. k .. ' = ' .. tostring(v) elseif type(v) == "boolean" then variables[#variables+1] = racine .. k .. ' = ' .. tostring(v) else objects[#objects+1] = racine .. k .. " => " .. type(v) end end table.sort(variables) table.sort(functions) table.sort(objects) return variables, functions, objects end function QuickApp:onButtonClic(event) self:trace("") local variables, functions, objects = self:browse("", _G) self:trace("Variables :") for _, v in ipairs(variables) do self:debug(v) end self:trace("Fonctions :") for _, v in ipairs(functions) do self:debug(v) end self:trace("Objets :") for _, v in ipairs(objects) do self:debug(v) end self:debug("Terminé") end function QuickApp:onInit() end Résultat : Variables : _VERSION = "Lua 5.3" __TAG = "QuickApp152" json._COPYRIGHT = "Copyright (c) 2007-2017 Thomas Harning Jr. " json._DESCRIPTION = "LuaJSON : customizable JSON decoder/encoder" json._VERSION = "1.3.4" json.decode.simple.array.allowEmptyElement = false json.decode.simple.array.trailingComma = true json.decode.simple.calls.allowEmptyElement = false json.decode.simple.calls.allowUndefined = false json.decode.simple.calls.trailingComma = true json.decode.simple.number.exp = true json.decode.simple.number.frac = true json.decode.simple.number.hex = false json.decode.simple.number.inf = true json.decode.simple.number.nan = true json.decode.simple.object.allowEmptyElement = false json.decode.simple.object.identifier = true json.decode.simple.object.number = true json.decode.simple.object.trailingComma = true json.decode.simple.others.allowUndefined = true json.decode.simple.others.null = false json.decode.simple.others.undefined = false json.decode.simple.strings.additionalEscapes = false json.decode.simple.strings.badChars = "" json.decode.simple.strings.strict_quotes = false json.decode.strict.array.allowEmptyElement = false json.decode.strict.array.trailingComma = false json.decode.strict.calls.allowEmptyElement = false json.decode.strict.calls.allowUndefined = false json.decode.strict.calls.trailingComma = true json.decode.strict.initialObject = true json.decode.strict.nothrow = false json.decode.strict.number.exp = true json.decode.strict.number.frac = true json.decode.strict.number.hex = false json.decode.strict.number.inf = false json.decode.strict.number.nan = false json.decode.strict.object.allowEmptyElement = false json.decode.strict.object.identifier = false json.decode.strict.object.number = false json.decode.strict.object.trailingComma = false json.decode.strict.others.allowUndefined = false json.decode.strict.strings.additionalEscapes = false json.decode.strict.strings.badChars = " " json.decode.strict.strings.strict_quotes = true json.decode.strict.unicodeWhitespace = true json.decode.util.DecimalLpegVersion = 1.0 json.encode.default.number.inf = true json.encode.default.number.nan = true json.encode.default.others.allowUndefined = true json.encode.default.strings.encodeSet = "\"/%z-" json.encode.default.strings.xEncode = false json.encode.strict.initialObject = true json.encode.strict.number.inf = false json.encode.strict.number.nan = false json.encode.strict.others.allowUndefined = false json.encode.strict.strings.encodeSet = "\"/%z-" json.encode.strict.strings.xEncode = false logger.DEBUG = 1 logger.ERROR = 4 logger.FATAL = 5 logger.INFO = 2 logger.TRACE = 0 logger.WARNING = 3 math.huge = inf math.maxinteger = 9223372036854775807 math.mininteger = -9223372036854775808 math.pi = 3.1415926535898 plugin.mainDeviceId = 152 utf8.charpattern = "[-�-�][�-�]*" Fonctions : __assert_type() __fibaroSleep() __fibaroUseAsyncHandler() __fibaro_add_debug_message() __fibaro_get_device() __fibaro_get_device_property() __fibaro_get_devices() __fibaro_get_global_variable() __fibaro_get_room() __fibaro_get_scene() __print() __ternary() api.delete() api.get() api.post() api.put() assert() bit32.arshift() bit32.band() bit32.bnot() bit32.bor() bit32.btest() bit32.bxor() bit32.extract() bit32.lrotate() bit32.lshift() bit32.replace() bit32.rrotate() bit32.rshift() class() clearInterval() clearTimeout() collectgarbage() configure() error() fibaro.__houseAlarm() fibaro.alarm() fibaro.alert() fibaro.call() fibaro.callGroupAction() fibaro.clearTimeout() fibaro.debug() fibaro.emitCustomEvent() fibaro.error() fibaro.get() fibaro.getDevicesID() fibaro.getGlobalVariable() fibaro.getIds() fibaro.getName() fibaro.getRoomID() fibaro.getRoomName() fibaro.getRoomNameByDeviceID() fibaro.getSectionID() fibaro.getType() fibaro.getValue() fibaro.profile() fibaro.scene() fibaro.setGlobalVariable() fibaro.setTimeout() fibaro.sleep() fibaro.trace() fibaro.useAsyncHandler() fibaro.wakeUpDeadDevice() fibaro.warning() getHierarchy() ipairs() json.array() json.decode.decode() json.decode.getDecoder() json.decode.simple.object.setObjectKey() json.decode.simple.strings.decodeUnicode() json.decode.strict.object.setObjectKey() json.decode.strict.others.null() json.decode.strict.others.undefined() json.decode.strict.strings.decodeUnicode() json.decode.util.denied() json.decode.util.get_invalid_character_info() json.decode.util.setObjectKeyForceNumber() json.decode.util.unexpected() json.encode.default.array.isArray() json.encode.default.others.null() json.encode.default.others.undefined() json.encode.encode() json.encode.getEncoder() json.encode.strict.array.isArray() json.encode.strict.others.null() json.encode.strict.others.undefined() json.null() json.util.InitArray() json.util.IsArray() json.util.buildCall() json.util.clone() json.util.decodeCall() json.util.doOptionMerge() json.util.isCall() json.util.merge() json.util.null() json.util.printValue() json.util.undefined() logger.debug() logger.error() logger.fatal() logger.getLevel() logger.info() logger.log() logger.setLevel() logger.trace() logger.warning() math.abs() math.acos() math.asin() math.atan() math.atan2() math.ceil() math.cos() math.cosh() math.deg() math.exp() math.floor() math.fmod() math.frexp() math.ldexp() math.log() math.log10() math.max() math.min() math.modf() math.pow() math.rad() math.random() math.randomseed() math.sin() math.sinh() math.sqrt() math.tan() math.tanh() math.tointeger() math.type() math.ult() next() onAction() onUIEvent() os.clock() os.date() os.difftime() os.exit() os.time() pairs() pcall() plugin.createChildDevice() plugin.deleteDevice() plugin.getChildDevices() plugin.getDevice() plugin.getProperty() plugin.restart() print() property() rawlen() select() setInterval() setTimeout() string.byte() string.char() string.dump() string.find() string.format() string.gmatch() string.gsub() string.len() string.lower() string.match() string.pack() string.packsize() string.rep() string.reverse() string.split() string.starts() string.sub() string.unpack() string.upper() super() table.concat() table.insert() table.move() table.pack() table.remove() table.sort() table.unpack() tonumber() tostring() type() unpack() utf8.char() utf8.codepoint() utf8.codes() utf8.len() utf8.offset() xpcall() Objets : Device => userdata Hierarchy => userdata QuickApp => userdata QuickAppBase => userdata QuickAppChild => userdata core.EventTarget => userdata json.decode.simple.strings.escapeCheck => userdata json.decode.strict.strings.escapeCheck => userdata json.decode.util.ascii_ignored => userdata json.decode.util.ascii_space => userdata json.decode.util.comment => userdata json.decode.util.comments.c => userdata json.decode.util.comments.cpp => userdata json.decode.util.hex => userdata json.decode.util.hexpair => userdata json.decode.util.identifier => userdata json.decode.util.unicode_ignored => userdata json.decode.util.unicode_space => userdata mqtt.Client => userdata mqtt.ConnectReturnCode => userdata mqtt.QoS => userdata net.HTTPClient => userdata net.TCPSocket => userdata quickApp => userdata Scènes Créer une scène LUA en exécution manuelle avec ce code : local function browse(racine, tableau) local variables, functions, objects = {}, {}, {} for k, v in pairs(tableau) do if type(v) == "table" then if v ~= _G and v ~= _ENV and v ~= __index and k ~= "__index" then local variables2, functions2, objects2 = browse(racine .. k .. ".", v) for i = 1, #variables2 do variables[#variables+1] = variables2[i] end for i = 1, #functions2 do functions[#functions+1] = functions2[i] end for i = 1, #objects2 do objects[#objects+1] = objects2[i] end end elseif type(v) == "function" then functions[#functions+1] = racine .. k .. '()' elseif type(v) == "string" then variables[#variables+1] = racine .. k .. ' = "' .. v .. '"' elseif type(v) == "number" then variables[#variables+1] = racine .. k .. ' = ' .. tostring(v) elseif type(v) == "integer" then variables[#variables+1] = racine .. k .. ' = ' .. tostring(v) elseif type(v) == "boolean" then variables[#variables+1] = racine .. k .. ' = ' .. tostring(v) else objects[#objects+1] = racine .. k .. " => " .. type(v) end end table.sort(variables) table.sort(functions) table.sort(objects) return variables, functions, objects end fibaro.trace(tag, "") local variables, functions, objects = browse("", _ENV) fibaro.trace(tag, "Variables :") for _, v in ipairs(variables) do fibaro.debug(tag, v) end fibaro.trace(tag, "Fonctions :") for _, v in ipairs(functions) do fibaro.debug(tag, v) end fibaro.trace(tag, "Objets :") for _, v in ipairs(objects) do fibaro.debug(tag, v) end fibaro.debug(tag, "Terminé") Résultat : Variables : fibaro.version = "1.0.0" json._version = "0.1.0" math.huge = inf math.maxinteger = 9223372036854775807 math.mininteger = -9223372036854775808 math.pi = 3.1415926535898 sceneId = 10 sourceTrigger.id = 2 sourceTrigger.property = "execute" sourceTrigger.type = "user" tag = "Scene10" Fonctions : api.delete() api.get() api.post() api.put() assert() error() fibaro.alarm() fibaro.alert() fibaro.call() fibaro.callGroupAction() fibaro.debug() fibaro.emitCustomEvent() fibaro.error() fibaro.get() fibaro.getAllDeviceIds() fibaro.getDevicesID() fibaro.getGlobalVariable() fibaro.getIds() fibaro.getName() fibaro.getRoomID() fibaro.getRoomName() fibaro.getRoomNameByDeviceID() fibaro.getSectionID() fibaro.getType() fibaro.getValue() fibaro.homeCenter.climate.setClimateZoneToManualMode() fibaro.homeCenter.climate.setClimateZoneToScheduleMode() fibaro.homeCenter.climate.setClimateZoneToVacationMode() fibaro.homeCenter.notificationService.publish() fibaro.homeCenter.notificationService.remove() fibaro.homeCenter.notificationService.update() fibaro.homeCenter.popupService.publish() fibaro.homeCenter.systemService.reboot() fibaro.homeCenter.systemService.suspend() fibaro.profile() fibaro.scene() fibaro.setGlobalVariable() fibaro.setTimeout() fibaro.sleep() fibaro.trace() fibaro.wakeUpDeadDevice() fibaro.warning() ipairs() json.decode() json.encode() math.abs() math.acos() math.asin() math.atan() math.atan2() math.ceil() math.cos() math.cosh() math.deg() math.exp() math.floor() math.fmod() math.frexp() math.ldexp() math.log() math.log10() math.max() math.min() math.modf() math.pow() math.rad() math.random() math.randomseed() math.sin() math.sinh() math.sqrt() math.tan() math.tanh() math.tointeger() math.type() math.ult() net.HTTPClient.new() net.HTTPClient.request() next() os.date() os.time() pairs() pcall() print() select() string.byte() string.char() string.dump() string.find() string.format() string.gmatch() string.gsub() string.len() string.lower() string.match() string.pack() string.packsize() string.rep() string.reverse() string.sub() string.unpack() string.upper() table.concat() table.insert() table.move() table.pack() table.remove() table.sort() table.unpack() tonumber() tostring() type()
-
"circuit imprimé" facile - plaques à bandes (ou trous)
Lazer a répondu à un(e) sujet de Sowliny dans DIY (Do It Yoursel)
Quand on sait qu'on a pas mal de ce genre de petits projets DIY à venir, il faut tout commander sur Aliexpress. Les délais de livraison peuvent être ultra longs (jusqu'à 2 mois et demi pendant le confinement...) mais les tarifs sont imbattables. Sinon c'est plutôt 15 jours / 1 mois en moyenne (avec un record à 9 jours dans mon historique) RS et Farnell c'est pour les pros, commande unitaire pour du prototypage, livré le lendemain, mais c'est juste hors de prix.... -
"circuit imprimé" facile - plaques à bandes (ou trous)
Lazer a répondu à un(e) sujet de Sowliny dans DIY (Do It Yoursel)
Suffit de l'imprimer en 3D https://www.thingiverse.com/thing:2144441 L'afficheur 7 segments n'est pas cher parce qu'il est tout nu. L'objectif c'est de concevoir tout ce qui va autour. Sinon il existe des afficheurs plus cher avec leur propre boitier. -
"circuit imprimé" facile - plaques à bandes (ou trous)
Lazer a répondu à un(e) sujet de Sowliny dans DIY (Do It Yoursel)
J'en étais sûr, j'ai même failli te conseiller V33 ton Acajou -
"circuit imprimé" facile - plaques à bandes (ou trous)
Lazer a répondu à un(e) sujet de Sowliny dans DIY (Do It Yoursel)
Oui c'est sûr, mais ce n'est pas le seul boitier que j'ai fait, et puis ça sert à plein de choses. Au final la boitier coute environ 1€ à produire, c'est à dire rien du tout. Cherche "Vernis Tropicalisation" sur Amazon, y'a plein de bombes -
"circuit imprimé" facile - plaques à bandes (ou trous)
Lazer a répondu à un(e) sujet de Sowliny dans DIY (Do It Yoursel)
Hum, @Sowliny tu as édité ton message plus haut. Autant je suis parfaitement en phase sur la lute contre les petites bêtes, autant je ne suis pas d'accord sur la lute contre l'humidité. Il faut tropicaliser le circuit si tu veux le protéger, c'est la seule solution fiable... c'est pas pour rien que c'est pratiqué dans l'industrie. Une bonne couche de vernis, c'est imparable (et ça protège mêmes des petites bêtes en prime... dès fois qu'elles arrivent finalement par rentrer) -
"circuit imprimé" facile - plaques à bandes (ou trous)
Lazer a répondu à un(e) sujet de Sowliny dans DIY (Do It Yoursel)
Même en ayant une boite étanche, tu n'empêcheras pas l'humidité d'oxyder les pistes de cuivres non protégées. Il vaut mieux tropicaliser le circuit avec un vernis. Pour moi, la boite étanche hermétique sert à 2 choses : - empêcher les petites bêtes de rentrer dedans (qui font court-circuit) - empêcher l'eau (la pluie) de rentrer dedans (qui fait cout-circuit également) D'ailleurs "étanche" ne veut rien dire. Étanche dans l'absolu, ça n'existe pas. C'est étanche à certaines conditions. Tout cela est standardisé par les normes de protection IP. Sinon pour un boitier propre, il faut se mettre à l'impression 3D, pour se faire des ouvertures propres au 1/10 de millimètre près Exemple, non étanche car il y a volontairement des ouïes de ventilation (il y a un module Qubino pour volet roulant avec son alimentation 24V dedans). Fixation par vis dans inserts métalliques en laiton (donc vissable/dévissable à volonté)... sur la photo on voit que les vis ne sont pas positionnées. Connexion électrique propre avec prise C7 et cordon standard sur le coté. -
Pour les diodes à l'extinction, je t'avoue que je ne sais pas trop... je n'éteins jamais ma box (onduleur, région parisienne, orages rares)
-
La configuration usine de la HC2, c'est d'être en DHCP. Cette adresse statique 192.168.81.1 est celle qui est forcée lors qu'on démarre la box en Recovery par un appui long sur le bouton arrière (par opposition à l'appui court) Cela est utile par exemple quand on ne sait pas interroger son serveur DHCP pour connaitre l'IP attribuée, ou qu'elle a été forcée en IP statique sur une IP inconnue (cas typique de la box achetée d'occasion) Rappel : Quand tu as arrêté ta box, tu es passé par l'interface Web/API, ou via un appui sur le bouton ? Même question pour le redémarrage, as-tu bien fait un appui court uniquement ? C'est une piste. Si par contre tu as bien fait un appui court pour l'arrêt et le redémarrage, alors il y a un mystère.
-
Sur IPX800 v4 et EDRT2 tu n'as pas besoin d'authentification pour interroger l'API, tout passe par le keyapi=xxx passé en paramètre dans l'URL.
-
Cherche plutôt emoji sur Google et prend le premier lien. C'est standardisé par Unicode maintenant, tous les OS modernes (fixe et mobile) les supportent. Par contre l'affichage peut différer légèrement d'un OS à l'autre, mais c'est un détail. Tu connais forcément, c'est ce que tout le monde utilise à outrance sur les réseaux sociaux, messageries instantanées, etc. Ça remplace les bons vieux smileys ;-)
-
La procédure c'est de savoir programmer
-
J'en sais rien, je n'ai cliqué sur rien et j'ai laissé faire. Donc il a fait sa tambouille tout seul dans son coin. Ta question est pertinente, ça mérite de reproduire le bug. Un jour... si je suis motivé !
-
Comme je disais ailleurs, Gmail + Chrome ça fait très bien le boulot, aussi bien sur PC que sur Mobile. Sur Android en tout cas car l'intégration est native.
-
Il y aune vieille vidéo du BIOS de la HC2 qui traine sur Youtube, regarde si ça peut t'aider :
-
Je ne comprend pas que tu utilises encore Tapatalk.... Cette application est totalement dépassée.... En l'absence d'une commande magique comme sur HC2, il me semble très complexe de lire les valeurs des labels des QuickApps sur la HC3. Ca viendra peut être quand l'interface des QuickApps changera pour de bon (cf le petit doigt de @TonyC ) En attendant, la meilleure méthode semble être de maintenir une variable, un tableau, qui contient les dernières valeurs connues des différents Labels du QA. C'est d'ailleurs ce que fait jgab ici : https://forum.fibaro.com/topic/49113-hc3-quickapps-coding-tips-and-tricks/?tab=comments#comment-201303
-
c'est clair.... En tout cas la HC3 n'est pas encore aussi stable que la HC2, je ne l'avais jamais planté ainsi, pourtant ma HC2 elle en a vu des codes tordus. Le seul truc qui faisait crasher la HC2, c'était sa clé Recovery... toujours très paradoxale comme situation. N'empêche, c'est pratique cette détection automatique de plantage, mais c'est dommage que la box n'arrive pas à isoler le QA fautif. Là c'est toute la configuration qui est perdue depuis le dernier backup.
-
Ah ouais quand même, mon premier plantage : Je pense qu'il n'a pas aimé un requête volontairement mal formée via l'API (la chaine "xxx" au lieu d'un tableau) : local response, status = api.post("/globalVariables", "xxx") Dans le onInit() d'un QuickApp, ce qui fait planter la HC3 en boucle. Impossible de s'y reconnecter. Après 2 ou 3 reboots automatiques, la HC3 initie automatiquement une restauration : Un reboot supplémentaire : Redémarrage des services... avec l'ancien code couleur : Et on se retrouve au backup précédent, donc dans mon cas, au firmware 5.030.45 avec tous les modules ajoutés entre temps qui sont perdus => mise à jour en cours Conclusion, même si ce n'est pas nouveau : - il faut faire des sauvegardes régulières (ce que je ne sais pas sur cette box de test) - il faut développer sur une box de test, différente de la box de prod
-
topic unique Fibaro FGR-223 - Roller Shutter 3 - Micromodule pour volet roulant Z-Wave+
Lazer a répondu à un(e) sujet de Lazer dans Modules Fibaro
C'est très malpoli de poster le même message simultanément sur plusieurs topics => je fais le ménage -
ça fait 4 ans qu'il est dehors mon pluviomètre, il marche toujours aussi bien, et les piles ont une bonne durée de vie à part le plastique qui est devenu totalement jaune avec le temps. Je fais juste un nettoyage 1 à 2 fois par an, sinon il se bouche avec les saletés (feuilles, etc)
-
Remarque sur la carte électronique : c'est une erreur de conception de Netatmo de ne pas l'avoir tropicalisé. Mes détecteurs extérieur d'alarme (Diagral) sont tropicalisés, la carte électronique est intégralement recouverte d'un épais vernis.
-
Je pensais juste faire un trou par dessous, pour y faire rentrer le fil, et un petit joint au niveau de ce trou pour éviter que l'eau ne remonte par capillarité.
-
Je remonte ce topic, car j'ai le souci de piles qui se vident en 3 à 4 semaines pour l'anémomètre. J'ai été bête, car ça m'avait vidé le jeu de pile d'origine lors de son achat. Je n'y ai pas fait attention car je ne l'ai pas installé dehors et je l'ai laissé trainé dans un coin, en me disant que les piles d'origine étaient des sous-marques de mauvaise qualité. Depuis 2 mois je l'ai ressorti, et les jeux de piles passent à une allure folle (Duracell Ultra, et même accus Eneloop) Comme l'anémomètre a 4 ans, je peux m'assoir sur la garantie. Bref, ça me fait un module à 67€ inutilisable.... ça m'apprendra à laisser trainer les choses Ou alors, si un jour je fait une installation propre sur un poteau, il faudra que je lui bricole des fausses piles, en prenant soin de l'étanchéité du boitier (la colle chaude c'est efficace mais je ne sais pas si ça tient en extérieur ?)
-
J'en ai parlé il y a quelques pages. Résumons : Les USG et USG Pro disparaissent, remplacés par les UXG et UXG Pro. UDM et UDM Pro : nouvelle gamme tout intégré. L'UDM cible les geeks / la toute petite entreprise => Routeur + Switch + Wi-Fi + Controler. Attention lez débit s'effondre totalement dès qu'on active l'inspection de paquets. L'UDM Pro cible les PME : à peu près pareil que l'UDM, mais en version 19", avec support du 10 Gbps et un CPU plus puissant pour le débit, et sans Wi-Fi. Perso ce qui me gêne dans la gamme UDM c'est le coté tout intégré, par exemple impossible de gérer les routeurs avec un Controler externe (et ici on en a tous déjà un, soit sous forme de Clé, soit sous forme de logiciel VM/Container). Le tout intégré c'est bien, mais on se retrouve enfermé dans un écosystème et les migrations futures seront plus complexes UXG et UXG Pro : nouvelle gamme qui remplace les USG et USG Pro Ce sont juste 2 routeurs, le Pro reprend les caractéristiques matérielles de l'UDM Pro : 10 Gbps et CPU plus puissant, mais sans le coté tout intégré, donc on peut continuer à mixer les équipements : bornes UAP, switch, etc... et tout piloter depuis le Controler externe (toujours Clé ou Logiciel) Pour finir, le souci actuel avec les gammes UDM et UXG c'est qu'elles utilisent le nouvel OS, qui dispose de moins de fonctionnalités que les USG actuels. Et forcément beaucoup moins de fonctionnalités que les EdgeRouters (la gamme Edge reste le matos qui cible le plus les entreprises ou les nerds) Bref, c'est pas le moment de changer de routeur.... patience....