Aller au contenu

Messages recommandés

Posté(e)

Voilà  tu as tout compris :):60:

 

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)

Posté(e)

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 !

 

  • Upvote 1
Posté(e)

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é :D:13:

Posté(e)

:) 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 ?

Posté(e)

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.

Posté(e)

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...

Posté(e)

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

Posté(e)

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 ! :15:

ç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 !  :angry:

 

 

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
  • Upvote 1
Posté(e)

alors !! j'en suis à  la version 4

 

qui est de mieux en mieux je trouve :13:

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...

  • Upvote 1
Posté(e)

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...

  • Upvote 1
  • 10 mois après...
Invité chris6783
Posté(e)

J'avais pas vu votre discussion. Bravo et merci pour le partage

Envoyé de mon Lenovo YT-X703F en utilisant Tapatalk

×
×
  • Créer...