Étape 7: Le Code de Vera
Pour utiliser le contrôleur de mon Garage avec mon Vera2, j’ai dû écrire un « plugin ». Mais en ajoutant votre propre plugin pour la Vera n’est pas facile. Tout d’abord, le peu de documentation qui existe sur leur Wiki est périmé ou incomplet. Il existe également un forum où vous pouvez voir quels autres personnes l’ont fait et poser des questions.Vera utilise une combinaison de UPnP et LUA appelé Luup. Vous avez besoin d’au moins deux fichiers, un fichier de « définition » et un fichier « mise en oeuvre ». Le problème, c’est que le fichier de mise en œuvre est une combinaison de XML et LUA. La seule façon de tester votre code LUA (au moins que je connais pour le Mac), est de charger le fichier de mise en œuvre et espère qu’il fonctionne. Chargement de vos fichiers et redémarrer le moteur Luup prend une minute ou plus, donc le processus est lent. Il n’y a aucun débogueur et votre seul outil de débogage est la fonctionnalité de journalisation. Vous affichez le journal, vous pouvez soit SSH dans la Vera ou utilisez l’URL suivante : < yourVeraIp > / cgi-bin/cmh/log.sh ? Device = LuaUPnP ". S’il y a des moyens plus facile, je n’ai pas trouvé leur encore.
À moins que votre périphérique est un type de UPnP « notoirement connu », toutes les applications de contrôle à distance de téléphone portable ne sera pas en mesure de contrôler votre appareil. Étant donné que je veux faire le contrôle à distance, mon contrôleur de Garage apparaît comme un « contrôleur de Garage » qui a les dispositifs suivants d’enfant :
- Une lumière réglable pour contrôler la porte de garage (n’oubliez pas, je veux ouvrir partiellement la porte)
- Trois interrupteurs de lumière pour chacun des relais qui contrôlent mes zones d’irrigation.
Voici donc le fichier de définition (enregistrer en tant que « D_GarageController1.xml ») :
<? xml version = « 1.0 »? >
< racine xmlns = "urn : schemas-upnp-org:device-1-0" >
< specVersion >
< majeur > 1 < / major >
< minor > 0 < / minor >
< / specVersion >
< périphérique >
< deviceType > urn : schemas-aram-perez-com:device:GarageController:1 < / deviceType >
< friendlyName > Garage contrôleur < / friendlyName >
< modelNumber > 1.0 < / modelNumber >
crlf < protocole > < / protocole >
< handleChildren > 1 < / handleChildren >
< implementationList >
< implementationFile > I_GarageController1.xml < / implementationFile >
< / implementationList >
< / périphérique >
< / root >
Et voici le fichier d’implémentation (enregistrer en tant que « I_GarageController1.xml ») :
<? xml version = « 1.0 »? >
< application >
< fonctions >
local GC = "contrôleur de Garage, dispositif: »
GC_SID locale = "urn : schemas-aram-perez-com:device:GarageController:1"
SP_SID locale = "urn : upnp-org:serviceId:SwitchPower1"
DIM_SID locale = "urn : upnp-org:serviceId:Dimming1"
local CR = string.char(13)
FIXED_LEVEL locale = « 30 »
la CSI locale = string.char (27, 91)--ESC + [
parentDevice locaux
garageDoorStatus locaux
-- -------------------------------------------------------------------------
--Ouvrez une session avec couleur
fonction Log (dispositif, msg)
luup.log (CSI... « 35m »... GC... ToString(Device)... ", " .. msg... CSI... « 0 m »)
fin
function LogL1 (device, msg)
luup.log (CSI... « 35m »... GC... ToString(Device)... ", " .. msg... CSI... « 0 m", 1)
fin
function LogL2 (device, msg)
luup.log (CSI... « 35m »... GC... ToString(Device)... ", " .. msg... CSI... « 0 m", 2)
fin
fonction startup(lul_device)
dispositif local = luup.devices[lul_device]
ipAddress locales, ignorer, ipPort = string.match (device.ip, « ^ ([% w%.%-]+) (:? () %d-))$")
Si (ipAddress ~ = "") puis
parentDevice = lul_device
Si (ipPort == nil) ou (ipPort == "") puis
Si (device.port == nil) ou (device.port == "") puis
ipPort = 23 ;
fin
fin
Journal (lul_device, ("mise en marche, se connecter à"... ipAddress... ", port"... ipPort))
luup.IO.Open (lul_device, ipAddress, ipPort)
child_devices = luup.chdev.start(lul_device) ;
luup.chdev.Append (lul_device, child_devices, « GD », « Porte de Garage », "urn : schemas-upnp-org:device:DimmableLight:1", "D_DimmableLight1.xml", "", "", true)
luup.chdev.Append (lul_device, child_devices, « Z1 », "Zone d’Irrigation 1", "urn : schemas-upnp-org:device:BinaryLight:1", "D_BinaryLight1.xml", "", "", true)
luup.chdev.Append (lul_device, child_devices, « Z2 », "Zone d’Irrigation 2", "urn : schemas-upnp-org:device:BinaryLight:1", "D_BinaryLight1.xml", "", "", true)
luup.chdev.Append (lul_device, child_devices, « Z3 », "Zone d’Irrigation 3", "urn : schemas-upnp-org:device:BinaryLight:1", "D_BinaryLight1.xml", "", "", true)
luup.chdev.Sync(lul_device,child_devices)
valeur locale = luup.variable_get (GC_SID, « DelayPartialOpen », lul_device + 1)
Si (valeur == nil) ou (valeur == "") puis
luup.variable_set (GC_SID, « Open DelayPartial », « 3 », lul_device + 1)
fin
--Suppose que tous les relais d’irrigation sont éteints
luup.variable_set (GC_SID, « Status », « 0 », lul_device + 2)
luup.variable_set (GC_SID, « Status », « 0 », lul_device + 3)
luup.variable_set (GC_SID, « Status », « 0 », lul_device + 4)
d’autre
locale err = "erreur : aucune adresse IP trouvée"
LogL2(lul_device, err)
retourne la valeur false, err, « Contrôleur de Garage »
fin
luup.IO.Write("g?")
renvoie la valeur true, « Ok », « Contrôleur de Garage »
fin
fonction partialOpen(data)
luup.IO.Write("GB")
fin
< / fonctions >
démarrage de < démarrage > < / démarrage >
< entrants >
< lua >
Journal (lul_device, (« données reçues: ".. ToString(lul_data)))
ch local = lul_data:sub(1,1)
Si ch == « g » puis
statut local
ch = lul_data:sub(2,2)
Si ch == ' o ' alors
garageDoorStatus = ch
statut = « 100 »
luup.variable_set (SP_SID, « Status », « 1 », lul_device + 1)
ElseIf ch == « c » puis
garageDoorStatus = ch
statut = « 0 »
luup.variable_set (SP_SID, « Status », « 0 », lul_device + 1)
ElseIf ch == « p » puis
garageDoorStatus = ch
statut = FIXED_LEVEL
luup.variable_set (SP_SID, « Status », « 1 », lul_device + 1)
d’autre
Log (lul_device, « données reçues inconnues »)
revenir fin
fin
luup.variable_set (DIM_SID, « LoadLevelStatus », status, lul_device + 1)
ElseIf ch == « r » puis
ch = lul_data:sub(2,2)
Si (ch & gt ; '0') et (ch & lt ; "4") puis
luup.variable_set (SP_SID, « Statut », lul_data:sub (3,3), lul_device + ch + 1)
d’autre
LogL1 (lul_device, (« numéro de zone non valide: ".. ToString(Device)))
fin
d’autre
LogL2 (lul_device, « données inconnues »)
fin
< / lua >
< / solaires >
< actionList >
< action >
< serviceId > urn : upnp-org:serviceId:Dimming1 < / serviceId >
< nom > SetLoadLevelTarget < / nom >
< exécuter >
local garageLevel = lul_settings.newLoadlevelTarget
luup.variable_set (« LoadLevelTarget », garageLevel, DIM_SID, lul_device)
Journal (lul_device, (« Réglez niveau porte sur"... garageLevel))
statut local = luup.variable_get (SP_SID, « Status », lul_device)
Si garageLevel == statut puis
retourne la valeur true
fin
Si luup.io.write("gb") == false alors
LogL1 (lul_device, ("erreur envoi de commande"))
luup.set_failure(true)
retourner false
fin
Si (garageLevel ~ = « 0 ») et (garageLevel ~ = « 100 ») puis
retard local = luup.variable_get (GC_SID, « DelayPartialOpen », lul_device)
luup.call_delay ("partialOpen", delay, garageLevel)
fin
retourne la valeur true
< / run >
< / action >
< action >
< serviceId > urn : upnp-org:serviceId:SwitchPower1 < / serviceId >
< nom > SetTarget < / nom >
< exécuter >
relais local = lul_device - parentDevice
Si (Relais & lt; 1) ou (Relais & gt; 4) puis
LogL1 (lul_device, (« pas un nombre valide de relais: ".. Relais))
retourner false
fin
Relais = relais - 1
local newTarget = tostring(lul_settings.newTargetValue)
commande locale = ""
statut local = luup.variable_get (SP_SID, « Status », lul_device)
Si statut == nil lors
statut = "?"
fin
Si relais == 0 alors
Si statut ~ = newTarget then
Command = « Go »
fin
d’autre
Command = « o »... Relais... newTarget
fin
Journal (lul_device, (« envoi: ".. commande))
luup.variable_set (SP_SID, « Target », newTarget, lul_device)
Si commande == "" puis
retourne la valeur true
fin
Si luup.io.write(command) == false alors
LogL1 (lul_device, « erreur envoi de commande »)
luup.set_failure(true)
retourner false
fin
retourne la valeur true
< / run >
< / action >
< / actionList >
< / mise en oeuvre >
Sur la Vera UI5 (j’ai testé cela avec interfaces utilisateur plus tôt), cliquez sur l’onglet applications, puis cliquez sur le sous-onglet « Développer des applications », puis sur "fichiers Luup" sur la gauche. Vous verrez une liste de courant et un lieu pour sélectionner les fichiers à télécharger. Une fois que vous téléchargez les deux fichiers, vous cliquez sur « Create device » sur la gauche et remplissez les informations. « Description » je rentre « zGarage Controller » pour qu’il apparaisse comme le dernier périphérique sur l’interface UI5. Une fois que le dispositif est créé, je recommande que vous « rechargez » pour que tous les périphériques de l’enfant s’afficher correctement.
Vous pouvez ajouter des annexes pour ouvrir et fermer votre porte de garage et vos zones d’irrigation. Vous pouvez télécharger des applications mobiles Vera sur votre téléphone portable et contrôler les zones de garage porte et l’irrigation de n’importe où dans le monde !