Accéder à un périphérique réseau DEPUIS Domoticz

Posez ici vos questions d'utilisation, de configuration de DomoticZ, de bugs, de conseils sur le logiciel lui même dans son utilisation et son paramétrage.
Des forums spécifiques sont ouverts ci-dessous pour regrouper les différents sujets.
Aile
Messages : 157
Inscription : 27 janv. 2022, 12:18

Accéder à un périphérique réseau DEPUIS Domoticz

Message par Aile »

Bonjour à tous,

Je viens d'installer la dernière version de Domoticz, et après quelques modifications en raison des changements sur l'API JSON, tout fonctionne bien à l'exception des accès réseau depuis Domoticz.
Je m'explique :
Mon routeur Teltonika (10.0.0.254) met à jour en temps réel les personnes présentes dans la maison (selon l'IP locale de leur téléphone) en écrivant la table ARP dans un fichier local (/mnt/sda1/IPs.txt), partagé en tant que \\10.0.0.254\arp\IPs.txt, et visible sur le PC Windows sur lequel tourne Domoticz.
Un script Dzvents lit ce fichier et met à jour le panneau de sécurité en conséquence.
Depuis cette dernière version de Domoticz, impossible d'ouvrir ce fichier distant : le descripteur de fichier renvoie nil !
En revanche, le fichier est bien visible par Dz, puisque la fonction domoticz.utils.fileExists renvoie vrai.

Code : Tout sélectionner

	if not domoticz.utils.fileExists(FichierArp) then
		domoticz.log('Erreur lecture fichier ARP',domoticz.LOG_ERROR)
	end

	local FichierArp  = '\\\\10.0.0.254\\arp\\IPs.txt'

	arp = {}				-- Table pour les lignes du fichier
	local fileArp = io.open(FichierArp,'r')	-- Ouvre le fichier en mode lecture
--	print('fileArp : '..tostring(fileArp)) ======> renvoie nil
J'imagine que c'est en raison des nouvelles procédures de sécurité de cette version, mais je n'ai rien trouvé pour mon cas précis.
Si quelqu'un peut m'orienter ;-)

Merci et bonne journée à tous.
NUC Celeron 1037U / Win 10 Pro
  • EcoCompteur Legrand
  • RFLink Nodo : capteurs T° Alecto / capteurs présence EV1527
  • Clef Sonoff Zigbee 3.0 : capteurs T° Sonoff / capteurs présence Lidl / Détecteurs fumée Heiman
  • BroadLink : pilotage clim
  • Shelly 1
lost
Messages : 1511
Inscription : 12 nov. 2016, 11:01

Re: Accéder à un périphérique réseau DEPUIS Domoticz

Message par lost »

Aile a écrit : 02 août 2023, 10:34 J'imagine que c'est en raison des nouvelles procédures de sécurité de cette version, mais je n'ai rien trouvé pour mon cas précis.
Il n'y a qu'un extrait de code, mais la déclaration "FichierArp" visible ici est après le test d'existence du fichier? Difficile d'imaginer que cela ne lève pas une erreur à l’exécution si la variable n'existe pas à l'appel de ce test, mais en tout cas si elle change entre le test et l'ouverture du fichier le test n'est plus forcément probant!

Aucune raison pour que les changements sécurité pour une connexion entrante à Domoticz aient en impact pour de telles connexions sortantes. Surtout que le io.open() va ici appeler directement des fonctions du système.

Bizarre de mélanger des fonctions de Domoticz et du système sur ce genre de besoin purement système: A priori, si io.open() retourne 'nil' c'est que vu du système le fichier n'est pas présent/accessible (montage réseau, droits...).
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Re: Accéder à un périphérique réseau DEPUIS Domoticz

Message par Keros »

Il n'était pas plus simple de réaliser un ping depuis DomoticZ avec le plugin System Alive Checker pour savoir quelles IP étaient sur le réseau ?

Du même avis que Lost également pour voir le script complet.
Comment bien utiliser le forum : Poser une question, Mettre un script, un fichier, une image ou des logs
Mes petits guides : Débuter en programmation, Le débogage, Le choix de matériel, Les sauvegardes
Ma présentation - Mes Tutos
lost
Messages : 1511
Inscription : 12 nov. 2016, 11:01

Re: Accéder à un périphérique réseau DEPUIS Domoticz

Message par lost »

Keros a écrit : 02 août 2023, 12:50 Il n'était pas plus simple de réaliser un ping...
Sans doute, maintenant il peut y avoir des raisons d'utiliser la table ARP, car c'est un cache, avec des durées d'expiration qui masquent les déconnexions fréquentes des wifi de smartphones (pour raison d'économie d'énergie)... Mais c'est niveau réactivité quand on s'en va que c'est pas génial pour commander le panneau de sécurité (et, j’imagine, l'activation d'une alarme) car l'invalidation d'une adresse en cache arp est longue.

