Lazer Posté(e) le 18 octobre 2016 Signaler Posté(e) le 18 octobre 2016 Voilà tu as tout compris Tu vois qu'il y a encore un peu de boulot avant d'arriver à un script stable.... mais c'est faisable. Dans un premier temps, il sera impossible de traiter tous les cas d'erreur possible. Donc tu peux simplement arrêter l'exécution de ton script si tu n'obtiens pas la réponse que tu attends, et te déconnecter proprement. Ensuite, tu relances (par exemple avec GEA ou ce que tu veux) tout le processus jusqu'à obtenir l'action désirée (activation/désactivation du wifi)
jjacques68 Posté(e) le 18 octobre 2016 Auteur Signaler Posté(e) le 18 octobre 2016 ok bon je m'y remets ce soir je posterai le nouvelle version merci !
jjacques68 Posté(e) le 18 octobre 2016 Auteur Signaler Posté(e) le 18 octobre 2016 alors j'ai essayer avec string.match() mais aucun resultat ???? J'ai contourné avec un string:find() voilà un bout du code qui m'emmène jusqu'au prompt : --ouvre la connexion tcpSocket = Net.FTcpSocket(deviceIp, devicePort) --set the read timeout tcpSocket:setReadTimeout(2000) local result = "" --affiche le login while string.find(result, "login:") == nil do result = tcpSocket:read() end fibaro:debug(result) --transmet le login bytes, errorCode = tcpSocket:write("admin".."\n") --login if errorCode == 0 then --boucle jusqu'à la demande du mot de pass while string.find(result, "Password:") == nil do result = tcpSocket:read() end fibaro:debug(result) else fibaro:debug("Error dans le login") end --trasmet le mot de pass bytes, errorCode = tcpSocket:write("xxxx".."\n") --pass if errorCode == 0 then --boucle jusqu'à l'arrivé du prompt while string.find(result, "NetgearRdc#") == nil do result = tcpSocket:read() end fibaro:debug(result) else fibaro:debug("Error dans le mdp") end --deconnect la session telnet tcpSocket:disconnect() fibaro:abort() et voilà le debug : [DEBUG] 18:39:44: login: [DEBUG] 18:39:44: Password: [DEBUG] 18:39:44: NetgearRdc# ça semble un peu plus propre sans les sleep() , mais par contre je traite plus le errorCode du coup ! c'est instantané l'enchainement des commandes... Modification faites, j'ai rajouter les errorCode... il faudra aussi que je regroupe dans une fonction les lignes de code, car elles sont répétitives. Et je mettrait les commandes telnet dans une variable tableau, un peu comme le watchdog avec le mot clé à rechercher ! 1
Lazer Posté(e) le 18 octobre 2016 Signaler Posté(e) le 18 octobre 2016 héhé, mettre le code dans une fonction et les commandes dans un tableau, c'était l'étape suivante que j'allais te proposer, tu m'as devancé
jjacques68 Posté(e) le 18 octobre 2016 Auteur Signaler Posté(e) le 18 octobre 2016 je continue doucement... par contre je bug depuis un petit moment la-dessus : je viens d'ajouter la commande me permettant d'aller dans le menu config : bytes, errorCode = tcpSocket:write("configure terminal".."\n") --menu configuration if errorCode == 0 then --boucle jsuqu'à l'arrivé du menu config while string.find(result, "config") == nil do result = tcpSocket:read() end fibaro:debug(result) else fibaro:debug("Error dans le menu config") end et voici le debug : [DEBUG] 20:23:01: login: [DEBUG] 20:23:01: Password: [DEBUG] 20:23:02: NetgearRdc# [DEBUG] 20:23:02: onfigure terminal NetgearRdc(config)# c'est pas logique, je devrais avoir que "NetgearRdc(config)# " ?? !! et puis il est passé où le "c" de configue ?
Lazer Posté(e) le 18 octobre 2016 Signaler Posté(e) le 18 octobre 2016 Non, c'est tout à fait normal. Parce que quand tu fais un telnet à la main, ce que tu vois à l'écran n'est pas ce que tu tapes à l'écran, mais ce que le switch t'envoie. Autrement dit, le switch te fait un retour visuel d'absolument tous les caractères que tu tapes. Quand je disais page précédente que le telnet est le protocole le plus basique qui soit, où chaque caractère est transmis tel quel dans la trame TCP, tu dois maintenant commencer à comprendre.... Donc il faut que ton script LUA tienne compte des caractères qu'il a envoyé, afin de ne pas en tenir compte dans la réponse.
jjacques68 Posté(e) le 18 octobre 2016 Auteur Signaler Posté(e) le 18 octobre 2016 oula !! bon ok. alors c'était ça la fonction string.match() ?? parce que j'ai absolument rien trouver de compréhensible sur cette fonction sur les sites qui parlent de lua (quand ils en parlent de cette fonction...) il y a string.gmatch(), j'ai trouvé la string.find() et encore je l'utilise pas correctement...
Lazer Posté(e) le 18 octobre 2016 Signaler Posté(e) le 18 octobre 2016 ouh làlà, la complexité ce n'est pas la fonction string àutiliser, mais ce que tu mets dedans : des expressions régulières. Je ne suis pas spécialiste des regex..... làtu ne te lances pas dans l'aspect le plus simple de la programmation
pepite Posté(e) le 18 octobre 2016 Signaler Posté(e) le 18 octobre 2016 Ca devient bon, bravo.. Et après tuy te lances dans une class TELNET ?
jjacques68 Posté(e) le 19 octobre 2016 Auteur Signaler Posté(e) le 19 octobre 2016 euh pour la classe on va y aller doucement au fait, encore merci pour votre aide et patience !! donc voilà la version 3, un code un peu moins crade : local deviceIP = { {name = "NetgearCave", ip = "192.168.xxx.xxx"}, {name = "NetgearRdc", ip = "192.168.xxx.yyy"}, --{name = "NetgearEtage", ip = "192.168.xxx.zzz"} } local devicePort = 23 local SendCommand = { {name="login", command="admin".."\n", txtmatch="Password:"}, {name="pass", command="xxxxxxx".."\n"}, {name="config", command="configure terminal".."\n", txtmatch="config"}, {name="wifiOff", command="radio 2.4 disable".."\n", txtmatch="disable"}, {name="retourMenu", command="exit".."\n"}, {name="save", command="save-and-activate".."\n", txtmatch="Activating"} } function Disconnect() for _,device in ipairs(deviceIP) do --pour chaque device du tableau deviceIP --ouvre la connexion tcpSocket = Net.FTcpSocket(device.ip, devicePort) tcpSocket:setReadTimeout(2000) --affiche le login local result = "" while string.find(result, "login:") == nil do result = tcpSocket:read() end --on lit la réponse jusqu'à avoir le mot clé "login" fibaro:debug(device.name.." - "..result) --envoi des commandes for _,com in ipairs(SendCommand) do --pour chaque commande du tableau SendCommand result="" bytes, errorCode = tcpSocket:write(com.command) if errorCode == 0 then if com.txtmatch then --un peu nul, mais si pas de txtmatch dans le tableau SendCommand, on prend le nom du device txt = com.txtmatch -- prend le mot clé définit dans le tableau SendCommand else txt = device.name.."#" --prend le nom du device pour le prompt car différent d'un device à l'autre (+ le #) end while string.find(result, txt) == nil do result = tcpSocket:read() end --on lit la reponse jusqu'à avoir le mot clé définit dans txtmatch (ou le nom du device) fibaro:debug(device.name.." - "..result) else fibaro:debug("Error dans "..com.name) --en cas d'erreur, mais je vois pas trop laquelle en fait !?? end end --deconnect la session telnet fibaro:debug(device.name.." - disconnect") tcpSocket:disconnect() end end --appel de la fonction pincipale Disconnect() Et voila le debug : [DEBUG] 07:22:50: NetgearCave - login: [DEBUG] 07:22:50: NetgearCave - Password: [DEBUG] 07:22:50: NetgearCave - NetgearCave# [DEBUG] 07:22:50: NetgearCave - onfigure terminal NetgearCave(config)# [DEBUG] 07:22:50: NetgearCave - adio 2.4 disable NetgearCave(config)# [DEBUG] 07:22:50: NetgearCave - xit NetgearCave# [DEBUG] 07:22:51: NetgearCave - % Activating config... [DEBUG] 07:22:51: NetgearCave - disconnect [DEBUG] 07:22:51: NetgearRdc - login: [DEBUG] 07:22:51: NetgearRdc - Password: [DEBUG] 07:22:51: NetgearRdc - NetgearRdc# [DEBUG] 07:22:51: NetgearRdc - onfigure terminal NetgearRdc(config)# [DEBUG] 07:22:51: NetgearRdc - adio 2.4 disable NetgearRdc(config)# [DEBUG] 07:22:51: NetgearRdc - xit NetgearRdc# [DEBUG] 07:22:53: NetgearRdc - % Activating config... [DEBUG] 07:22:53: NetgearRdc - disconnect ça marche très bien, pareil pour activer le wifi. Le code est moins crade... Mais pas encore très satisfait, car en cas d'erreur (ex demande d'activer alors qu'il est déjà activé), le script s'arrête et ne déconnecte donc jamais la session. et puis le debug est par porpre ! ça commence bien (login:, password, prompt) et puis après ça part en cou... et comme vu avec @Lazer, je pense que ma détection du mot clé dans la réponse n'est pas bonne. Mais les fonction string() avec les pattern, c'est une prise de tête moooooonumentale ! ce qui aurait été top aussi, c'est de pouvoir dans le tableau SendCommand pour la valeur "txtmatch", insérer le nom du device comme ci-dessous (pour la commande pass et retourMenu), mais ça marche pas : local deviceIP = { {name = "NetgearCave", ip = "192.168.xxx.xxx"}, {name = "NetgearRdc", ip = "192.168.xxx.xxx"} } local SendCommand = { {name="login", command="admin".."\n", txtmatch="Password:"}, {name="pass", command="xxxxxxx".."\n", txtmatch=deviceIP.name.."#"}, {name="config", command="configure terminal".."\n", txtmatch="config"}, {name="wifiOff", command="radio 2.4 disable".."\n", txtmatch="disable"}, {name="retourMenu", command="exit".."\n", txtmatch=deviceIP.name.."#"}, {name="save", command="save-and-activate".."\n", txtmatch="Activating"} } d'où ce bout de code un peu nul dans la fonction : if com.txtmatch then --un peu nul, mais si pas de txtmatch dans le tableau SendCommand, on prend le nom du device txt = com.txtmatch -- prend le mot clé définit dans le tableau SendCommand else txt = device.name.."#" --prend le nom du device pour le prompt car différent d'un device à l'autre (+ le #) end 1
jjacques68 Posté(e) le 20 octobre 2016 Auteur Signaler Posté(e) le 20 octobre 2016 alors !! j'en suis à la version 4 qui est de mieux en mieux je trouve et non toujours pas de classes !! (en fait je sais pas ce que c'est !!!) local deviceIP = { {name = "NetgearCave", ip = "192.168.xxx.xxx"}, {name = "NetgearRdc", ip = "192.168.xxx.yyy"}, {name = "NetgearEtage", ip = "192.168.xxx.zzz"} } local SendCommand = { {name="login", command="admin".."\n", txtmatch="Password:"}, {name="pass", command="xxxxxxx".."\n"}, {name="config", command="configure terminal".."\n", txtmatch="config"}, {name="wifiOff", command="radio 2.4 disable".."\n", txtmatch="disable"}, {name="retourMenu", command="exit".."\n"}, {name="save", command="save-and-activate".."\n", txtmatch="Activating"} } local devicePort = 23 local maxRetry = 5 local delayCommand = 100 function onError(com, device) fibaro:debug("ERROR sur "..device.." avec commande "..com) fibaro:call(fibaro:getGlobal("IdPhoneJJ"), "sendPush" , "Erreur lors de WIFI OFF sur "..device.." avec la commande "..com) end function StandbyLabel(name) fibaro:call(fibaro:getSelfId(), "setProperty", "ui.Label"..name..".value", "en cours...") end function Disconnect() for _,device in ipairs(deviceIP) do --boucle sur chaque device StandbyLabel(device.name) -- met les ... sur les label tcpSocket = Net.FTcpSocket(device.ip, devicePort) --ouvre la connexion tcpSocket:setReadTimeout(2000) --set the read timeout local result = "" local retry = 0 --attend le login while string.match(result, "login:") == nil and retry < maxRetry do fibaro:sleep(delayCommand) result = tcpSocket:read() retry=retry+1 end --si on a atteint les 5 essais alors erreur if retry >= maxRetry then onError(com.command, device.name) end fibaro:debug(device.name.." - "..result) --affiche le login for _,com in ipairs(SendCommand) do --boucle sur chaque commande de la table SendCommand local retry = 0 result="" bytes, errorCode = tcpSocket:write(com.command) if errorCode == 0 then --détermine le texte a trouver dans la réponse - C'EST NUL çA !! if com.txtmatch then txt = com.txtmatch else txt = device.name.."#" end --boucle jusqu'à trouver le texte MAX 5 essai while string.match(result, txt) == nil and retry < maxRetry do fibaro:sleep(delayCommand) result = tcpSocket:read() retry=retry+1 end --si on a atteind les 5 essais alors erreur if retry >= maxRetry then onError(com.command, device.name) end fibaro:debug(device.name.." - "..result) --affiche le resultat de la commande passée else --errorCode = 1 - dans quels cas c'est pssible ? onError(com.command, device.name) end end fibaro:debug(device.name.." - disconnect Telnet") --deconnect la session telnet et passe au device suivant tcpSocket:disconnect() tcpSocket=nil end return true --renvoie true si tout est ok (plus vraiment utile) end --MAIN local result = Disconnect() if result == true then fibaro:debug("OFF OK") else fibaro:debug("ERROR") end --effectue un check des device fibaro:sleep(15*1000) fibaro:call(fibaro:getSelfId(), "pressButton", 10) J'ai largement pioché les idées dans des VD sur le forum, désolé je serais plus capable de dire qui à fait quoi, mais en tout cas je vous remercie tous pour l'aide !! Sans doute certains se reconnaitront J'ai pu utiliser les string.match(). J'ai rajouter des sleep() dans les boucles de détections car je les limite à 5 essais et donc elles s'enchainaient trop vite ! A la fin du script, j'utilise l'appel d'un autre script pour vérifier l'état des 3 access point. En fonction de leur état, l’icône du VD change et les notifications push également. Et ça marche pas mal je pense ! le but est que lorsque que je me couche ou que je quitte la maison, j'enclenche l'alarme, et en même temps je coupe le wifi. quand je me réveil ou que je rentre, je coupe l'alarme et le wifi s'allume. Juste un soucis à régler j'ai mis un sleep de 15 secondes à la fin du script pour appeler le check. Mais souvent le check se passe mal. Comme si il ne pouvait pas "encore accéder" aux paramètres des AP - malgré les 15 secondes ou 30 même !! ça me plante le VD, il suffit juste de refaire un check et c'est bon... A méditer... 1
pepite Posté(e) le 21 octobre 2016 Signaler Posté(e) le 21 octobre 2016 Bien bien !! waouw. Montre nous un petit debug stp, pour ma curiosite perso hihihi
jjacques68 Posté(e) le 21 octobre 2016 Auteur Signaler Posté(e) le 21 octobre 2016 et voilà! c'est pas très beau, mais comme dit @Lazer, visiblement en telnet c'est du brut de décoffrage ! [DEBUG] 07:46:56: NetgearCave - 1F000103 login: [DEBUG] 07:46:56: NetgearCave - admin Password: [DEBUG] 07:46:56: NetgearCave - NetgearCave# [DEBUG] 07:46:56: NetgearCave - configure terminal NetgearCave(config)# [DEBUG] 07:46:56: NetgearCave - radio 2.4 disable NetgearCave(config)# [DEBUG] 07:46:56: NetgearCave - exit NetgearCave# [DEBUG] 07:46:57: NetgearCave - % Activating config... [DEBUG] 07:46:57: NetgearCave - disconnect Telnet [DEBUG] 07:46:57: NetgearRdc - 1F000103 login: [DEBUG] 07:46:58: NetgearRdc - admin Password: [DEBUG] 07:46:58: NetgearRdc - NetgearRdc# [DEBUG] 07:46:58: NetgearRdc - configure terminal NetgearRdc(config)# [DEBUG] 07:46:58: NetgearRdc - radio 2.4 disable NetgearRdc(config)# [DEBUG] 07:46:58: NetgearRdc - exit NetgearRdc# [DEBUG] 07:46:59: NetgearRdc - % Activating config... [DEBUG] 07:46:59: NetgearRdc - disconnect Telnet [DEBUG] 07:46:59: NetgearEtage - 1F000103 login: [DEBUG] 07:46:59: NetgearEtage - admin Password: [DEBUG] 07:46:59: NetgearEtage - NetgearEtage# [DEBUG] 07:47:00: NetgearEtage - configure terminal NetgearEtage(config)# [DEBUG] 07:47:00: NetgearEtage - radio 2.4 disable NetgearEtage(config)# [DEBUG] 07:47:00: NetgearEtage - exit NetgearEtage# [DEBUG] 07:47:01: NetgearEtage - % Activating config... [DEBUG] 07:47:01: NetgearEtage - disconnect Telnet [DEBUG] 07:47:01: OFF OK Mon problème de check semble résolu j'ai simplement augmenté le temps entre la fin du premier script et le lancement du check. Je pense que les AP travaillent encore après la validation... 1
Invité chris6783 Posté(e) le 17 septembre 2017 Signaler Posté(e) le 17 septembre 2017 J'avais pas vu votre discussion. Bravo et merci pour le partageEnvoyé de mon Lenovo YT-X703F en utilisant Tapatalk
Messages recommandés