Maintenant, le principal défaut que je vois, c'est que l'on ne voit dans la table arp que ce qui est sur le même segment réseau... et que beaucoup de points d'accès wifi, si on a besoin de couverture, sont également des routeurs qui vont faire un réseau séparé: Dans ce cas, les ping répondent mais la table arp ne va montrer que l'adresse du routeur (gateway pour le réseau séparé)... et perdu!

Pour ma part la détection de présence passe par le bluetooth pour 2 raisons:
-Pas visé par les gestions d'énergie des smartphones, contrairement au wifi (on gère donc bien la réactivité).
-Ça oblige les enfants à laisser leurs dumb-phones en bas et a pas monter dans les piaules, sinon avec la portée inférieure au wifi ça va vite se voir (voir s'entendre s'ils sont seuls)! :lol:
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Re: Accéder à un périphérique réseau DEPUIS Domoticz

Message par Keros »

J'adore ta solution pour que les enfants laissent leur téléphone en bas :D
Comment bien utiliser le forum : Poser une question, Mettre un script, un fichier, une image ou des logs
Mes petits guides : Débuter en programmation, Le débogage, Le choix de matériel, Les sauvegardes
Ma présentation - Mes Tutos
Aile
Messages : 157
Inscription : 27 janv. 2022, 12:18

Re: Accéder à un périphérique réseau DEPUIS Domoticz

Message par Aile »

lost a écrit : 02 août 2023, 11:29 Il n'y a qu'un extrait de code, mais la déclaration "FichierArp" visible ici est après le test d'existence du fichier?
Oups !... Cette ligne de déclaration n'existe pas dans le script. Je l'avais mise pour la compréhension, mais elle aurait dû être au tout début de l'extrait.

Voici donc l'intégralité du code, mais je doute que ce soit vraiment utile pour résoudre le problème. La seule difficulté, c'est l'impossibilité d'accéder au partage réseau du routeur.

Code : Tout sélectionner

--[[
	Prerequisits
	==================================
	Domoticz v3.8837 or later (dzVents version 2.4 or later)

	Scan ARP + ping
	
-- Authors  ----------------------------------------------------------------
	V1.0 - Neutrino
	V1.1 - Aile
]]--

local scriptName = 'ARPing'
local scriptVersion = '1.1'
local scriptTrigger = 'MAJ'
local PingTrigger = 'Ping'
local Presences = ''
local PresenceOk = false

-- Variables to customize --------------------------------------------------

local IntervalleMinutes = 1     -- Délai Dzvents
local IntervalleSecondes = 10   -- Délai entre interrogations
local nbPings = 1               -- Nombre de pings pour tester la connexion
local timoutPings = 50          -- Timeout entre pings
local tempo = 1                 -- Temporisation en minutes avant détection d'absence (évite les faux positifs)
local ClasseC = '10.0.0.'
local Panneau = 'Panneau de sécurité'
local DevicePresence = 'Présence'
local VariablePresence = 'Présences'
local armAwayToggleBtn = 'Alarme en absence'
local FichierArp  = '\\\\10.0.0.254\\arp\\IPs.txt'

--Tableau des périphériques à interroger
-- ScanARP['adresse IP']={'Interrupteur virtuel',0}
local ScanARP = {}
	ScanARP[ClasseC..'2']={'Julien',false}
	ScanARP[ClasseC..'4']={'Cathy',false}
	ScanARP[ClasseC..'6']={'Cédric',false}
	ScanARP[ClasseC..'7']={'Sylvie',false}
	ScanARP[ClasseC..'3']={'Luc',false}
------------------------------------------------------------------------------

-------------------------------
function Ping(IP,Domoticz,Item)
-------------------------------
    command = "cmd /K Ping -n "..nbPings.." -w "..timoutPings.." "..IP
    command = "Ping -n "..nbPings.." -w "..timoutPings.." "..IP
    local handle = io.popen(command)
    local result = handle:read("*a")
    handle:close()
    return string.find(result, 'temps=') ~= nil
end

--------------------------------
function ScanPresences(domoticz)
--------------------------------

	if not domoticz.utils.fileExists(FichierArp) then
		domoticz.log('Erreur lecture fichier ARP',domoticz.LOG_ERROR)
    else
		domoticz.log('Fichier lu !',domoticz.LOG_ERROR)
	end

	arp = {}                                    -- Table pour les lignes du fichier
	local fileArp = io.open(FichierArp,'r')     -- Ouvre le fichier en mode lecture

	for line in fileArp:lines() do              -- Pour chaque ligne
		table.insert(arp, line)                 -- On insère les lignes dans la table
    end
    io.close(fileArp)

	for Ligne in pairs(arp) do
		IPutilisateur = arp[Ligne]:sub(1,arp[Ligne]:find(" ")-1)                --Extraction des IP de la table ARP
		for word in arp[Ligne]:gmatch("%a+") do
		    StatutUtilisateur = word                                            -- (REACHABLE, STALE, FAILED, etc.)
		end
		if ScanARP[IPutilisateur] ~= nil then                                   -- IP recherchée
			domoticz.log(IPutilisateur.." ("..ScanARP[IPutilisateur][1]..") : "..StatutUtilisateur,domoticz.LOG_DEBUG)
			if arp[Ligne]:find("REACHABLE")~=nil then                           -- IP connue sur le réseau, connectée
				domoticz.log("ARP Ok sur "..arp[Ligne], domoticz.LOG_DEBUG)
				ScanARP[IPutilisateur][2]=true                                  -- flag pour mise à On
			elseif arp[Ligne]:find("STALE")~=nil or arp[Ligne]:find("DELAY")~=nil then -- IP connue sur le réseau, état incertain
				domoticz.log("ARP douteux sur "..arp[Ligne], domoticz.LOG_DEBUG)
                ScanARP[IPutilisateur][2]=Ping(IPutilisateur,domoticz,item)
			else                                                                -- Adresse IP connue mais déconnectée
				domoticz.log("Echec ARP "..arp[Ligne], domoticz.LOG_DEBUG)
                ScanARP[IPutilisateur][2]=Ping(IPutilisateur,domoticz,item)
			end
			domoticz.log("Résultat du ping sur "..ScanARP[IPutilisateur][1].." : "..tostring(ScanARP[IPutilisateur][2]),domoticz.LOG_DEBUG)
		else
			domoticz.log(IPutilisateur.." : injoignable",domoticz.LOG_DEBUG)
		end
	end

    ScanARPtri = {}
    for IP in pairs(ScanARP) do
        if ScanARP[IP][2] then
            PresenceOk = true
            table.insert(ScanARPtri, ScanARP[IP][1])
        end
    end
    table.sort(ScanARPtri)
    for Ligne,Valeur in pairs(ScanARPtri) do Presences = Presences..'-'..Valeur end

    domoticz.log("Présence : "..tostring(PresenceOk),domoticz.LOG_DEBUG)
	local TelephonesActifs = string.sub(Presences,2,string.len(Presences))
	domoticz.log("Telephones actifs : "..TelephonesActifs,domoticz.LOG_DEBUG)
    domoticz.devices(VariablePresence).updateText(TelephonesActifs)
    return TelephonesActifs
end

return {
	active = true,
	logging = {
		-- level = domoticz.LOG_INFO, -- Uncomment to override the dzVents global logging setting
		marker = scriptName..' '..scriptVersion
	},
	on = {
		timer = { 'every '..tostring(IntervalleMinutes)..' minutes'	},
        httpResponses = { scriptTrigger },
        shellCommandResponses = { pingTrigger }
    },

	execute = function(domoticz, item)

        if item.isTimer then
            url = domoticz.settings['Domoticz url']
            for seconds = IntervalleSecondes, (IntervalleMinutes * 60) - IntervalleSecondes, IntervalleSecondes do -- start with 10 step 10 until 290
                domoticz.openURL({url = url, callback = scriptTrigger }).afterSec(seconds)
            end
        end

        TelephonesActifs = ScanPresences(domoticz)

        if domoticz.devices(armAwayToggleBtn).state == "Off" and tonumber(os.date("%M")) % 5 == 0 and tonumber(os.date("%S")) < 2 then
            domoticz.log('********* Attention ! Bouton Alarme désactivé *********',domoticz.LOG_ERROR)
            if domoticz.devices(Panneau).state == "Armed Away" then domoticz.devices(Panneau).disarm() end
            return
        end

        if PresenceOk then
            domoticz.devices(DevicePresence).switchOn()
            if domoticz.devices(Panneau).state == "Armed Away" then --  and domoticz.devices(armAwayToggleBtn).state == "Off"
                domoticz.log('********* Présence détectée ('..TelephonesActifs..') ===> Désactivation alarme *********',domoticz.LOG_FORCE)
                domoticz.devices(Panneau).disarm()
            end
        else
        	if tonumber(os.date("%M")) % 5 == 0 and tonumber(os.date("%S")) < 2 then
                domoticz.log('Aucune présence détectée depuis '..domoticz.devices(Panneau).lastUpdate.minutesAgo.." minute(s)",domoticz.LOG_FORCE)
            end
            if domoticz.devices(DevicePresence).lastUpdate.minutesAgo > tempo-1 then
                domoticz.devices(DevicePresence).switchOff()
                if domoticz.devices(Panneau).state == "Disarmed" and domoticz.devices(armAwayToggleBtn).state == "On" then
                    domoticz.log('********* Aucune présence détectée depuis '..domoticz.devices(DevicePresence).lastUpdate.minutesAgo..' minutes ===> Activation alarme *********',domoticz.LOG_FORCE)
                    domoticz.devices(Panneau).armAway()
                end
            end
        end

	end
}
lost a écrit : 02 août 2023, 11:29 Aucune raison pour que les changements sécurité pour une connexion entrante à Domoticz aient en impact pour de telles connexions sortantes. Surtout que le io.open() va ici appeler directement des fonctions du système.
[...]
A priori, si io.open() retourne 'nil' c'est que vu du système le fichier n'est pas présent/accessible (montage réseau, droits...)
Et pourtant, lorsque je suis sur le PC qui héberge Domoticz, j'accède sans problème au partage :
Capture.JPG
Capture.JPG (39.11 Kio) Consulté 869 fois
lost a écrit : 02 août 2023, 11:29 Bizarre de mélanger des fonctions de Domoticz et du système sur ce genre de besoin purement système.
Tu peux développer ? Quelle aurait été la méthode "orthodoxe" ?
NUC Celeron 1037U / Win 10 Pro
  • EcoCompteur Legrand
  • RFLink Nodo : capteurs T° Alecto / capteurs présence EV1527
  • Clef Sonoff Zigbee 3.0 : capteurs T° Sonoff / capteurs présence Lidl / Détecteurs fumée Heiman
  • BroadLink : pilotage clim
  • Shelly 1
Aile
Messages : 157
Inscription : 27 janv. 2022, 12:18

Re: Accéder à un périphérique réseau DEPUIS Domoticz

Message par Aile »

Bonjour, quelques news :

impossible d'accéder par io.open au fichier partagé sur mon routeur Teltonika.
En modifiant l'instruction de

Code : Tout sélectionner

local fileArp = io.open(FichierArp,'r')     -- Ouvre le fichier en mode lecture
en

Code : Tout sélectionner

local fileArp = assert(io.open(FichierArp,'r'))
le message renvoyé est "Invalid argument" !!!
Ce n'est donc pas un problème d'accès au fichier, si je comprends bien ?
Il n'y a pourtant que deux arguments, le chemin du fichier et le mode d'ouverture (lecture, écriture, création, etc.)
En tous cas, ça marche avec un fichier local, mais pas avec un fichier partagé en réseau.
Chose étonnante comme indiqué plus haut, le pc lit le fichier depuis la ligne de commande sans problème.
Avec la version 2022.1 de Domoticz, le phénomène ne se produisait pas. Serait-ce un bug :mrgreen: ?

Donc, j'ai craqué et j'ai utilisé smbclient sur le routeur pour envoyer le fichier sur le PC qui héberge Domoticz.
Et dans ce sens, ça tombe en marche sans problème...
NUC Celeron 1037U / Win 10 Pro
  • EcoCompteur Legrand
  • RFLink Nodo : capteurs T° Alecto / capteurs présence EV1527
  • Clef Sonoff Zigbee 3.0 : capteurs T° Sonoff / capteurs présence Lidl / Détecteurs fumée Heiman
  • BroadLink : pilotage clim
  • Shelly 1
lost
Messages : 1511
Inscription : 12 nov. 2016, 11:01

Re: Accéder à un périphérique réseau DEPUIS Domoticz

Message par lost »

Aile a écrit : 04 août 2023, 19:37 Avec la version 2022.1 de Domoticz, le phénomène ne se produisait pas. Serait-ce un bug :mrgreen: ?
Pas forcément... Mais il me semble me souvenir en effet que j'avais dû changer un truc (pas lié) dans mes scripts Lua (dzVents est basé dessus et sera aussi concerné) en passant en 2022.2 en début d'année, la raison étant que la version de Lua embarquée par Domoticz avait changé.

Je pense qu'il faut plus chercher la raison d'un changement de comportement de ce côté si tu veux en avoir le coeur net malgré le contournement trouvé... Attention aussi aux pb de droits (test direct avec un utilisateur qui n'est pas celui sous lequel le service domoticz est lancé).

Je note aussi que dans ton test tu préfixe le chemin réseau par un \\ et que dans la string Lua c'est \\\\ (besoin d'échapper le caractère \ comme en shell Linux sous windows??? J'en sais rien je dirais car je n'utilise plus windows sauf obligation pour le laptop du boulot, qui me sert globalement plus qu' à faire tourner une VM Linux pour ce qui n'est pas purement bureautique, depuis une quinzaine d'années mais ca m'étonne).
Répondre