Aller au contenu

Rechercher dans la communauté

Affichage des résultats pour les étiquettes 'tuto hc2'.



Plus d’options de recherche

  • Rechercher par étiquettes

    Saisir les étiquettes en les séparant par une virgule.
  • Rechercher par auteur

Type du contenu


Forums

  • Bienvenue
    • Nouveau ? Présentez-vous
    • Le bistrot
    • Mon installation domotique
    • Annonces et suggestions
  • La Home Center et ses périphériques
    • La Home Center pour les nuls
    • HC 2 & Lite
    • HC 3
    • Modules Fibaro
    • Modules Z-wave
    • Périphériques et matériels autres
    • Plugins
    • Quick App
    • Multimédia (audio, vidéo ...)
    • Chauffage et Energie
    • Actionneurs & Ouvrants (Portail, volets, piscines, ...)
    • Eclairage
    • Applications Smartphones et Tablettes
  • Autres solutions domotiques
    • Box / Logiciel
    • Modules Nice (433 & 866 MHz)
    • Modules Zigbee
    • GCE Electronics
    • Modules Bluetooth Low Energy
  • Objets connectés
    • Les Assistants Vocaux
    • Netatmo
    • Philips Hue
    • DIY (Do It Yoursel)
  • Sécurité
    • Alarmes
    • Caméras
    • Portiers
    • Serrures
  • Informatique / Réseau
    • Tutoriels
    • Matériels Réseaux
    • Matériels Informatique
    • NAS
    • Virtualisation
  • Les bonnes affaires
    • Sites internet
    • Petites annonces

Rechercher les résultats dans…

Rechercher les résultats qui…


Date de création

  • Début

    Fin


Dernière mise à jour

  • Début

    Fin


Filtrer par nombre de…

Inscription

  • Début

    Fin


Groupe


Jabber


Skype


Ville :


Intéret :


Version

133 résultats trouvés

  1. jojo

    Backup Variables

    Le soucis de bon nombre d'entre nous est le fait qu'on soit lié à un backup sur une clé USB propriété de Fibaro. L'excellent tuto de Lazer explique comment faire un backup de la clé, mais il faut avoir des connaissances Linux, que perso je n'ai pas. Merci à mprinfo pour son tuto sur la création des variables en LUA qui m'a donné l'idée et les premières infos pour le restore. Merci également à Steven pour son script de génération des ID dont je me suis inspiré pour faire le backup. Alors, ici, je vous présente mon premier couple scène / VD de backup / restore, d'une série que j'espère longue … Avec la scène en mode débug, on crée le backup des variables. On colle le résultat du debug de la scène dans le bouton restore du VD (que vous exportez sur votre disque dur), et en cliquant sur le bouton Restore, il recrée les variables si elles n'existaient pas. Si vous lancez le restoreen Debug, vous avez un débug détaillé de ce qu'il a fait. C'est très utile pour faire un restore sur une nouvelle box (ou après un recovery) Les instructions se trouvent dans le code de la main loop. Version 2.0 : Backup_Variables_v2.0.vfib Backup_Variables_v2.0.lua Version 1.0 : Backup_Variables_v1.0.vfib Backup_Variables_v1.0.lua
  2. Watchdog Version 1.3 Voici une scène permettant de surveiller le fonctionnement des Scènes et Main Loop de Modules Virtuels sur Home Center 2 en version 4.x. Pour ce faire, les messages de la fenêtre de Debug sont analysés. De plus, pour les scènes uniquement, le nombre d'instances est compté. En cas de problème détecté, la scène ou le virtual device considéré est automatiquement redémarré, et une notification peut être envoyée. Copier/coller le script LUA suivant dans une nouvelle scène : --[[ %% autostart %% properties %% globals --]] -------------------------------------------------- -- Scene : Watchdog -- Author : Lazer -- Version : 1.3 -- Date : June 2017 -------------------------------------------------- -- User variables local intervalle = 60 local delay = 15*60 local watchdog = { } local userID = {} -- Email local smartphoneID = {} -- Push local sms = { ["VD_ID"] = 0, -- Virtual Device ID ["VD_Button"] = "1", -- Virtual Device Button ["VG_Name"] = "SMS" -- Global Variable Name } local debug = false -- -- Message function -- function Message(color, message) if color and color ~= "" then fibaro:debug('<span style="color:'..color..';">'..(message or '<nil>')..'</span>') else fibaro:debug(message or '<nil>') end end -- -- Notification function -- function Notification(message, param) local message = message or "<vide>" Message("yellow", "Notification : "..message) if param then for _, notif in ipairs(param) do if debug then Message("grey", notif) end -- Envoi Push if notif == "push" and smartphoneID then for _, id in ipairs(smartphoneID) do if debug then Message("grey", "Send Push smartphone ID : "..id) end fibaro:call(id, "sendPush", message) end -- Envoi Email elseif notif == "email" and userID then for _, id in ipairs(userID) do if debug then Message("grey", "Send Email user ID : "..id) end fibaro:call(id, "sendEmail", "HC2 Watchdog", message) end -- Envoi SMS elseif notif == "sms" and sms then if debug then Message("grey", "Send SMS : VD_ID="..(sms["VD_ID"] or 0).." VD_Button="..(sms["VD_Button"] or "0").." VG_Name="..(sms["VG_Name"] or "")) end fibaro:setGlobal(sms["VG_Name"], message) if sms["VD_ID"] and tonumber(sms["VD_ID"])>0 and sms["VD_Button"] and tonumber(sms["VD_Button"])>0 then fibaro:call(sms["VD_ID"], "pressButton", sms["VD_Button"]) end end end else Message("orange", "Warning : no notification options given") end end -- -- Restart function -- function Restart(type, id, restart, notification, reason) Message("blue", 'Restart '..type..'('..id..')') -- Prepare API URL local getURL = "" local putURL = "" if type:lower() == "scene" then getURL = 'http://127.0.0.1:11111/api/scenes/'..id putURL = 'http://127.0.0.1:11111/api/scenes/'..id elseif type:lower() == "vd" then getURL = 'http://127.0.0.1:11111/api/virtualDevices/'..id putURL = 'http://127.0.0.1:11111/api/virtualDevices/'..id end -- Load VD/Scene local httpClient = net.HTTPClient() httpClient:request(getURL, { success = function(response) if response.status == 200 then local jsonTable = json.decode(response.data) local name = jsonTable.name or "" if restart and restart == true then -- Add new line at end of scene lua code if type:lower() == "scene" and jsonTable.lua then jsonTable.lua = jsonTable.lua .. "\n" response.data = json.encode(jsonTable) end -- Save VD/Scene httpClient:request(putURL, { success = function(response) if response.status == 200 then Message("green", type.."("..id..") successfully restarted") Notification('Watchdog : '..type..' « '..(name or "")..' » ('..id..") a été redémarré : "..(reason or "???"), notification) else Message("red", type.."("..id..") Error : status="..tostring(response.status)) Notification('Watchdog : '..type..' « '..(name or "")..' » ('..id..") n'a pas pu être redémarré : "..(reason or "???"), notification) end end, error = function(err) Message("red", type.."("..id..") Error : "..err) Notification('Watchdog : '..type..' « '..(name or "")..' » ('..id..") n'a pas pu être redémarré : "..(reason or "???"), notification) end, options = { method = 'PUT', -- headers = { -- ["content-type"] = 'application/x-www-form-urlencoded;' -- }, data = response.data } }) else Notification('Watchdog : '..type..' « '..(name or "")..' » ('..id..") doit être redémarré manuellement : "..(reason or "???"), notification) end else Message("red", type.."("..id..") Error : status="..tostring(response.status)) Notification('Watchdog : '..type..' ('..id..") n'a pas pu être redémarré : "..(reason or "???"), notification) end end, error = function(err) Message("red", type.."("..id..") Error : "..err) Notification('Watchdog : '..type..' ('..id..") n'a pas pu être redémarré : "..(reason or "???"), notification) end, options = { method = 'GET' } }) end -- function -- -- Check function -- function Check(interval) Message(nil, "Check") -- Browse VD/Scene list local httpClient = net.HTTPClient() local elements = #watchdog for i = 1, elements do -- Initialization local countscene_found = false if debug then Message(nil, "Check : type="..watchdog[i].type.." id="..watchdog[i].id) end -- Check number of running scene instances if watchdog[i].type:lower() == "scene" and watchdog[i].count and watchdog[i].count > 0 then local countScenes = fibaro:countScenes(watchdog[i].id) if countScenes < watchdog[i].count then Message("orange", watchdog[i].type..'('..watchdog[i].id..') '..countScenes..' running instance') countscene_found = true Restart(watchdog[i].type, watchdog[i].id, watchdog[i].restart, watchdog[i].notification, countScenes..' instance') elseif debug then Message("green", watchdog[i].type..'('..watchdog[i].id..') '..countScenes.." running instance") end end if countscene_found == false then -- Do not enter this loop if scene has already been restarted -- Prepare API URL local getURL = "" if watchdog[i].type:lower() == "scene" then getURL = "http://127.0.0.1:11111/api/scenes/"..watchdog[i].id.."/debugMessages" elseif watchdog[i].type:lower() == "vd" then getURL = "http://127.0.0.1:11111/api/virtualDevices/"..watchdog[i].id.."/debugMessages/0" else Message("red", "Error : unknown type value") end if getURL ~= "" then if debug then Message("grey", getURL) end -- Load VD/Scene debug messages httpClient:request(getURL, { success = function(response) if response.status == 200 then if response.data and response.data ~= "" then local jsonTable = json.decode(response.data) local current_timestamp = os.time() local oldest_timestamp = current_timestamp local match_found = false local no_match_found = false local reason = "" -- Reverse browsing of debug messages for j = #jsonTable, 1, -1 do oldest_timestamp = jsonTable[j].timestamp -- Check if debug message match lookup string within allowed interval if watchdog[i].match.text and watchdog[i].match.text ~= "" and watchdog[i].match.interval > 0 and jsonTable[j].txt:match(watchdog[i].match.text) then if jsonTable[j].timestamp > current_timestamp - watchdog[i].match.interval then if debug then Message("green", watchdog[i].type..'('..watchdog[i].id..') Found string "'..watchdog[i].match.text..'"') end match_found = true end end -- Check if debug message match forbidden string if watchdog[i].no_match.text and watchdog[i].no_match.text ~= "" and jsonTable[j].txt:match(watchdog[i].no_match.text) then Message("orange", watchdog[i].type..'('..watchdog[i].id..') Found string "'..watchdog[i].no_match.text..'"') no_match_found = true reason = os.date('%H:%M:%S', (jsonTable[j].timestamp or 0)) .. " " .. jsonTable[j].type .. " : " .. jsonTable[j].txt break end if watchdog[i].no_match.type and watchdog[i].no_match.type ~= "" and jsonTable[j].type == watchdog[i].no_match.type then Message("orange", watchdog[i].type..'('..watchdog[i].id..') Found type "'..watchdog[i].no_match.type..'"') no_match_found = true reason = os.date('%H:%M:%S', (jsonTable[j].timestamp or 0)) .. " " .. jsonTable[j].type .. " : " .. jsonTable[j].txt break end end -- for if debug and oldest_timestamp > current_timestamp - watchdog[i].match.interval then Message("grey", watchdog[i].type..'('..watchdog[i].id..') oldest debug timestamp more recent than interval') end -- Restart VD/Scene if watchdog[i].match.text and watchdog[i].match.text ~= "" and watchdog[i].match.interval > 0 and match_found == false and oldest_timestamp < current_timestamp - watchdog[i].match.interval then Message("orange", watchdog[i].type..'('..watchdog[i].id..') String "'..watchdog[i].match.text..'" not found') reason = 'Chaine « ' .. watchdog[i].match.text .. ' » non trouvée' if #jsonTable > 0 then reason = reason .. ', dernier message : ' .. os.date('%H:%M:%S', (jsonTable[#jsonTable].timestamp or 0)) .. ' « ' .. (jsonTable[#jsonTable].txt or "<nil>") .. ' »' end Restart(watchdog[i].type, watchdog[i].id, watchdog[i].restart, watchdog[i].notification, reason) --if watchdog[i].no_match.text and watchdog[i].no_match.text ~= "" and no_match_found == true then elseif no_match_found == true then Restart(watchdog[i].type, watchdog[i].id, watchdog[i].restart, watchdog[i].notification, reason) end else Message("red", "Error : empty response") end else Message("red", "Error : status=" .. tostring(response.status)) end end, error = function(err) Message("red", 'Error : ' .. err) end, options = { method = 'GET' } }) end end end -- for -- Wait if interval and interval > 0 then setTimeout(function() Check(interval) end, interval*1000) end end -- function -- -- Main loop -- local trigger = fibaro:getSourceTrigger() if trigger["type"] == "autostart" then Message(nil, "Watchdog instance autostart") -- Check function call delayed to prevent killing all other scenes not already started right after HC2 boot setTimeout(function() Check(intervalle) end, delay*1000) else Message(nil, "Watchdog instance manual launch") -- Call Check function Check(nil) end . Le paramétrage du script s'effectue dans les quelques lignes situées sous le commentaire "User variables" : intervalle : durée entre 2 vérifications delay : délai avant la première vérification. En effet, cette scène ayant la propriété autostart afin de démarrer automatiquement au boot de la box, le risque est de démarrer avant les autres Scène/VD, et de forcer un redémarrage de ceux-ci alors qu'ils n'ont pas encore effectivement démarré. Ce délai laisse donc aux autres Scène/VD le temps de démarrer et de s'initialiser proprement. watchdog : tableau dont chaque ligne représente une Scène ou un Virtual Device à monitorer : type : "Scene" ou "VD" id : valeur numérique représentant l'ID de la Scène ou VD à monitorer match : texte qui doit être trouvé pendant un certain laps de temps afin de confirmer le bon fonctionnement du VD/Scène. Cela correspond typiquement à un message affiché cycliquement à intervalle régulier. Les 2 champs suivants doivent être renseignés pour que la condition soit prise en compte (condition ET) : text : chaine de caractères à trouver interval : durée en secondes no_match : texte qui ne doit pas être trouvé, sous peine de considérer le VD/Scène comme planté. Cela correspond typiquement à un message d'erreur LUA qui entraine le plantage du script. A noter que la condition no_match à priorité sur la condition match, c'est à dire que si le texte recherché par no_match est détecté, le VD/Scène sera redémarrer même si le texte recherché par match a été détecté. L'un ou l'autre des 2 champs suivants peuvent être renseignés pour que la condition soit prise en compte (condition OU) : text : chaine de caractères à trouver type : "ERROR" correspond aux messages affichés en rouge dans la fenêtre de Debug de l'interface HC2. A noter que jusqu'en v4.056, dans une scène une erreur LUA affichait le message en rouge avec le type "ERROR", tandis que depuis les Beta v4.057 et v4.058, cette même erreur s'affiche en blanc sans le type ERROR, par conséquent ce test ne fonctionne plus. En revanche, aucun changement de mode de fonctionnement concernant les Virtual Devices. count : valeur valable pour les scènes uniquement, et indiquant le nombre minimal d'instances qui doivent fonctionner pour confirmer le bon fonctionnement de la scène. Cela correspond typiquement à l'instance de type boucle infinie lancée en autostart. restart : true ou false afin de redémarrer le VD/Scène concerné, ou seulement envoyer une notification signalant qu'il faut le redémarrer manuellement. notification : liste séparée par des virgules des moyens de notifications à employer. userID : liste séparée par des virgules des ID des utilisateurs qui doivent recevoir des notifications par email (le mail est celui configuré pour chaque utilisateur dans le panneau de contrôle d'accès) smartphoneID : liste séparée par des virgules des ID des smartphones qui doivent recevoir des notifications push (à récupérer dans le toolkit de Krikroff ou via l'API : /api/iosDevices) sms : si vous avez une passerelle SMS sous Android avec SMS Gateway (ou équivalent) pilotée par un module virtuel, il faut renseigner ici les informations nécessaires : VD_ID : ID du module virtuel VD_Button : ID du bouton du module virtuel VG_Name : nom de la variable globale debug : true ou false afin d'activer l'affichage étendu dans la fenêtre de débugage de la scène. Exemple de paramètres : -- User variables local intervalle = 60 local delay = 15*60 local watchdog = { {type = "Scene", id = 1, match = {text="", interval=0}, no_match = {text=""}, count=1, restart=true, notification = {"push", "email", "sms"}}, -- Présence Lazer {type = "Scene", id = 2, match = {text="Last run", interval=2*60}, no_match = {text=""}, count=1, restart=true, notification = {"push", "email", "sms"}}, -- DomoCharts {type = "Scene", id = 3, match = {text="Durée des traitements", interval=11*60}, no_match = {text=""}, count=1, restart=true, notification = {"push", "email", "sms"}}, -- GEA {type = "VD", id = 1, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- Surveillance Station {type = "VD", id = 2, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- Clock Sync {type = "VD", id = 3, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- My Batteries {type = "VD", id = 4, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- Evénements {type = "VD", id = 5, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- Network Monitor {type = "VD", id = 6, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- GEA Alarm {type = "VD", id = 7, match = {text=" ", interval=30}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}}, -- Sonos Player (Tk.isTraceEnabled = true) {type = "VD", id = 8, match = {text="Start main process", interval=31*60}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email", "sms"}} -- Freebox Serveur } local userID = {1} -- Email local smartphoneID = {1, 2} -- Push local sms = { ["VD_ID"] = 99, -- Virtual Device ID ["VD_Button"] = "1", -- Virtual Device Button ["VG_Name"] = "SMS" -- Global Variable Name } local debug = false
  3. Utilisation de fibaro:call en fonction du module commandé Voici un lien qui vous donnera les actions que l'on peut utiliser pour chaque type de modules fibaro http://www.fibarouk.co.uk/support/lua/actions-use-fibarocall-api/ armed close firmwareUpdate open pollingDeadDevice pollingTimeSec pressButton requestNodeNeighborUpdate resetMeter sendDefinedEmailNotification sendDefinedPushNotification sendDefinedSMSNotification sendEmail sendGlobalEmailNotifications sendGlobalPushNotifications sendGlobalSMSNotifications sendPhotoToEmail sendPhotoToUser sendPush sendSipUserID setArmed setB setColor setG setProperty setProtectionLocalAndRF setR setSipDisplayName setSipUserID setSipUserPassword setSlider setTargetLevel setTime setValue setValue2 setW startProgram stop turnOff turnOn close Application pour : blind Description: Closes a blind. Usage: This action takes no arguments. Exemple: -- Close the blind with the device ID of 94 fibaro:call(94, "close") open Application pour : blind Description: Opens a blind. Usage: This action takes no arguments. Exemple: -- Open the blind with the device ID of 94 fibaro:call(94, "open") pressButton Application pour : virtual_device Description: Triggers a virtual device button press. Usage: This action takes one argument. The number of the button to be pressed. Each element of a virtual device has a unique number starting from 1. If your virtual device has two labels followed by two buttons, the buttons will be numbered 3 and 4. Exemple: -- Trigger a button press of button 3 of -- the virtual device with an ID of 358 fibaro:call(358, "pressButton", "3") sendDefinedEmailNotification Application pour : HC_user Description: Sends a notification to the email address associated with a user. Usage: This action takes one argument. The id of the notification to be sent. Exemple: 1-- Send notification 2 via email to the -- address associated with user 107. fibaro:call(107, "sendDefinedEmailNotification", "2") sendDefinedPushNotification Application pour : iOS_device Description: Sends a push notification to a device. Usage: This action takes one argument. The id of the notification to be sent. Exemple: -- Send notification 2 via push to modile device number 10. fibaro:call(10, "sendDefinedPushNotification", "2") sendDefinedSMSNotification Application pour : HC_user Description: Sends an SMS notification to a phone number. Usage: This action takes two arguments. The phone number to send the message to.This should be in the form xxyyyyyyyyy where xx = country code and yyyyyyyyy = phone number. The id of the notification to be sent. Exemple: -- Send notification 3 via SMS to device number +441234567890. fibaro:call(2, "sendDefinedSMSNotification", "441234567890", "3") sendEmail Application pour : HC_user Description: Sends an email to the email address associated with a user. Usage: This action takes two arguments. The subject of the email. The message body of the email. Exemple: -- Send an email to the email address associated with user 2. local subject = "This is the subject of the email." local message = "This is the body of the email.\nWith a line break." fibaro:call(2, "sendEmail", subject, message) sendPhotoToEmail Application pour : IP_camera Description: Sends a still image from a camera to a specified email address. Usage: This action takes one argument. The email address to send the image to. Exemple: -- Send an image from camera 120 to someone@this.address. fibaro:call(120, "sendPhotoToEmail", "someone@this.address") sendPhotoToUser Application pour : IP_camera Description: Sends a still image from a camera to the email address associated with a user. Usage: This action takes one argument. The id number of the user to send the image to. Exemple: -- Send an image from camera 120 to -- the email address associated with user 2. fibaro:call(120, "sendPhotoToUser", "2") sendPush Application pour : iOS_device Description: Sends a push notification to an iOS device. The device must have connected with the Home Centre recently, however once this connection has been made the app can be closed. Usage: This action takes one argument. The message to be pushed to the device. Exemple: -- Send a push notification to the iOS device with the ID of 10 fibaro:call(10, 'sendPush', 'This is the message to be pushed.') setArmed Application pour : motion_sensor, door_sensor, window_sensor, smoke_sensor Description: Arms or disarms a device. Usage: This action takes one argument. The armed state of the device. 0 = disarmed, 1 = armed. Exemple: -- Arm the door sensor with device ID of 174 fibaro:call(174, "setArmed", "1") -- Disarm the door sensor with device ID of 174 fibaro:call(174, "setArmed", "0") setB Application pour : rgb_driver Description: Sets the brightness of the blue channel of an rgb_driver. Usage: This action takes one argument. The brightness (0-99) of the channel. Exemple: -- Set the brightness of the blue channel of device 81 to 56% fibaro:call(81, "setB", "56") setColor Application pour : rgb_driver Description: Sets the colour of an rgb_driver. This is done by setting the brightness of the red, green, blue and white channels. Usage: This action takes four arguments. The brightness (0-99) of the red channel. The brightness (0-99) of the green channel. The brightness (0-99) of the blue channel. The brightness (0-99) of the white channel. Even if the device is in RGB mode, the white channel needs to be specified – in this case, just use 0. Exemple: -- Set the colour of device 81 to a blue-indigo colour -- (60% red, 23% green, 99% blue, 0% white) fibaro:call(81, "setColor", "60", "23", "99", "0") setG Application pour : rgb_driver Description: Sets the brightness of the green channel of an rgb_driver. Usage: This action takes one argument. The brightness (0-99) of the channel. Exemple: -- Set the brightness of the green channel of device 81 to 56% fibaro:call(81, "setG", "56") setProperty Application pour : virtual_device Description: Sets value of the elements of a virtual device (labels and sliders). Usage: This action takes two arguments. The name of the element. The value to set the element to. Exemple: -- Set the content of Label1 in virtual device 1170 to 'program 1' fibaro:call(1170, "setProperty", "ui.Label1.value", "program 1") -- Set the value of Slider1 in virtual device 1170 to 45 fibaro:call(1170, "setProperty", "ui.Slider1.value", "45") setR Application pour : rgb_driver Description: Sets the brightness of the red channel of an rgb_driver. Usage: This action takes one argument. The brightness (0-99) of the channel. Exemple: -- Set the brightness of the red channel of device 81 to 56% fibaro:call(81, "setR", "56") setSlider Application pour : virtual_device Description: Triggers a change in the value of a virtual device slider. Usage: This action takes two arguments. The number of the slider to be changed. Each element of a virtual device has a unique number starting from 1. If your virtual device has two labels followed by two buttons and then a slider, the slider will be numbered 5. The value (0-99) to set the slider to. Exemple: -- Set the slider with an ID of 2 of the -- virtual device with an ID of 334 to 50% fibaro:call(334, "setSlider", "2", "50") setTargetLevel Application pour : thermostat_setpoint Description: Sets the target temperature of a thermostat_setpoint. Usage: This action takes one argument. A temperature in degrees. Exemple: -- Set the target temperature of device 117 to 18 degrees. fibaro:call(117, "setTargetLevel", "18") setTime Application pour : thermostat_setpoint Description: Sets the value of the timeStamp property of the thermostat_setpoint. Usage: This action takes one argument. A timestamp. Exemple: -- Set the timeStamp of the thermostat_setpoint -- with device ID of 117 to 2 hours from now. fibaro:call(117, "setTime", tonumber(os.time()) + 120*60) setValue Application pour : dimmable_light, blind, rgb_driver Description: Sets the brightness of a dimmable_light or rgb_driver or sets the position of a blind. When changing the brightness of rgb_drivers, all channels are set to the same level (white light). Usage: This action takes one argument. A value (0-99) representing the brightness of the light or position of the blind. For a blind, 0 = fully closed, 99 = fully open. Exemple: -- Set the brightness of the light with device ID of 68 to 25%. fibaro:call(68, "setvalue", "25") -- Set the position of the blind with the device ID of 94 to 75% open. fibaro:call(94, "setvalue", "75") setW Application pour : rgb_driver Description: Sets the brightness of the white channel of an rgb_driver. Usage: This action takes one argument. The brightness (0-99) of the channel. Exemple: -- Set the brightness of the white channel of device 81 to 56% fibaro:call(81, "setW", "56") startProgram Application pour : rgb_driver Description: Instruct the rgb_driver to play one of the preconfigured colour programmes. Usage: This action takes one argument. The light programme number to run. Exemple: -- Start programme number 2 ("storm") on device number 81 fibaro:call(81, "startProgram", "2") stop Application pour : blind Description: Stops the movement of a blind. Usage: This action takes no arguments. Exemple: -- Stop the blind with the device ID of 94 fibaro:call(94, "stop") turnOff Application pour : binary_light, dimmable_light, rgb_driver Description: Turns off a device. Usage: This action takes no arguments. Exemple: -- Turn off device number 58. fibaro:call(58, "turnOff") turnOn Application pour : binary_light, dimmable_light, rgb_driver Description: Turns on a device. Usage: This action takes no arguments. Exemple: -- Turn on device number 58. fibaro:call(58, "turnOn")
  4. Lazer

    Network Monitor

    Network Monitor Version 1.20 Voici un module virtuel permettant de surveiller plusieurs équipements sur le réseau local (et aussi sur Internet), et d'envoyer des notifications en cas de problème détecté. Icônes : Je propose ces 2 icônes, mais d'autres icônes sont disponibles dans les pages du topic : Configuration : Après import du module virtuel, modifier la section "User Variables" du 1er bouton du module virtuel : -- User variables local userID = {5} -- Mail local smartphoneID = {73, 127} -- Push local sms = { ["VD_ID"] = 98, -- Virtual Device ID ["VD_Button"] = "1", -- Virtual Device Button ["VG_Name"] = "SMS" -- Global Variable Name } local icons = { ["OK"] = 1028, -- Normal Icon ID ["Error"] = 1045 -- Error Icon ID } local DEVICES = { -- ["Service Name"] = { IP Address , Port, Protocol, Data to send, Expected return code, Expected data, Retry, {Notification methods}, VG, VG }, ["Eco-Devices"] = {"192.168.1.1", 80, "http", "/index1.htm", 200, "Eco Devices" , 1, {"push", "email", "sms"}, nil, nil}, ["HP ProLiant Remote Access Card"] = {"192.168.1.2", 80, "http", "/login.html", 200, "Remote Access Card" , 1, { "email" }, nil, {"Vacances", "1"}}, ["HP ProLiant Gen8 ILO"] = {"192.168.1.3", 443, "tcp", "", nil, "" , 1, { "email" }, nil, nil}, ["ESXi"] = {"192.168.1.4", 80, "http", "/", 301, "" , 1, {"push", "email", "sms"}, nil, nil}, ["Synology DiskStation"] = {"192.168.1.5", 5000, "http", "/webman/index.cgi", 200, "DiskStation" , 1, {"push", "email", "sms"}, nil, nil}, ["Raspberry PI"] = {"192.168.1.6", 80, "http", "/", 200, "Welcome to nginx" , 1, {"push", "email", "sms"}, nil, nil}, ["Sonos"] = {"192.168.1.7", 1400, "http", "/status", 200, "Options" , 1, {"push", "email" }, nil, {"Vacances", "1"}}, ["SMS Gateway"] = {"192.168.1.8", 9090, "http", "/", 200, "Welcome to SMS Gateway" , 5, {"push", "email" }, nil, nil}, ["VRT-IP"] = {"192.168.1.9", 80, "http", "/", 200, "Volets Roulant de Toit" , 1, {"push", "email" }, nil, nil}, ["IPX800"] = {"192.168.1.10", 80, "http", "/user/index2.htm", 200, "IPX800" , 1, {"push", "email" }, nil, nil}, ["Foscam"] = {"192.168.1.11", 88, "http", "/", 200, "IPCam Client" , 1, {"push", "email", "sms"}, nil, {"Vacances", "0"}}, ["Hikvision"] = {"192.168.1.12", 80, "http", "/doc/page/login.asp", 200, "login" , 1, {"push", "email", "sms"}, nil, nil}, ["HAproxy"] = {"192.168.1.13", 80, "http", "/", 503, "" , 1, {"push", "email", "sms"}, nil, nil}, ["FHEM"] = {"192.168.1.14", 8083, "http", "/fhem", 200, "EnOcean" , 1, {"push", "email", "sms"}, nil, nil}, ["Freebox"] = {"192.168.1.15", 80, "http", "/login.php", 200, "Freebox OS" , 1, { "sms"}, nil, nil}, ["OpenVPN"] = {"192.168.1.16", 443, "tcp", "", nil, "" , 1, { "email", "sms"}, nil, nil}, ["Redhat"] = {"192.168.1.17", 22, "tcp", nil, nil, "OpenSSH" , 1, { "email" }, nil, nil}, ["Google"] = {"www.google.fr", 80, "http", "/", 200, "Recherche Google" , 1, { "sms"}, nil, nil}} } local debug = false userID : liste séparée par des virgules des ID des utilisateurs qui doivent recevoir des notification par email (le mail est celui configuré pour chaque utilisateur dans le panneau de contrôle d'accès) smartphoneID : liste séparée par des virgules des ID des smartphones qui doivent recevoir des notifications push (à récupérer dans le toolkit de Krikroff ou via l'API : /api/iosDevices) sms : si vous avez une passerelle SMS sous Android avec SMS Gateway (ou équivalent) pilotée par un module virtuel, il faut renseigner ici les informations nécessaires. icons : si vous avez 2 icônes personnalisées, remplacer les valeurs nil par les ID numériques de vos icones (à trouver dans /api/icons) DEVICES : c'est la partie la plus longue à paramétrer, pour cela je vous ai laissé un exemple de tout ce que je monitore chez moi (j'ai juste changé les IP). C'est assez parlant, vous pouvez copier/coller en respectant bien la syntaxe. A noter que si l'avant-dernière colonne qui contient le nom facultatif d'une variable globale à incrémenter, celle-ci est automatiquement créée par le module. La dernière colonne permet d'annuler le monitoring d'un équipement particulier en fonction de la valeur d'une variable globale. debug : true ou false afin d'activer l'affichage étendu dans la fenêtre de débugage du bouton du module virtuel. Dans la Main Loop, le code est de Steven. Il y a une variable nbHeure permettant de paramétrer l'intervalle de vérification, par défaut à 1 heure. Si vous voulez un rafraichissement inférieur à 40 minutes, il suffit de tout remplacer par un simple fibaro:sleep(), car cette fonction ne plante pas pour les durées inférieures. Network_Monitor_v1.01.vfib Network_Monitor_v1.10.vfib Network_Monitor_v1.20.vfib
  5. Steven

    Evénements

    Evénements Module virtuel pour afficher les derniers événements Lorsque l'on fait des tests, il est parfois pratique d'avoir la liste des derniers événements ayant eu lieu sur notre HC2. Voici donc mon dernier module virtuel avant les vacances :-) Comme vous pouvez le voir, ce module affiche les 10 événements en oubliant volontairement les modules de températures. Si vous voulez voir plus d'événements, il vous faudra rajouter vous-même des labels en faisant juste attention que leur ID suivent la numérotation Label11, Label12, Label13, ... et modifier la position du bouton rafraîchir dans le Main Loop. J'ai volontairement ajouté la pièce pour certaine personne qui se reconnaîtrons Ce dernier affiche donc : Le nom du module concerné La pièce dans laquelle il se trouve Son ancienne valeur Sa nouvelle valeur L'heure de l'événement Ce module se rafraîchi automatiquement toutes les 3 secondes . . . Installation Il vous suffit juste d'importer le module virtuel ci-joint puis de modifier votre pseudonyme et mot de passe qui se trouve dans le bouton Rafraichir local user = "admin" local pwd = "password" HC2 = Net.FHttp("127.0.0.1",80) HC2:setBasicAuthentication(user, pwd) ... Cordialement Evenements.vfib
  6. Voici un périphérique virtuel qui a pour utilité de détecter et de notifier un utilisateur lorsqu’une nouvelle mise à jour est disponible en téléchargement pour le HC2 de Fibaro. (Publié sur le blog de Pascal le 21-03-2014) Version 1.0.8 - Mise à jour : 13/01/2015 Vous pouvez télécharger la dernière version ici et sur le blog consulter la notice d'installation et d'utilisation bien que tout soit simplifié au maximum Version 1.0.8 - Mise à jour : 13/01/2015 (Pour HC2 >= V4.031) Aucunes configuration nécessaire dorénavant, il faut importer le vd et c'est tout. Compatible API REST de la V4 L'unique paramétrage restant à faire par l'utilisateur est de préciser dans le code (dans le mainloop) l' ID du smartphone et de l' utilisateur pour les notifications. local userID = 2; local smartphoneID = 844; Version 1.0.6 - Mise à jour : 08/09/2014 (Pour HC2 <= V3.600) L'image principale du Virtual Device réapparaît maintenant automatiquement après l'appui sur un bouton Notification de mise à jour disponible sur la home du périphérique virtual. Remise en forme et révision du code Version 1.0.5 - Mise à jour : 04/09/2014 Amélioration: Récupération automatique de la variable en cas de données corrompues (suggéré par Lazer) Mise à jour des traductions Version 1.0.4 - Mise à jour : 03/09/2014 Nouveau: Affichage du numéro de version dans l'interface utilisateur et ajouté à la notification (mail & push) Nouveau: Icône d'un membre du forum domotique-fibaro.fr, merci Lazer Amélioration: Envoyer une notification si une nouvelle mise à jour est détectée et ne pas répéter les envois. Corrections mineures. Version 1.0.2 - Mise à jour : 21/02/2014 Corrections mineures. Version 1.0.1 - Mise à jour : 14/02/2014 Installation automatisée pour faciliter la mise en place des variables globales et du paramétrage de l’application. Possibilité de choisir le type de notification avec un bouton à trois états depuis l’interface graphique: Email, Push ou les deux. Possibilité de choisir le type de mise à jour devant être notifié avec un bouton à trois états depuis l’interface graphique : Bêta, stable ou les deux. Multilingue : Français, Anglais. Téléchargements: UpdateNotifier_1.0.8.zip pour HC2 en V4.xxx
  7. Krikroff

    Hc2 Waze Calculator

    Après longue absence voici un petit script permettant d’utiliser sur notre HC2 le service de trafic et de navigation communautaire WAZE (https://www.waze.com/fr/) Le principe du script est très simple : 1 scène pour interroger l’ API Waze pour tous les trajets parametrés et autant de vd qui seront mis à jour par la dite scène.] 1 - Installation Importer le vd HC2_Waze_Calculator.vfib sur le HC2, 1x pour un trajet, 2x pour deux etc... Créer la scène HC2 Waze Calculator cf. fichier HC2 Waze Calculator Scene.txt puis passer au paramètrage 2 - Paramétrage Configurer l'object params: nom, id du vd cible, polling, latitude, longiture etc... pour tous les trajets. Pour trouver les coordonnées GPS, latitude et longitude il existe les services : www.coordonnees-gps.fr, www.torop.net/coordonnees-gps.php, www.gpsfrance.net etc. local params = { { name = "Trajet 1", virtualDeviceId = 1449, from = { name = "Palais de l'Élysée", x = 2.3167538999999806, -- longitude y = 48.8704156 -- latitude }, to = { name = "Théâtre Guignol", x = 2.311747670173645, -- longitude y = 48.86977710077997 -- latitude }, pollingMs = 60*1000 }, { name = "Trajet 2", virtualDeviceId = 1452, from = { name = "Palais de l'Élysée", x = 2.3167538999999806, -- longitude y = 48.8704156 -- latitude }, to = { name = "Théâtre Guignol", x = 2.311747670173645, -- longitude y = 48.86977710077997 -- latitude }, pollingMs = 5*60*1000 } } 4 - Icône Merci à Moicphil de m’avoir suggéré la chose et aussi pour son icône tip-top Fichier du vd: HC2_Waze_Calculator.vfib Fichier de la scène: HC2 Waze Calculator Scene.txt
  8. Suite à un besoin particulier je voulais m'assurer de la taille maximale d'une variable globale afin de persister des informations de type chaînes de caractères si vous souhaitez faire l’expérience vous même, il faut créer une variable globale, ici: varMaxLength, puis dans un périphérique virtuel ajouter le code suivant dans un bouton for i=1, 250 do fibaro:setGlobal("varMaxLength", fibaro:getGlobalValue("varMaxLength").."0"); fibaro:debug("global variable length is now "..string.len(fibaro:getGlobalValue("varMaxLength"))); end pour remettre la variable à zero, dans un autre bouton le code suivante: fibaro:setGlobal("varMaxLength", ""); 228 est donc la taille maximale d'une chaîne dans une variable globale
  9. Bonjour, Voilà , le code est enfin correct, je le partage donc. Je n'ai pas beaucoup de temps ce soir, mais voici 2-3 points: - Ce VD crée automagiquement 3 Variables globales (si demandé dans les options) - Ce VD est multilingue - Ce VD fait des push de la météo à deux moments de la journée - CE VD s'adapte aux mobiles et à l'interface web - Ce VD télécharge automagiquement les icônes - Ce VD a besoin d'une clef APi de Wunderground, - La partie mobile du VD n'est pas encore complètement terminée. Merci à Jompa68 de forum.fibaro.com pour le code de base Pour l'installer: - Téléchargez le vfib attaché et importez le dans la HC2 - Changer l'icône du slider avec l'icône attachée: - Utilisez le dernier code disponible sur github: https://github.com/sjauquet/YAMSWU Qui ajoute la création de VG qui contiendront la météo prononçable par une synthèse vocale comme S.A.R.A.H.: http://www.domotique-fibaro.fr/index.php/topic/6446-yams-wu-yet-another-meteo-station-wunderground-version/page-4#entry132933 et placez-le dans le main loop du VFIB (V3.9) attaché à ce message - Changez l'api key. Pour cela, créez un compte wunderground et allez la récupérer ici: http://www.wunderground.com/weather/api/ WU.APIkey = "xxxxxxxxxxxxxxx" - Ensuite définissez les variables suivantes: WU.PWS = "IGVLEBOR5" -- The PWS location to get data from (Personal Weather Station) WU.LOCID = "SWXX0076" -- The location ID to get data from (City location) WU.station = "PWS" -- Choose your prefered method to retrieve from: PWS or LOCID Personnellement je préfère utiliser les infos d'une pws près de chez moi. Pour trouver ces variables: @bono2007 écrivait: Pour trouver, j'ai eu la station PWS en cliquant dans "Search locations" sur Wunderground, on te propose "search nearest station", et il a proposé une station météo proche. Sinon en entrant ta ville, tu peux cliquer sur "change Station" et tu verras une carte avec d'autres stations météo. Exemple : j'ai entré "Boussois" et j'ai comme station météo "Cit du Grand Bois, Récquignies ( IRECQUIG2) J'ai modifié WU.PWS = "IRECQUIG2" Et tout devrait fonctionner :-) Virtual device avec code V3.7 (ancien à remplacer !!! ) YAMS_WU.vfib Virtual device avec code V3.9 YAMS_WU V3.9.vfib Voici les dernières captures d'écran pour avoir une idée: à gauche en mode Browser Web, à droite en mode Mobile (les icônes ne sont pas téléchargeables) Attention, ancien code ci-dessous ! ------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------- -- WU WeatherData - Fetch weather data from wunderground.com. Multilanguage support! -- Original Code by Jonny Larsson 2015 http://forum.fibaro.com/index.php?/topic/19810-wu-weatherdata-version-202-2015-10-25/ -- forked by Sébastien Jauquet 11/2015 -- Inspired by GEA(steven), stevenvd, Krikroff and many other users. -- Source - forum.fibaro.com, domotique-fibaro.fr and worldwideweb -- -- Version 3.7 -- -- PWS = Personal Weather Station -- LOCID = Public station -- -- 2014-03-22 - Permissions granted from Krikroff -- 2014-03-23 - Added rain and forecast, Added FR language. -- 2014-03-23 - Language variable changed to get the translation from wunderground.com in forcast -- 2014-03-24 - Added PL language -- 2014-03-24 - Select between PWS or LOCID to download weather data -- 2015-10-23 - New source code. -- 2015-11-13 - V3.0 - Fork Code by Sebastien Jauquet (3 days forecast, rain in mm) -- 2015-11-14 - V3.1 - Compatibilty with GEA, French translation -- 2015-11-14 - V3.2 - Catch rain errors (-999mm null empty etc.) -- 2015-11-14 - V3.3 - Catch json decode error (was stopping main loop) with pcall (can be extended to other jdon datas if needed) -- 2015-11-16 - V3.4 - Generate HTML and non HTML version (for compatibility with mobiles) -- 2015-11-18 - V3.5 - Fixed bug not updating Meteo_Day becaus WU.now was only updated at first launch -- 2015-11-18 - V3.6 - Merged some changes from jompa new version -- 2015-11-18 - Added autmatic creation of Global Variables if not existing -- 2015-11-19 - V3.7 - Modify schedule management and CleanUp code -- Look for nearest station here: http://www.wunderground.com ------------------------------------------------------------------------------------------- -- MAIN CODE -- ------------------------------------------------------------------------------------------- WU = {} -- WU settings WU.APIkey = "xxxxxxxxxxxxxxx" -- Put your WU api key here WU.PWS = "IGVLEBOR5" -- The PWS location to get data for (Personal Weather Station) WU.LOCID = "SWXX0076" -- The location ID to get data for (City location) WU.station = "PWS" -- PWS or LOCID -- Other settings WU.translation = {true} WU.language = "FR"; -- EN, FR, SW, PL (default is en) WU.smartphoneID = 1347 -- your smartphone ID WU.sendPush = true -- send forecast as push message WU.push_fcst1 = "07:00" -- time when forecast for today will be pushed to smartphone WU.push_fcst2 = "18:15" -- time when forecast for tonight will be pushed to smartphone WU.GEA = true -- subst % with %% when storing in the VG's (because gea bug with % in push messages) WU.CreateVG = true -- will atomaticaly create global variables at first run if = true updateEvery = 30 -- get data every xx minutes WU.startTime = os.time() WU.scheduler = os.time()+60*updateEvery WU.currentDate = os.date("*t"); WU.now = os.date("%H:%M"); DoNotRecheckBefore = os.time() WU.selfId = fibaro:getSelfId() WU.version = "3.7" WU.translation["EN"] = { Push_forecast = "Push forecast", Exiting_loop_slider = "Exiting loop earlier (Slider Changed)", Exiting_loop_push = "Exiting loop earlier (For push)", Last_updated = "Last updated", Temperature = "Temperature", Humidity = "Humidity", Pressure = "Pressure", Wind = "Wind", Rain = "Rain", Forecast = "Forecast", Station = "Station", Fetched = "Fetched", Data_processed = "Data processed", Update_interval = "Next update will be in (min)", No_data_fetched = "No data fetched", NO_STATIONID_FOUND = "No stationID found", NO_DATA_FOUND = "No data found" } WU.translation["FR"] = { Push_forecast = "Push des prévisions", Exiting_loop_slider = "Sortie de boucle (Slider Changé)", Exiting_loop_push = "Sortie de boucle (Pour Push)", Last_updated = "Mise à jour", Temperature = "Actuellement", Humidity = "Hum", Pressure = "Pression", Wind = "Vent", Rain = "Pluie", Forecast = "Prévisions pour ce", Station = "Station", Fetched = "Données Reçues", Data_processed = "Données mises à jour", Update_interval = "Prochaine Mise à jour prévue dans (min)", No_data_fetched = "Pas de données reçues !!", NO_STATIONID_FOUND = "StationID non trouvée !!", NO_DATA_FOUND = "Pas de données disponibles !!" } WU.translation["SW"] = { Push_forecast = "Push forecast", Exiting_loop_slider = "Exiting loop earlier (Slider Changed)", Exiting_loop_push = "Exiting loop earlier (For push)", Last_updated = "Last updated", Temperature = "Temperatur", Humidity = "Fuktighet", Pressure = "Barometer", Wind = "Vind", Rain = "Regn", Forecast = "Prognos", Station = "Station", Fetched = "Hà¤mtat", Data_processed = "All data processat", Update_interval = "Nà¤sta uppdatering à¤r om (min)", No_data_fetched = "Inget data hà¤mtat", NO_STATIONID_FOUND = "StationID ej funnet", NO_DATA_FOUND = "Ingen data hos WU" } WU.translation["PL"] = { Push_forecast = "Push prognoza", Exiting_loop_slider = "Exiting loop earlier (Slider Changed)", Exiting_loop_push = "Exiting loop earlier (For push)", Last_updated = "Last updated", Temperature = "Temperatura", Humidity = "Wilgotnosc", Pressure = "Pressure", Wind = "Wiatr", Rain = "Rain", Forecast = "Forecast", Station = "Station", Fetched = "Fetched", Data_processed = "Data processed", No_data_fetched = "No data fetched", Update_interval = "Next update will be in (min)", NO_STATIONID_FOUND = "No stationID found", NO_DATA_FOUND = "No data found" } WU.translation["NL"] = { Push_forecast = "Push verwachting", Exiting_loop_slider = "Exiting loop earlier (Slider Changed)", Exiting_loop_push = "Exiting loop earlier (For push)", Last_updated = "Last updated", Temperature = "Temperatuur", Humidity = "Vochtigheid", Pressure = "Druk", Wind = "Wind", Rain = "Regen", Forecast = "Verwachting", Station = "Weerstation", Fetched = "Ontvangen", Data_processed = "Gegevens verwerkt", Update_interval = "Volgende update in (min)", No_data_fetched = "Geen gegevens ontvangen", NO_STATIONID_FOUND = "Geen stationID gevonden", NO_DATA_FOUND = "Geen gegevens gevonden" } WU.translation["DE"] = { Push_forecast = "Push vorhersage", Exiting_loop_slider = "Exiting loop earlier (Slider Changed)", Exiting_loop_push = "Exiting loop earlier (For push)", Last_updated = "Last updated", Temperature = "Temperatur", Humidity = "Luftfeuchtigkeit", Pressure = "Luftdruck", Wind = "Wind", Rain = "Regen", Forecast = "Vorhersage", Station = "Station", Fetched = "Abgerufen", Data_processed = "Daten verarbeitet", No_data_fetched = "Keine Daten abgerufen", Update_interval = "Das nà¤chste Update in (min)", NO_STATIONID_FOUND = "Keine stationID gefunden", NO_DATA_FOUND = "Keine Daten gefunden" } Debug = function ( color, message ) fibaro:debug(string.format('<%s style="color:%s;">%s</%s>', "span", color, message, "span")); end WU.createGlobalIfNotExists = function (varName, defaultValue) if (fibaro:getGlobal(varName) == "") then Debug("red", "Global Var: "..varName.." HAS BEEN CREATED") newVar = {} newVar.name = varName HC2 = Net.FHttp("127.0.0.1", 11111) HC2:POST("/api/globalVariables", json.encode(newVar)) end end WU.substPercent = function(doublePercentSymbol) if WU.GEA then doublePercentSymbol = string.gsub(doublePercentSymbol, "%%.", "%%%%") end return doublePercentSymbol end WU.cleanJson = function(jsontocheck,returnIfTrue) if jsontocheck == "-999.00" or jsontocheck == "--" or jsontocheck == json.null then jsontocheck = returnIfTrue end local ok = pcall(function() testConcatenate = "Test Concatenate: " .. jsontocheck -- test for non concatenate value end ) if (not ok) then decode_error = true Debug( "red", "decode raised an error") fibaro:call(WU.smartphoneID , "sendPush", "decode error in WU Meteo") end return jsontocheck end WU.HtmlColor = function(StringToColor,color) if MobileDisplay == false then StringToColor= "<font color=\""..color.."\"> "..StringToColor.."</font>" end return StringToColor end WU.IconOrText = function(icon,txt) if MobileDisplay == false then IconOrText = "<img src="..icon.."\>" else IconOrText = txt end return IconOrText end WU.getSlider = function() ValeurSliderfunct = fibaro:getValue(WU.selfId , "ui.WebOrMobile.value") return tonumber(ValeurSliderfunct) end WU.setSlider = function(position) fibaro:call(WU.selfId , "setProperty", "ui.WebOrMobile.value", position) return WU.getSlider() end WU.checkMobileOrWeb = function() ValeurSliderSleep = WU.getSlider() -- check slider value at first run if ValeurSliderSleep <= 50 then if ValeurSliderSleep == 1 then MobileDisplay = false else MobileDisplay = false WU.runDirect = 1 sleepAndcheckslider = 20*updateEvery -- exit wait loop Debug("orange", WU.translation[WU.language]["Exiting_loop_slider"]); end WU.setSlider(1) -- désactive le run immediat lors du prochain test end if ValeurSliderSleep >= 50 then if ValeurSliderSleep == 98 then else MobileDisplay = true WU.runDirect = 1 sleepAndcheckslider = 20*updateEvery -- exit wait loop Debug("orange", WU.translation[WU.language]["Exiting_loop_slider"]); end WU.setSlider(98) -- désactive le run immediat lors du prochain test end return WU.getSlider() end WU.fetchWU = function() decode_error = false WU.checkMobileOrWeb() local WGROUND = Net.FHttp("api.wunderground.com",80); local response ,status, err = WGROUND:GET("/api/"..WU.APIkey.."/conditions/forecast/lang:"..WU.language.."/q/"..WU.station..":"..locationID..".json"); if (tonumber(status) == 200 and tonumber(err)==0) then Debug( "cyan", WU.translation[WU.language]["Fetched"]) if (response ~= nil) then WU.now = os.date("%H:%M") jsonTable = json.decode(response); if jsonTable.response.error ~= nil then Debug( "red", WU.translation[WU.language]["NO_DATA_FOUND"]) fibaro:sleep(15*1000) return end stationID = jsonTable.current_observation.station_id; humidity = jsonTable.current_observation.relative_humidity temperature = jsonTable.current_observation.temp_c pression = jsonTable.current_observation.pressure_mb wind = jsonTable.current_observation.wind_kph rain = WU.cleanJson(jsonTable.current_observation.precip_today_metric,"0") weathericon = jsonTable.current_observation.icon_url fcstday1 = jsonTable.forecast.txt_forecast.forecastday[1].title -- Day meteo fcst1 = jsonTable.forecast.txt_forecast.forecastday[1].fcttext_metric fcst1icon = jsonTable.forecast.txt_forecast.forecastday[1].icon_url fcst1SmallTxt = jsonTable.forecast.simpleforecast.forecastday[1].conditions fcst1Tmax = jsonTable.forecast.simpleforecast.forecastday[1].high.celsius fcst1Tmin = jsonTable.forecast.simpleforecast.forecastday[1].low.celsius fcst1avewind =jsonTable.forecast.simpleforecast.forecastday[1].avewind.kph fcst1avewinddir =jsonTable.forecast.simpleforecast.forecastday[1].avewind.dir fcst1mm = WU.cleanJson(jsonTable.forecast.simpleforecast.forecastday[1].qpf_day.mm,"0") fcstday2 = jsonTable.forecast.txt_forecast.forecastday[2].title -- Evening Meteo fcst2 = jsonTable.forecast.txt_forecast.forecastday[2].fcttext_metric fcst2icon = jsonTable.forecast.txt_forecast.forecastday[2].icon_url fcst2SmallTxt = jsonTable.forecast.simpleforecast.forecastday[2].conditions fcst2Tmax = jsonTable.forecast.simpleforecast.forecastday[2].high.celsius fcst2Tmin = jsonTable.forecast.simpleforecast.forecastday[2].low.celsius fcst2avewind =jsonTable.forecast.simpleforecast.forecastday[2].avewind.kph fcst2avewinddir =jsonTable.forecast.simpleforecast.forecastday[2].avewind.dir fcst2mm = WU.cleanJson(jsonTable.forecast.simpleforecast.forecastday[1].qpf_night.mm,"0") fcstday3 = jsonTable.forecast.txt_forecast.forecastday[3].title -- Tomorrow fcst3 = jsonTable.forecast.txt_forecast.forecastday[3].fcttext_metric fcst3icon = jsonTable.forecast.txt_forecast.forecastday[1].icon_url fcst3SmallTxt = jsonTable.forecast.simpleforecast.forecastday[1].conditions fcst3Tmax = jsonTable.forecast.simpleforecast.forecastday[1].high.celsius fcst3Tmin = jsonTable.forecast.simpleforecast.forecastday[1].low.celsius fcst3avewind =jsonTable.forecast.simpleforecast.forecastday[1].avewind.kph fcst3avewinddir =jsonTable.forecast.simpleforecast.forecastday[1].avewind.dir fcst3mm = WU.cleanJson(jsonTable.forecast.simpleforecast.forecastday[2].qpf_allday.mm,"0") fcstday5 = jsonTable.forecast.txt_forecast.forecastday[5].title -- In 2 days fcst5 = jsonTable.forecast.txt_forecast.forecastday[5].fcttext_metric fcst5icon = jsonTable.forecast.txt_forecast.forecastday[1].icon_url fcst5SmallTxt = jsonTable.forecast.simpleforecast.forecastday[1].conditions fcst5Tmax = jsonTable.forecast.simpleforecast.forecastday[1].high.celsius fcst5Tmin = jsonTable.forecast.simpleforecast.forecastday[1].low.celsius fcst5avewind =jsonTable.forecast.simpleforecast.forecastday[1].avewind.kph fcst5avewinddir =jsonTable.forecast.simpleforecast.forecastday[1].avewind.dir fcst5mm = WU.cleanJson(jsonTable.forecast.simpleforecast.forecastday[3].qpf_allday.mm,"0") if (stationID ~= nil) and decode_error == false then fibaro:call(WU.selfId , "setProperty", "ui.lblStation.value", locationID); if temperature < 5 then cTemperature = WU.HtmlColor(temperature,"blue") elseif temperature > 18 then cTemperature = WU.HtmlColor(temperature,"red") else cTemperature = WU.HtmlColor(temperature,"yellow") end fibaro:call(WU.selfId , "setProperty", "ui.lblTempHum.value", WU.translation[WU.language]["Temperature"]..": "..cTemperature.." °C - "..WU.translation[WU.language]["Humidity"]..": "..humidity); fibaro:call(WU.selfId , "setProperty", "ui.lblWindRain.value", WU.translation[WU.language]["Wind"]..": "..wind.." km/h - "..WU.translation[WU.language]["Rain"]..": "..rain.." mm"); if (WU.now >= "00:00" and WU.now <= "15:59") then -- donne meteo du jour entre 00:00 (ou 3h) et 15:59. permet de garder la météo du soir jusqu'a 3h du matin, sinon change à minuit fibaro:call(WU.selfId , "setProperty", "ui.lblFcst.value", WU.translation[WU.language]["Forecast"].." "..WU.HtmlColor(fcstday1,"yellow")..": "..WU.HtmlColor(fcst1.." ("..fcst1mm.." mm)","green")); fibaro:setGlobal("Meteo_Day", WU.substPercent(WU.translation[WU.language]["Forecast"].." "..fcstday1..": ".." "..fcst1.." ("..fcst1mm.." mm)") ); fibaro:call(WU.selfId , "setProperty", "ui.lblIcon.value",WU.IconOrText(fcst1icon,fcst1SmallTxt)); elseif (WU.now >= "16:00" and WU.now <= "23:59") then -- donne meteo soirée entre 16:00 et 23:59 fibaro:call(WU.selfId , "setProperty", "ui.lblFcst.value", WU.translation[WU.language]["Forecast"].." "..WU.HtmlColor(fcstday2,"yellow")..": "..WU.HtmlColor(fcst2.." ("..fcst2mm.." mm)","green")); fibaro:setGlobal("Meteo_Day", WU.substPercent(WU.translation[WU.language]["Forecast"].." "..fcstday2..": ".." "..fcst2.." ("..fcst2mm.." mm)") ); fibaro:call(WU.selfId , "setProperty", "ui.lblIcon.value",WU.IconOrText(fcst2icon,fcst2SmallTxt)); end -- Meteo of Tomorrow fibaro:call(WU.selfId , "setProperty", "ui.lblFcstTomorrow.value", WU.translation[WU.language]["Forecast"].." "..WU.HtmlColor(fcstday3,"yellow")..": "..WU.HtmlColor(fcst3.." ("..fcst3mm.." mm)","green")); fibaro:setGlobal("Meteo_Tomorrow", WU.substPercent(WU.translation[WU.language]["Forecast"].." "..fcstday3..": ".." "..fcst3.." ("..fcst3mm.." mm)") ); fibaro:call(WU.selfId , "setProperty", "ui.lblIconTomorrow.value",WU.IconOrText(fcst3icon,fcst3SmallTxt)); -- Meteo in 2 Days fibaro:call(WU.selfId , "setProperty", "ui.lblFcst2Days.value", WU.translation[WU.language]["Forecast"].." "..WU.HtmlColor(fcstday5,"yellow")..": "..WU.HtmlColor(fcst5.." ("..fcst5mm.." mm)","green")); fibaro:setGlobal("Meteo_In_2_Days", WU.substPercent(WU.translation[WU.language]["Forecast"].." "..fcstday5..": ".." "..fcst5.." ("..fcst5mm.." mm)") ); fibaro:call(WU.selfId , "setProperty", "ui.lblIcon2Days.value",WU.IconOrText(fcst5icon,fcst5SmallTxt)); if WU.sendPush then if (os.date("%H:%M") == WU.push_fcst1) then -- fibaro:call(WU.smartphoneID , "sendPush", fcstday1.." - "..fcst1) -- envoie meteo du matin elseif (os.date("%H:%M") == WU.push_fcst2) then fibaro:call(WU.smartphoneID , "sendPush", fcstday2.." - "..fcst2) -- envoie meteo du soir end end if WU.sendPush then fibaro:call(WU.selfId , "setProperty", "ui.lblNotify.value", WU.translation[WU.language]["Push_forecast"].." = true"); else fibaro:call(WU.selfId , "setProperty", "ui.lblNotify.value",WU.translation[WU.language]["Push_forecast"].." = false"); end WU.scheduler = os.time()+updateEvery*60 fibaro:call(WU.selfId, "setProperty", "ui.lblUpdate.value", WU.translation[WU.language]["Last_updated"]..": "..os.date("%c")); Debug( "cyan", WU.translation[WU.language]["Data_processed"]) Debug( "white", WU.translation[WU.language]["Update_interval"].." "..updateEvery) else Debug( "red", WU.translation[WU.language]["NO_STATIONID_FOUND"]) end else fibaro:debug("status:" .. status .. ", errorCode:" .. errorCode); end end sleepAndcheckslider = 0 while sleepAndcheckslider <= 20*updateEvery do fibaro:sleep(3000) WU.checkMobileOrWeb() sleepAndcheckslider = sleepAndcheckslider+1 if (DoNotRecheckBefore <= os.time()) and ((WU.scheduler == os.time) or (os.date("%H:%M") == WU.push_fcst1) or (os.date("%H:%M") == WU.push_fcst2)) then Debug("orange", WU.translation[WU.language]["Exiting_loop_push"]); DoNotRecheckBefore = os.time()+60 sleepAndcheckslider = 20*updateEvery end end end Debug( "orange", "WU Weather - Original LUA Scripting by Jonny Larsson 2015"); Debug( "orange", "YAMS WU - Fork by Sébastien Jauquet 11/2015"); Debug( "orange", "Version: "..WU.version); if WU.station == "LOCID" then locationID = WU.LOCID elseif WU.station == "PWS" then locationID = WU.PWS end if WU.CreateVG then WU.createGlobalIfNotExists("Meteo_Day", "") WU.createGlobalIfNotExists("Meteo_Tomorrow", "") WU.createGlobalIfNotExists("Meteo_In_2_Days", "") end while true do WU.fetchWU() end
  10. Compatible uniquement 4.x (pour la 3.60 ... c'est ICI ... merci DMK2424) L'idée est de générer automatiquement le tableau d'ID utilisé dans GEA ou autres scripts. Ainsi, il sera possibile à chaque mise à jour de votre HC2, de simplement relancer le générateur, copier le résultat dans GEA et vos ID seront donc remis à jour. Voici le tableau dont je parle : local id = { --inconnu LUA_SNIPPETS = 141, --Garage OREGON = 128, SURPRESSEUR = 118, CAMERA = 123, PORTE_GARAGE = 238, DETECTEUR_PORTE = 112, PORTE_GARAGE_GARAGE = 64, --Jardin TEMPERATURE = 69, SEISMOMETRE = 71, HUMIDITE = 261, DETECTEUR = 68, NETATMO = 137, PLUVIOMETRE = 262, LUMINOSITE = 70, LAMPE_OUEST = 234, PLUIE = 139, COIN_REPAS = 14, PRESSION_ATMOSPHERIQ = 258, TERRASSE = 160, METEOALERTE = 150, ARROSAGE = 158, NETATMO_EXTERIEUR = 260, --Local Technique LIVEBOX = 251, IPX800_RELAIS = 106, PORTE_LOCAL = 56, VMC_DOUBLE_FLUX = 114, LAVE_LINGE = 120, PLAFONNIER = 54, PASSERELLE_NETATMO = 135, PASSERELLE_ZIBASE = 126, --Entrée CAMERA_ENTREE = 129, DETECTEUR_ENTREE = 5, LUMINOSITE_ENTREE = 7, SEISMOMETRE_ENTREE = 8, PLAFONNIER_ENTREE = 10, PORTE_ENTREE = 58, TEMPERATURE_ENTREE = 6, --Cuisine SIRENE = 200, BRITA__FILTRE_ = 131, CUISINE = 237, CAPTEUR_FUMEE = 46, ALARME_FUMEE = 48, FRIGO = 52, TEMPERATURE_CUISINE = 47, LAVE_VAISSELLE = 50, TABLETTE = 176, --Chambre parentale SECHE_SERVIETTE = 60, --Salon CHAUFFAGE = 104, HUMIDITE_SALON = 257, CO2 = 256, NETATMO_SALON = 255, SONOMETRE = 259, POELE = 34, OREGON_SALON = 127, TV = 39, HIFI = 42, BLUE_RAY = 41, OPENKAROTZ = 133, ROMBA = 43, LUMIERE_SALON = 107, PRISE_LIBRE = 44, BRISE_SOLEIL = 105, WI = 40, KAROTZ = 134, NETATMO_SALON_SALON = 136, --Chambres PLAFONNIER_KENDRA = 23, PLAFONNIER_NORA = 18, TEMPERATURE_CHAMBRES = 147, FENETRE_NORA = 143, FENETRE_KENDRA = 145, OREGON_CHAMBRES = 138, FENETRE_NOLAN = 149, PLAFONNIER_NOLAN = 21, --Couloir PORTE_TERRASSE = 153, APLIQUE_ESCALIER = 25, TEMPERATURE_AU_SOL = 155, SPOTS = 230, LEDS_ESCALIER = 27, --Divers ANDROID_FILES = 162, IMPERIHOME = 208, TYPE_DE_JOURNEE = 110, EVENEMENTS = 173, NETATMO_DIVERS = 253, CLOCK_SYNC = 252, UPDATE_NOTIFIER_1_0_6 = 206, AGENDA = 178, MY_BATTERIES = 130, VACANCES_SCOLAIRES = 151, } Ce générateur ce base sur les noms des modules et des pièces que vous avez déclarer. Il va donc parcourir tous vos modules, prendre leur nom et le transformer (majuscule, suppression caractères spéciaux, ...). Si le nom existe deux fois, il va le suffixer du nom de la pièces (ex : DETECTEUR_GARAGE). Donc, si comme moi, vous ne changer pas régulièrement le nom de vos modules, ce générateur va vous permettre de gagner quelques précieuses minutes. Usage ... simple, copier le code ci-dessous et lancer le script avec le bouton "start". Une fois le script terminé, il va vous affiché le tableau dans la fenêtre de debug, il ne vous suffira plus que de le copier dans vos scripts. Il est possible de spécifier les ID ou type de module que vous ne voulez pas prendre en compte. Vous pouvez aussi préciser si vous souhaiter prendre en compte les modules caché ou mort. Voici donc le script dans sa globalité : --[[ %% properties %% globals --]] local hidden = false --- true pour exporter les devices cachés local dead = false -- true pour exporter les devices morts local excludeType = {"com.fibaro.zwaveDevice", "weather", "HC_user", "iOS_device", "com.fibaro.voipUser"} local excludeID = {} local devicesJSon = api.get("/devices") local devices = {} local names = {} local rooms = {} function addName(name, roomname) if (type(names[name]) == "nil") then names[name] = true return name else return addName(name.."_"..roomname, roomname) end end function getRooms() local roomsJSon = api.get("/rooms") rooms[0] = "inconnu" for k, v in ipairs(roomsJSon) do rooms[v.id] = v.name end end function rename(name, roomname) local name = name:upper():gsub("[éêèà«]", "E"):gsub("EE", "E"):gsub("[à»à¼ù]", "U"):gsub("UU", "U"):gsub("[à âà¤]", "A"):gsub("AA", "A"):gsub("[à¶ô]", "O"):gsub("OO", "O"):gsub("[îà¯]", "I"):gsub("II", "I"):gsub("%W", "_") local roomname = roomname:upper():gsub("[éêèà«]", "E"):gsub("EE", "E"):gsub("[à»à¼ù]", "U"):gsub("UU", "U"):gsub("[à âà¤]", "A"):gsub("AA", "A"):gsub("[à¶ô]", "O"):gsub("OO", "O"):gsub("[îà¯]", "I"):gsub("II", "I"):gsub("%W", "_") return addName(name, roomname) end getRooms() for k, v in pairs(devicesJSon) do local doit = (hidden or v.visible) and (dead or not v.dead) if (doit) then for h, w in pairs(excludeType) do if (v.type == w) then doit = false end end if (doit) then for h, w in pairs(excludeID) do if (v.id == w) then doit = false end end end end if (doit) then table.insert(devices, v) end end table.sort(devices, function(a, return a.roomID<b.roomID end) local result = "<BR><BR>-- IDs générés le : " .. os.date("%d/%m/%y à %X") local room = -1 local lastinfo = ""; result = result .. "<BR><BR>local id = {" for k, v in ipairs(devices) do if (room ~= v.roomID) then room = v.roomID result = result .. "<BR>--"..rooms[v.roomID].."<BR>" end lastinfo = rename(v.name, rooms[v.roomID]) result = result .. lastinfo .. " = " .. v.id .. ", " end result = result .. "<BR>}" result = result .. "<BR>" result = result .. "<BR>-- usage :" result = result .. "<BR>-- fibaro:getValue(id[\""..lastinfo .."\"], \"value\")" result = result .. "<BR>-- GEA.add(id[\""..lastinfo .."\"], 30, \"\")" print(result) Il ne vous restera plus qu'à utiliser les ID ainsi fibaro:getValue(id["DETECTEUR_GARAGE"], "value") GEA.add(id["DETECTEUR_GARAGE"], -1, "La porte du garage est entrain de s'ouvrir") ATTENTION : Les déclencheurs doivent et devront toujours être changé par vos soins ATTENTION 2 : Si vous ne comprenez pas l'usage de ce script, c'est sà»rement parce que vous n'en avez pas l'utilité Icone by @Did (Merci)
  11. Voici un script pour l'extension Greasemonkey de Firefox afin de faciliter le login sur l'interface Web de notre box préférée : Remplissage automatique du compte admin Focus sur le champs Mot de passe Il ne reste plus qu'à taper le mot de passe, et appuyer sur la touche Entrée. Dans le panneau des extensions de Firefox, rechercher et installer Greasemonkey : Sur la gauche, cliquer sur le nouvelle section Scripts utilisateur, puis sur Nouveau Script... : Rentrer les informations suivantes : Nom : Fibaro HC2 Espace de nom : http://www.domotique-fibaro.fr Description : Remplie automatiquement le champ login avec le compte admin et met le focus sur le champs password Inclus : http://*/fibaro/*/home/login.html* Dans la fenêtre de l'éditeur qui s'ouvre, copier/coller le code suivant : // ==UserScript== // @name Fibaro HC2 // @namespace http://www.domotique-fibaro.fr // @description Remplie automatiquement le champ login avec le compte admin et met le focus sur le champs password // @include http://*/fibaro/*/home/login.html* // @version 1.0 // @grant none // ==/UserScript== var inputlogin = document.querySelectorAll("input#login"); inputlogin[0].value = "admin"; var inputpassword = document.getElementById("pwd"); inputpassword.focus(); Enregistrer et fermer la fenêtre, le script apparait : Aller sur la fenêtre de connexion de la box, qui devrait ressembler à ceci : Il ne reste plus qu'à taper le mot de passe, et appuyer sur la touche Entrée. Théoriquement, ce script doit également fonctionner pour l'extension Tampermonkey de Chrome (testé par @crazymonster999). Pour ceux qui voudraient aller plus loin et automatiser complètement le login (et qui n'ont pas peut de laisser leur mot de passe en clair dans le script) voir le message de @crazymonster999 plus bas dans cette page.
  12. Dgille

    Météo avec WeatherBit.IO

    Bonjour à tous, voici une scène et un VD sans prétention pour accéder aux données météo de WeatherBit.io. Le paramétrage est simplissime, créer un compte sur le site et récupérer votre APIkey. En l'absence du code de la ville, la scène récupère les données de localisation de la HC2. Sinon, vous pouvez télécharger sur le site la liste des villes supportées et indiquer directement le code ville dans la variable WBCityid La scène est en manuel par défaut. Elle stocke bêtement la réponse json dans une VG. La langue de description de la météo est paramétrable (cf le site), mis en français par défaut. Deux solutions pour l'exploiter: - Vous la lancez via GEA et exploitez directement le JSON - Plus simple, vous installez le VD de ce post qui va lancer la scéne à une fréquence à définir (entre 2 et 45mn) et afficher les principales informations (vous pouvez compléter si nécessaire) pour exploitation par d'autres scènes/VD. Perso, je n'exploite que la température extérieure, mais tout est possible. Voici le code de la scène: --[[ %% properties %% events %% globals --]] -- DGILLE - V1 -- Quelques paramétres à fixer WBApikey = "xxxxxxxxxxxxxxx" -- API KEy Wetaher bit WBCityid ="" -- Code ville, sinon vide pour latitude longitude de la HC2 WBlang = "fr" -- un peu de code de Steven (Merci !!) VG={getValue=function(self,b)return fibaro:getGlobalValue(b)end,setValue=function(self,b,c)fibaro:setGlobal(b,c)end,getDateModification=function(self,b)return os.date("*t",fibaro:getGlobalModificationTime(b))end,supprimer=function(self,b)api.delete("/globalVariables/"..b)end,modifier=function(self,b,c,d)local e={}e.value=tostring(c)e.isEnum=false;if type(d)~="nil"then e.isEnum=true;e.enumValues=d end;api.put("/globalVariables/"..b,e)end,ajouter=function(self,b,c,d)local f=0;if type(d)~="nil"then f=1 end;api.post("/globalVariables",{name=b,isEnum=f})self:modifier(b,c,d)end,traiter=function(self,b,c,d)if fibaro:getGlobalValue(b)==nil then self:ajouter(b,c,d)elseif type(d)=="nil"then self:setValue(b,c)else self:modifier(b,c,d)end end,getInfo=function(self,b)return api.get("/globalVariables/"..b)end} function getResponseData(url, method, body, func) local http = net.HTTPClient() http:request(url, { options = { method = method, headers = { ["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/64.0", ["Content-Type"] = "application/json", }, data = body }, success = function(response) fibaro:debug(" Analyse de la réponse du site..") if (response.status==200) then VG:setValue("weatherbit",response.data) else fibaro:debug ("Erreur de récupération des données :"..response.status) fibaro:abort() end end, error = function(err) fibaro:debug("Erreur.."..response.status) fibaro:abort() end, }) end -- au boulot local url fibaro:debug ("Lancement de la scéne") VG:traiter("weatherbit", "") -- construction de l'URL if (WBCityid=="" )then fibaro:debug ("Pas de code ville - Utilisation de la localisation de la HC2") local loc=api.get("/settings/location") url = "https://api.weatherbit.io/v2.0/current?lat="..loc.latitude.."&lon="..loc.longitude.."&lang="..WBlang.."&key="..WBApikey else fibaro:debug ("Utilisation du code ville fourni.") url = "https://api.weatherbit.io/v2.0/current?city_id="..WBCityid.."&lang="..WBlang.."&key="..WBApikey end fibaro:debug ("appel de l'URL :"..url) getResponseData(url, "GET", nil) Pour paramétrer la VD, il suffit de lui indiquer dans la main loop l'ID de la scène créée précédemment. Voila, tout cela à été codé en 2h suite au mauvais fonctionnement des plugins YR Weather et Yahoo et fonctionne sans problème depuis plusieurs jours. Enjoy. WeatherBit.vfib
  13. ATTENTION Ce VD peux corrompre la DB de votre HC2, à n'utiliser qu'en connaissance de cause. Je ne puis être tenu pour responsable en cas de problème. Faire un backup de la DB avant de commencer à l'utiliser. Si vous cachez un device , notez bien son numéro, car il ne sera plus visible, et donc "impossible" à reconfigurer, ... (en tout cas si vous cachez le Main device et ses child devices) Merci : Merci à Steven pour son code "Double click pour confirmer" Merci à notre graphiste national (Couillerot) pour ses icônes Objectif : Ce VD permet de modifier une propriété d'un device. Je l'ai déjà utilisé dans les situations suivantes : dead : marquer manuellement un device sur pile comme mort, quand il n'a plus de pile ... disabled : afficher un "sous-device" qui était caché par erreur / cacher des child devices inutilisés (exple dans les binary sensors). "offset" : modifier l'offset d'une sonde de température (plutôt que d'utiliser le slider) Utilisation : avec l'URL suivante "<IP>/api/devices/" (suivi du # du device) vous pouvez voir dans votre browser les propriétés et leur nom précis (dépend du type de device) {"id":649,"name":"Tmp_Tisun","roomID":12,"type":"com.fibaro.temperatureSensor","baseType":"com.fibaro.multilevelSensor","enabled":true,"visible":true,"isPlugin":false,"parentId":634,"remoteGatewayId":0,"interfaces":["zwave"],"properties":{"parameters":[{"id":1,"lastReportedValue":0,"lastSetValue":0,"size":2,"value":0},{"id":2,"lastReportedValue":0,"lastSetValue":0,"size":2,"value":0},{"id":3,"lastReportedValue":1,"lastSetValue":1,"size":1,"value":1},{"id":4,"lastReportedValue":1,"lastSetValue":1,"size":1,"value":1},{"id":5,"lastReportedValue":255,"lastSetValue":255,"size":1,"value":255},{"id":6,"lastReportedValue":255,"lastSetValue":255,"size":1,"value":255},{"id":7,"lastReportedValue":255,"lastSetValue":255,"size":1,"value":255},{"id":8,"lastReportedValue":255,"lastSetValue":255,"size":1,"value":255},{"id":9,"lastReportedValue":0,"lastSetValue":0,"size":1,"value":0},{"id":10,"lastReportedValue":1,"lastSetValue":1,"size":1,"value":1},{"id":11,"lastReportedValue":200,"lastSetValue":200,"size":1,"value":200},{"id":12,"lastReportedValue":0,"lastSetValue":0,"size":1,"value":0},{"id":13,"lastReportedValue":0,"lastSetValue":0,"size":1,"value":0},{"id":14,"lastReportedValue":0,"lastSetValue":0,"size":1,"value":0}],"zwaveCompany":"Fibargroup","zwaveInfo":"3,3,52","zwaveVersion":"2.1","pollingTimeSec":0,"configured":"true","dead":"false","deviceControlType":"0","deviceIcon":"30","emailNotificationID":"0","emailNotificationType":"0","endPointId":"3","liliOffCommand":"","liliOnCommand":"","log":"","logTemp":"","manufacturer":"","markAsDead":"true","model":"","nodeId":"79","offset":"10.00","parametersTemplate":"85","productInfo":"1,15,5,1,16,2,2,1","pushNotificationID":"0","pushNotificationType":"0","remoteGatewayId":"0","saveLogs":"false","showFireAlarm":"false","showFreezeAlarm":"false","smsNotificationID":"0","smsNotificationType":"0","unit":"C","useTemplate":"true","userDescription":"","value":"70.87"},"actions":{"reconfigure":0},"created":1444553629,"modified":1444553629,"sortOrder":113} les propriétés concernées se trouvent dans : "properties":{...} {"parameters":[{"id":1,"lastReportedValue":0,"lastSetValue":0,"size":2,"value":0},{"id":2,"lastReportedValue":0,"lastSetValue":0,"size":2,"value":0},{"id":3,"lastReportedValue":1,"lastSetValue":1,"size":1,"value":1},{"id":4,"lastReportedValue":1,"lastSetValue":1,"size":1,"value":1},{"id":5,"lastReportedValue":255,"lastSetValue":255,"size":1,"value":255},{"id":6,"lastReportedValue":255,"lastSetValue":255,"size":1,"value":255},{"id":7,"lastReportedValue":255,"lastSetValue":255,"size":1,"value":255},{"id":8,"lastReportedValue":255,"lastSetValue":255,"size":1,"value":255},{"id":9,"lastReportedValue":0,"lastSetValue":0,"size":1,"value":0},{"id":10,"lastReportedValue":1,"lastSetValue":1,"size":1,"value":1},{"id":11,"lastReportedValue":200,"lastSetValue":200,"size":1,"value":200},{"id":12,"lastReportedValue":0,"lastSetValue":0,"size":1,"value":0},{"id":13,"lastReportedValue":0,"lastSetValue":0,"size":1,"value":0},{"id":14,"lastReportedValue":0,"lastSetValue":0,"size":1,"value":0}],"zwaveCompany":"Fibargroup","zwaveInfo":"3,3,52","zwaveVersion":"2.1","pollingTimeSec":0,"configured":"true","dead":"false","deviceControlType":"0","deviceIcon":"30","emailNotificationID":"0","emailNotificationType":"0","endPointId":"3","liliOffCommand":"","liliOnCommand":"","log":"","logTemp":"","manufacturer":"","markAsDead":"true","model":"","nodeId":"79","offset":"10.00","parametersTemplate":"85","productInfo":"1,15,5,1,16,2,2,1","pushNotificationID":"0","pushNotificationType":"0","remoteGatewayId":"0","saveLogs":"false","showFireAlarm":"false","showFreezeAlarm":"false","smsNotificationID":"0","smsNotificationType":"0","unit":"C","useTemplate":"true","userDescription":"","value":"70.87"}ensuite adapter suivant vos désirs les lignes 4, 10 et 11 du VD local Property = "offset" -- vleurs possibles : cfr json local NewPropValue = "0.00" -- la valsur doit être entre " local deviceID = 649 Lorsque vous appuyez une première fois sur le bouton "Update device property", il vous affiche le device, la propriété à modifier, sa valeur actuelle, et la future valeur Appuyez une deuxième fois sur le bouton (dans les 5 sec) pour effectuer la modification Si le nom de la propriété introduit en ligne 4 n'existe pas, il affiche un message d'erreur. Cette v2 est compatible avec le firmware v4.x DeviceProperties_v2.0.vfib DeviceProperties_v1.0.vfib DeviceProperties._v2.0.vfib
  14. Ce module permet de piloter l'arrêt, la petite et la grande vitesse à l'aide d'un FGS-221. La VMC n'est pas prévue pour être à l'arrêt initialement mais je trouve ridicule de la faire tourner les jours rouges (je suis en Tempo) qui sont généralement les plus froids. Une conso électrique pour en plus mettre de la chaleur dehors, plus jamais même si les radiateurs à chaleur douce sont en appoint d'un insert. La salle de bain à l'étage est en pignon et assez éloignée de la trémie de l'escalier donc pas réellement chauffée par l'insert. . Voici le schéma sur lequel je suis partit. Ayant un doute sur la possibilité de ma VMC à lui raccorder la grande vitesse en même temps que la petite, j'ai préféré ajouter un relais inverseur pour suivre le même câblage que le va-et-vient d'origine. L'astuce est de faire le pont entre la phase et O1 (marche-arrêt) puis d'alimenter le contact inverseur du relais en In et enfin sortir de O2 pour alimenter la bobine du relais (PV-GV). J'ai choisi des poussoirs à voyant Mosaïc pour les commandes et pour l'état un voyant vert pour la marche en petite vitesse et un voyant rouge sur le second poussoir pour la grande vitesse. Il me manquait des fils entre la VMC et une boîte à l'étage (au dessus du plan de travail). Je vous précise cela car ça ne voulait pas passer et j'ai été obligé de débrancher les fils existants dans la gaîne (circuit PC + circuit 20A + alim. d'un éclairage + 3 fils VMC), d'y accrocher une aiguille et ressortir les 7 mètres pour y ajouter mon neutre + d'autres en réserve pour ensuite les repasser tous ensemble (c'était chaud mais pas impossible). Pour les commandes des boutons, rien de compliqué La main loop pour le retour des 3 états. Un grand MERCI à Steven qui, une fois de plus à répondu présent pour me dépatouiller de Lua. --[[ %% properties %% globals --]] local id_vmc_lent = 236 local id_vmc_rapide = 238 local id_module_virtuel = fibaro:getSelfId() local lentAllumer = tonumber(fibaro:getValue(id_vmc_lent, "value")) == 1 local rapideAllumer = tonumber(fibaro:getValue(id_vmc_rapide, "value")) == 1 local icon = fibaro:getValue(id_module_virtuel, "currentIcon") if (lentAllumer and rapideAllumer) then -- icone rapide icon = 1097 elseif (lentAllumer) then -- icone lent icon = 1096 else -- icone éteint icon = 1091 end fibaro:call(235, "setProperty", "currentIcon", icon) Et enfin, les icônes au cas où vous ne les auriez pas déjà trouver dans le topic de Steh (Banque Icônes Hc2 & Hcl). Bien sûr, je n'ai pas fait ce module juste pour pouvoir m'amuser avec la VMC de la tablette mais je compte bien la faire taire complètement les jours rouges et peut-être aussi lui faire forcer la grande vitesse quand le taux d'humidité dans la gaîne de la salle de bain sera trop élevé mais encore faudrait-il trouver une sonde adéquate.
  15. jojo

    My Batteries

    @flamalex a fait une modification au code car problèmes à partir du firmware v'.140ou v 4.145. Il l'a baptisée v2, mas comme on était déjà à v5.4, je l'ai rebaptisé v6.0. My_Batteries_v6.2.vfib My_Batteries_v6.1.vfib My_Batteries_v6.0.vfib --------------------------------------------------------------------------------------------------------------- My Batteries Ce virtual device permet de visualiser le niveau des batteries de l'ensembles de vos appareils sur batterie (max 10). Il est TRES largement inspiré du travail initial de Steven http://www.domotique-fibaro.fr/index.php/topic/1710-my-batteries/ Merci également à Moicphil qui m'a énormément aidé pour debugger la partie v4.x Les modifications que j'y ai apportées : modification de l'affichage, avec moment du dernier check automatique incorporation des supers icônes de @couillerot firmware 4.x push si batterie sous un certain niveau Voici la dernière version du VD : My_Batteries_v5.4.vfib Et les codes : MyBatteries.Batteries.lua MyBatteries.MainLoop.lua
  16. razowski

    Module Virtuel "hc2 - Diagnostics"

    Hello, Voici un petit module virtuel qui va interroger la HC2 et qui permet quand on est pas à la maison, de garder un oeil sur la mémoire utilisée par notre HC2, la charge CPU et l'espace disponible pour le système respectivement le recovery. Voici mon icône, si cela peut vous intéresser...: Voici le module virtuel : HC2_Diagnostics.vfib Pour que ça marche, importer le Virtual Device et c'est prêt. Bonne découverte. @+ Razowski
  17. Bonjour Pour mon premier tuto, je vous propose un Module Virtuel pour interfacer la Livebox d'Orange et je vais vous détailler la mise en Å“uvre de l'intégration avec la HC2. Le module rassemble les informations importantes sur l'état des interfaces, le débit, les statistiques et les différents compteurs d'erreurs. Il permet aussi d'exécuter des commandes simples comme l'activation du Wifi ou le redémarrage de la Livebox. Prérequis Une Livebox 2 (Sagem) DSL note: pas pu tester la fibre. J'aimerais bien mais dans moin coin c'est pas avant 2022 ). Une HC2 (code lua testé avec v3.600 et v4.031) Installation Télécharger et ajouter le VD (lien en bas de post) Sur la page de configuration du module, saisir l'adresse ip et le port (80) de la Livebox Ensuite, il faut paramtètrer le VD, editez le code en debut de page (pour chaque bouttons): -- Nom d'utilisateur et mot de passe de la livebox local USER ="admin" local PASSWORD = "admin" Le VD retourne trois états possibles: Inconnu, OK et Not OK. Editez les variables pour adapter l'ID des icones: -- ID des icônes icon_ok = 1004 icon_nok = 1005 icon_unknown = 1006 Par défault, l'execution du module toutes les 5 minutes est confié à la mainloop du VD qui simule un appui sur le bouton Rafraichir. Simple, mais pour plus de fléxibilité et surtout de plus stabilté je recommande d'utiliser l'excellent GEA avec la ligne ci-dessous (à adapter). Dans ce cas, noubliez pas de supprimer le code dans le mainloop du VD. -- Mise à jour état connexion Internet GEA.add(true , 5*60, "",{{"VirtualDevice", id["VD_LIVEBOX"], "1"},{"VirtualDevice", id["VD_LIVEBOX"], "7"},{"Repeat"}}) Le VD n'utilise pas de Variable Globale car je n'ai pas de scénario qui necessite un retour sur l'état de la connexion internet mais c'est juste une ligne de code à ajouter: fibaro:setGlobal('test', Livebox.WANStatus.LinkState) Comment ca marche ? c'est la section pour les geeks. Je partage ici le resultat de mes bidouilles (et saut d'humeur) à propos de l'API Livebox Fonctionnement de l'API Orange/Sagem: En regardant d'un peu plus près les paquets échangés dans une session d'admin avec la livebox on peut voir des réponses de POST en json . à‡a commence plutôt pas mal, la livebox a donc une API ! Comme souvent avec Orange, ça commence bien, c'est après que les choses se gâtent ! Impossible de mettre la main sur une doc publique de l'API. En fouillant un peu sur les forums d'Orange j'ai trouvé quelques pistes mais mes vrais amis ont été Wireshark et les dev tools InternetExplorer ou Chrome (F12) pour comprendre un peu comment l'appli mobile d'Orange (version IOS) utilisait l'API… En inspectant le déroulé d'un login, je manque de m'étrangler en constatant que le nom d'utilisateur et le mot de passe sont balancés en clair; ben voyons les gars faut pas se gêner hein… la requête login retourne un "ContextID" qui est utilisé comme identifiant pour les appels aux fonctions de l'API (X-Context dans les headers). Donc au menu nous avons des custom headers et une authentification super basique, fastoche! où est le problème? Bah ça marche pô! - > "permission denied" le voilà le problème Bah surement qu'ils ont été pris de remords chez Orange avec cette authentification de mickey avec password en clair et histoire de faire bonne figure (et pas se faire défoncer tous les mercredi par des pré-ados qui voudraient passer outre le contrôle parental) ils ont semble-t-il cherché à compliquer un peu les choses… mais en faisant du gros n'importe quoi! Pour aller à l'enssentiel, en plus d'un ContextID, le Login renvoie une autre clé mais planquée dans un cookie cette fois. La sécurité n'y a pas gagné grand chose mais en revanche c'est une vraie prise de tête à intégrer sur la hc2. Hmm.. Net.FHttp avec des custom headers et un cookie, ça va pas le faire… Pour contourner le problème et récupérer le cookie, je me suis servi du génialissime ToolKit v1.0.4 de Krikroff. Une toute petite modif de 4 lignes dans httpClient:request et nous voila prêts à nous goinfrer de cookies. J'ai modifié (à l'arrache, sorry Krikroff) la fonction request(...) dans le fichier Toolkit.net.lua (commence ligne 165). on cherche la chaine "cookie" dans les response headers renvoyés par le serveur et le cas échéant on extrait avec un string.sub() en partant du douzième char. la fonction retourne le cookie en plus des classiques response, status et err. request = (function(self, method, uri, headers, body) ... for k, v in pairs(__headers) do --Toolkit.Net.__trace("raw #"..k..":"..v) if (string.find(string.lower( v or ""), "chunked")) then self.__isChunked = true; Toolkit.Net.__trace("%s.%s::receive > Transfer-Encoding: chunked", Toolkit.Net.__header, Toolkit.Net.__Http.__header, string.len(result)); -- Modification pour récupérer le cookie. Ofwood Janvier 2015 elseif (string.find(string.lower( v or ""), "cookie")) then cookie = string.sub(v, 12) Toolkit.Net.__trace("%s.%s::receive > Cookie: %s", Toolkit.Net.__header, Toolkit.Net.__Http.__header, cookie); end end ... -- return budy response & cookie return response, status, err, cookie; Voyons maintenant avec un exemple comment tirer profit de cette modification et mangeons des cookies! La fonction login() authentifie l'utilisateur et retourne le contextID (dans la réponse json) et le cookie associé. function login() local httpClient = Toolkit.Net.HttpRequest(ip, port) httpClient:setReadTimeout(Livebox.commandTimeOut) local uri = string.format("/authenticate?username=%s&password=%s", utilisateur, mot_de_passe) local response, status, errorCode, cookie = httpClient:request("POST", uri, {"User-Agent: FibaroHC2/1.0", "Content-Type: application/json"}, "" ) if (errorCode == 0) and tonumber(status) == 200 then local jsonTable = json.decode(response); ContextID = jsonTable.data.contextID; return ContextID, cookie end end l'exemple suivant utilise le contextID et notre cookie pour une requête (l'état de l'interface WAN sur la LiveBox) function getWANStatus(contextID, cookie) local httpClient = Toolkit.Net.HttpRequest(ip, port) httpClient:setReadTimeout(Livebox.commandTimeOut) local uri = "/sysbus/NMC:getWANStatus" local params = [[ {"parameters":{}} ]]; -- Injection de X-Context et du Cookie dans les headers local response, status, errorCode, cookie = httpClient:request("POST", uri, {"User-Agent: FibaroHC2/1.0", "Content-Type: application/json", "X-Context: "..contextID, "Cookie: "..cookie }, params); if (errorCode == 0) and (status == 200) then local jsonTable = json.decode(response) Return jsonTable.result.data end end Voici la liste des fonctions implémentées dans la version 1.0 du module. Il en existe d'autres, je n'ai pas encore tout recensé. Livebox.login() Authentification session utilisateur Livebox.logout() Fermeture session Livebox.listTrunks() Information téléphonie IP Livebox.getIPTVStatus() Etat IP TV Livebox.getDSLStats() Stats DSL (Erreurs) Livebox.getMIBs() Information lien dsl Livebox.getWifiMIBs() Information Wifi Livebox.getWANStatus() Etat de la connexion WAN Livebox.reboot() Redémarrage la livebox Livebox.setwifi(mode) Active/désactive le Wifi Livebox.filtreMAC(flag) Active/Désactive filtrage MAC address Livebox.getWificomStatus() Information Wifi public Orange Voilà , ça donne l'idée générale et Orange n'ayant pas le monopole sur les APIs bien pourries, je me suis dit que ça pourrait peut-être en aider d'autres qui se prennent la tête sur des intégrations nécessitant le support des cookies. Enjoy! merci pour vos retours (et votre indulgence) Historique 13/01/2015 - v1.0 : version initiale Livebox_VD.zip
  18. labomatik

    Plex - Films En Cours De Lecture

    Bonjour à tous, Ma petite contribution pour pouvoir récupérer les films en cours de lecture sur le serveur Plex. Il y a encore beaucoup d'amélioration possible mais il modifie déjà une variable globale (1 = film en cours, 0 = aucun film) et affiche le film en cours. Note: Aucune gestion de la lecture de plusieurs films en même temps. Il manque aussi l'information sur la source du lecteur plex (tv, iphone, ...), ce sera pour une prochaine version ;-) Importez le virtual device PlexHC2.vfib.zip PlexHC2 modifiez ces lignes: -- !!! VOS PARAMETRES !!! PlexHC2.Plex_ip = '192.168.1.9' -- IP du serveur Plex PlexHC2.Plex_port = 32400 -- PlexHC2.globalvariable = "" L'image du VD Note2: Largement inspiré du script de Steven MétéoAlerte (un grand merci à lui pour son travail)
  19. Bonjour, Sur le post du script pour le contrôle du niveau des piles j'ai abordé le sujet nÅ“uds morts pour les détecter et voici un script tip top qui/ - Contrôle les nÅ“uds morts, - Chercher a les réveiller, - Envoie des notifications pour avertir --[[ %% autostart %% properties %% globals --]] local sourceTrigger = fibaro:getSourceTrigger(); if (sourceTrigger["type"] == "autostart") then while true do local currentDate = os.date("*t"); local startSource = fibaro:getSourceTrigger(); if ( ( (tonumber(os.date("%H%M")) >= tonumber(string.format("%02d%02d", "07", "00")) and tonumber(os.date("%H%M")) <= tonumber(string.format("%02d%02d", "23", "00"))) and (math.floor(os.time()/60)-math.floor(1369026000/60))%2 == 0 ) ) then local i = 1 local TotalDevices = 156 + 1 while i < TotalDevices do local status = fibaro:getValue(i, 'dead'); if status == "1" then fibaro:setGlobal('lastDeadNode', i); -- fibaro:call(30, "pressButton", "6"); fibaro:call(1, "wakeUpDeadDevice",i); fibaro:debug("Try to wake up node "..i); fibaro:call(68, "sendPush", "Try to wake up node "..i); fibaro:sleep(5*1000); local status = fibaro:getValue(i, 'dead'); if status == "1" then fibaro:debug("Device "..i.." still dead"); fibaro:call(68, "sendPush", "Device "..i.." still dead"); -- fibaro:call(30, "pressButton", "6"); -- fibaro:call(65, "sendDefinedPushNotification", "9"); -- fibaro:call(2, "sendEmail", "DEAD "..i); else -- fibaro:call(30, "pressButton", "7"); fibaro:debug("Device "..i.." fixed"); fibaro:call(68, "sendPush", "Device "..i.." fixed"); end else end i = i + 1 end end fibaro:sleep(60*1000); end else local currentDate = os.date("*t"); local startSource = fibaro:getSourceTrigger(); if ( startSource["type"] == "other" ) then fibaro:debug("send notification"); fibaro:call(68, "sendPush", "start check dead node"); local i = 1 local TotalDevices = 156 + 1 while i < TotalDevices do local status = fibaro:getValue(i, 'dead'); if status == "1" then fibaro:setGlobal('lastDeadNode', i); -- fibaro:call(30, "pressButton", "6"); fibaro:call(1, "wakeUpDeadDevice",i); fibaro:debug("Try to wake up node "..i); fibaro:call(68, "sendPush", "Try to wake up node "..i); fibaro:sleep(5*1000); local status = fibaro:getValue(i, 'dead'); if status == "1" then fibaro:debug("Device "..i.." still dead"); fibaro:call(68, "sendPush", "Device "..i.." still dead"); -- fibaro:call(30, "pressButton", "6"); -- fibaro:call(65, "sendDefinedPushNotification", "9"); -- fibaro:call(2, "sendEmail", "DEAD "..i); else -- fibaro:call(30, "pressButton", "7"); fibaro:debug("Device "..i.." fixed"); fibaro:call(68, "sendPush", "Device "..i.." fixed"); end else end i = i + 1 end end end Voici le script,son auteur est Olivier MALE. Il faut l'adapter pour le N° d'ID pour le push. Son auteur a aussi mis des "--" devant certaines lignes de notifications push et de virtual device, perso j'ai supprimé ces lignes. Le script fonctionne nickel chez moi.
  20. Nikko

    Backup Via Scene Lua

    Bonjour, Voici un résumé sur la réalisation/suppression de backups via des scènes en Lua. La création/suppression de backup s'effectue en temps normal sur l'interface du HomeCenter à la page Diagnostiques/Sauvegarde et restauration. Le code donné dons les 2 scènes n'est pas des plus optimisé; cela constitue juste une base. EDIT (03/12/2016): Mise à jour avec l'api pour les versions >=4.101; voir plus loin: (https://www.domotique-fibaro.fr/topic/8641-backup-via-scene-lua/?do=findComment&comment=146362) Les Commandes de l'API La récupération au format JSON de la liste des backups se fait à l'addresse http://HC2/api/settings/backups Pour Créer un Backup on utilise l'addresse http://HC2/api/settings/backups avec une requète de type en POST avec les paramètres action et description. Pour Supprimer un Backup, on utilise l'addresse http://HC2/api/settings/backups?id=xx (où xx est le numéro de backup). La requète est de type DELETE avec comme paramètre id=xx => Comme les urls de l'api vont être appelées depuis des scènes lua, l'ip de la box utilisée sera 127.0.0.1 (port 11111) => En cas d'appel sur l'ip LAN de la box (Ex: http://192.168.0.100/api/settings/backups) , il faudra en plus transmettre l'authentification dans la requète. Attention: Lors de la création de Backup, "tout le reste" est suspendu; de même après que le backup soit effectué, le moteur Z-Wave et d'autres services redémarrent. Donc en cas de planification , privilégier la nuit, là ou l'activité ZWave, scénarios, est faible/inexistante. Scène de création d'un backup Exemple de Scène de création d'un Backup, avec notification vers portable: --[[ %% properties %% events %% globals --]] -- ID des mobiles,tablettes pour notification local portable = { 385,378 } -- Message Descriptif du Backup local descriptif = 'Backup du '..os.date("%d/%m/%y - %HH%M") function sendPush(message) if #portable > 0 then for _,v in ipairs(portable) do fibaro:call(v,'sendPush', message) end end end local url = 'http://127.0.0.1:11111/api/settings/backups' local httpClient = net.HTTPClient() httpClient:request(url , { success = function(response) if tonumber(response.status) == 201 then print("Backup Created at " .. os.date()) sendPush(descriptif .. ' effectué') else print("Error " .. response.status) sendPush('Erreur lors de la création du Backup') end end, error = function(err) print('error = ' .. err) end, options = { method = 'POST', headers = { ["content-type"] = 'application/x-www-form-urlencoded;' }, data = 'action=create&description='..descriptif } }); Depuis la page des backups, on peut vérifier que la scène fonctionne: Pour les utilisateurs de GEA, on peut déclencher cette sauvegarde le 1er samedi de chaque mois par exemple: -- Fonction déterminant si nous sommes le 1er samedi du mois function isFirstSaturday() local t = os.date('*t') return ( t['day'] < 8 and t['wday'] == 7 ) end -- Backup le 1er samedi du mois GEA.add({"Function",function() return isFirstSaturday() end} , 30 , "Backup Mensuel du HC2" , {{"Time","01:00","01:01"},{"Scenario", 12}}) . Scène de suppression d'un backup Exemple de Scene Lua pour réaliser la suppression du backup le plus ancien: --[[ %% properties %% events %% globals --]] -- Flag dryrun; Si true, la requete sur api pour effacer le backup n'est pas effectuée local dryrun = true -- Récupération de la list des backups local backups = api.get('/settings/backups') -- Vérification de présence Backup if (backups and type(backups == 'table') and #backups > 0) then if #backups > 1 then print(#backups .. ' Backups présents') else print('1 Backup présent') end for i in ipairs(backups) do fibaro:debug('ID: '..backups[i]['id']..' | TIMESTAMP: '..backups[i]['timestamp']..' | DESCRIPTION: '..backups[i]['description']) end else print('Pas de backup ou erreur lors de la récupération de la liste') fibaro:abort() end -- Pour chaque Backup on stock le timestamp de la date de réalisation dans une table -- On classe ensuite les timestamps par ordre croissant local timestamp = {} for i in ipairs(backups) do table.insert(timestamp, backups[i]['timestamp']) end table.sort(timestamp) -- Le 1er timestamp de la table est le plus petit donc le plus ancien en epochtime -- Dans la table de backup on recherche le backup ayant ce timestamp local id = false for i in ipairs(backups) do if (tonumber(backups[i]['timestamp']) == tonumber(timestamp[1])) then id = backups[i]['id'] end end if id then print("ID du backup le plus ancien: "..id) else print("Erreur lors de la récupération de l'ID") fibaro:abort() end -- Requete via API pour effacer le backup le plus ancien if not dryrun then local url = 'http://127.0.0.1:11111/api/settings/backups?id='..id local httpClient = net.HTTPClient() httpClient:request(url , { success = function(response) if tonumber(response.status) == 200 then print("Backup deleted at " .. os.date()) else print("Error " .. response.status) end end, error = function(err) print('error = ' .. err) end, options = { method = 'DELETE', headers = { ["content-type"] = 'application/x-www-form-urlencoded;' }, data = 'id='..id } }); end . Cette Scène produit le debug suivant: Nicolas
  21. Après avoir rencontré quelques difficultés avec la portée des variables, je vous propose un précis sur le sujet : Petit rappel : Une variable permet de stocker des valeurs de façon temporaire ou non dans des noms. On pourra en suite faire appel àces noms n'importe où dans notre code. Si cette gestion de l'information semble suffisante dans un petit script, il n'en va pas de même pour de longs codes (comme ceux dont nous gratifient Krikroff ou Steven) En effet, il serait catastrophique que des fonctions différentes utilisent le même nom de variable pour y stocker des valeurs !!! Les variables seraient alors écrasées ... Et ça c'est pas bon... La solution est de limiter la portée d'une variable en utilisant la notion de variable locale. Ainsi la variable locale n'aura d'existence que dans le bloc dans laquelle elle a été crée ! Mais qu'est-ce qu'un bloc ? Et bien c'est par exemple ce qui est situé entre if et end, ou entre do et end, ou encore une fonction ... Ben alors comment qu'on va faire maintenant ? Déjà, on a de la chance, puisque le Lua utilise ces 2 types de variables et que c'est super simple de les créer ! Les variables Globales sont crées simplement en tapant leur nom suivi d'un "=" et de la valeur numérique souhaitée ou du texte entre "" ou ' ' : MaVariableGlobale = 1 Attention : Fibaro propose en plus une gestion particulière des variables Globales par le biais de son Panneau variables. Il sera donc inutile de la déclarer ànouveau dans votre code pour l'utiliser. Cette gestion permet d'utiliser une même variable commune àtoutes les scènes ou modules de votre HC2. Les variables Locales sont quant àelles créées en ajoutant cette fois le mot local devant le nom de la variable (c'est ce mot clé qui restreint sa portée àun bloc ou àune fonction) : local MaVariableLocale = 2 Attention : Pour changer la valeur de cette variable locale il ne sera plus nécessaire de mettre le mot clé "local" devant ! Bon après ça dépend de ce que vous souhaitez faire... Mettre àjour la variable ou en créer une nouvelle (voir plus bas *) Mais c'est peut-être ce que vous voulez finalement ? Oui et non Il faudra être vigilant quant àla portée que l'on souhaite donnée àsa variable et choisir qu'elle soit locale ou globale. En effet, dans une fonction, il peut être intéressant d'utiliser une variable et d'être certain qu'il n'y aura pas de conflit avec un nom que vous auriez utilisé avant. C'est làque vous allez utiliser la puissance de la variable LOCALE ! Voici un exemple de la portée d'une variable locale (regardez la valeur retournée par le début). On voit clairement que nous avons àfaire à2 variables locales : local MaVarLocale = 1 fibaro:debug(MaVarLocale) -- donne 1 do local MaVarLocale = 5 -- création d'une nouvelle variable locale au sein du bloc (rien àvoir avec celle créée ligne 2 !) fibaro:debug(MaVarLocale) -- donne 5 end fibaro:debug(MaVarLocale) -- donne 1 Même si elles ont le même nom, elles ont été déclarées dans 2 blocs différents. Le système les considère comme complètement différentes àcause du mot clé local. Le danger avec le Lua c'est que ce langage est très permissif et qu'àforce d'omission, on peut se prendre les pieds sans le tapis ... Je m'explique en reprenant le même code qu'au dessus en supprimant le mot clé local : MaVariable = 1 -- création d'une variable globale fibaro:debug(MaVariable) -- donne 1 do MaVariable = 5 -- mise àjour de la variable globale créée ligne 2 fibaro:debug(MaVariable) -- donne 5 end fibaro:debug(MaVariable) -- donne 5 Ici nous n'avons àfaire qu'àune seule variable globale (elle s'appelle MaVariable ! Elle est considérée ici par le système comme globale car nous ne l'avons jamais déclarée avec le mot clé local. Ok ! Alors maintenant vous vous dites : je vais déclarer ma variable MaVariable en local dès la première ligne (comme ça je suis tranquille) : local MaVariable = 1 -- création d'une variable locale fibaro:debug(MaVariable) -- donne 1 do MaVariable = 5 -- ici pas de mot clé local, donc mise àjour de la variable déclarée ligne 2 fibaro:debug(MaVariable) -- donne 5 end fibaro:debug(MaVariable) -- donne 5 (C'est ici plus bas * !!!) Ici il n'y a pas d'erreur ! Ce code est valable si vous souhaitiez vraiment utiliser la même variable locale (dans un nouveau bloc) que celle déclarée en locale au début de votre script (et donc la mettre àjour). La Variable est mise àjour et non créer au sein du nouveau bloc. Le code suivant crée 4 variables locales MaVariable : local MaVariable = 0 -- création d'une variable locale do local MaVariable = 1 -- création d'une nouvelle variable locale (rien àvoir avec le ligne 2 end do local MaVariable = 2 -- création d'une nouvelle variable locale (rien àvoir avec le ligne 2 et 5 end do local MaVariable = 3 -- création d'une nouvelle variable locale (rien àvoir avec le ligne 2 ; 5 et 9) end Le code suivant crée 1 seule variable locale MaVariable et la met àjour 3 fois : local MaVariable = 0 -- création de la variable locale do MaVariable = 1 -- mise àjour de la variable déclarée ligne 2 end do MaVariable = 2 -- mise àjour de la variable déclarée ligne 2 et modifiée àla ligne 5 end do MaVariable = 3 -- mise àjour de la variable déclarée ligne 2, modifiée àla ligne 5 et modifiée ànouveau ligne 9 end Ce code utilise une seule variable Globale MaVariable car on a supprimé la 1ère ligne ! : -- On supprime la déclaration de la variable locale en la commentant : -- local MaVariable = 0 do MaVariable = 1 -- création de la variable globale ! end do MaVariable = 2 -- mise àjour de la variable globale ! end do MaVariable = 3 -- mise àjour de la variable globale ! end Subtile non ?! Une ligne en moins au début et on passe tout de local en globale ! Voilàpourquoi je disais que le côté permissif du Lua peut jouer des tours. Imaginez que vous vous trouviez àla tête de 1500 lignes de codes, il se pourrait que vous souhaitiez mettre àjour une variable globale (donc sans local devant) mais que malheureusement vous ayez àfaire àune variable locale déclarée quelques lignes au-dessus... ... En espérant que ce sujet vous ait été utile.
  22. Bonjour, Le but de ce tuto sera de faire une passerelle pour les données de la netatmo vers emoncms. J'en ai profité pour améliorer le script php classique d'interface entre la netatmo et la HC2 les versions disponibles ot du mal à gérer les installations netatmo avec plusieurs modules. Ici j'ai cherché à améliorer les choses et ça fonctionne même lorsque l'on a plusieurs master device et plusieurs stations additionnelles. En effet, savoir l'ordre des modules renvoyé par netatmo dans ces conditions est un peur hard. J'ai ajouté plusieures pages de résultats au script PHP: une avec un json viewer intégré et un qui retourne le json complet. J'ai aussi optimisé pour minimiser le nombre de requêtes faites à netatmo, histoire de ne pas se faire "jeter" voici déjà la présentation de la plateforme emon CMS très puissante que j'utilise depuis plus d'un an: http://emoncms.org/site/home http://emoncms.org/site/docs/visualisations Personellement je l'utilise pour remonter mes graphiques de valeurs diverses de ma HC2 - températures - consommations eau, gaz, elec - paramètres de ma VMC (T° Vitesse, rendement etc.) J'ai partagé mon script avec un ami et comme il était enchanté, je fais l'effort de le mettre ici aussi ;-) En effet, il suffit de configurer les variables dans le VD, créer un répertoire /netatmo dans www ou web ou html, y mettre le PHP et le répertoire jsoneditor et c'est parti, les données seront remontées automatiquement à emonCMS ! Voici déjà le script côté HC2: Je l'ai mis derrière un bouton, car dans un main loop, une corruption json quelquepart et c'est tout qui plante. Ce bouton dont être cliqué via GEA ou autre scheduler toutes les 10 minutes. Voici le Virtual Device tout fait: Grosse mise à jour à ce post: http://www.domotique-fibaro.fr/index.php/topic/3929-yagda-yet-another-graphic-data-analyser-netatmo-vmc-emoncms-json-viewer/#entry63238 Netatmo_V2.vfib Attention, dans ce post ne figure que les scripts de la première version, voir plus loin dans le fil pour les versions suivantes ! ----------------------------------------------------------------------------------------- -- YAGDA - yet another graphic data analyser V2.01 -- Retreive Netatmo values for more than 2 modules, compute CO2 and push to EmonCMS -- Sebastien Jauquet -- Février 2015 -- Thanks to cedriclocqueneux, krikroff, i-magin and all contibutors to the netatmo code ----------------------------------------------------------------------------------------- -- Instructions: -- Create an free emoncms.org account -- Retrieve your Write API Key from it -- Create a Global variable (undefined) -> CO2_Max_Value to store the max value of CO2 of the house - if you dont need this, set CO2 to false (default: 0) -- Install my netatmo.php in your webserver and write his address in the ip Address of this module -- for each value you want to be pushed to emoncms, modify the section -- Push To EMONCMS -- below -- Create a block scene or use gea to click this button each 10 minutes (to avoid rejection from the api of Netatmo) local EmonCMS_Prefix = "NETATMO_" -- prefix of the id of the inpus to be created in emoncms (convenient for testing to not alter current feeds) local PushToEmonCMS = true -- true = push to emoncms - false = do not push local selfId = fibaro:getSelfId(); local thismodule=fibaro:getSelfId() local domaine = fibaro:get(selfId, 'IPAddress') local PushItem local CO2_Max_Value_Local = 0 -- if you dont need this, set CO2 to false (default: 0) local emoncms = Net.FHttp("emoncms.org",80) local emoncms_api_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" -- your EMONCMS WRITE api Key EmonCMS = {}; if (temperature_exterieure==nil) then temperature_exterieure = ""; end if (humidite_exterieure==nil) then humidite_exterieure = ""; end if (temperature_interieure==nil) then temperature_interieure = ""; end if (humidite_interieure==nil) then humidite_interieure = ""; end if (co2==nil) then co2 = ""; end if (pression==nil) then pression = ""; end if (bruit==nil) then bruit = ""; end if (temperature_int_mod2==nil) then temperature_int_mod2 = ""; end if (humidite_int_mod2==nil) then humidite_int_mod2 = ""; end if (co2_mod2==nil) then co2_mod2 = ""; end if (temperature_int_mod3==nil) then temperature_int_mod3 = ""; end if (humidite_int_mod3==nil) then humidite_int_mod3 = ""; end if (co2_mod3==nil) then co2_mod3 = ""; end if (temperature_int_mod4==nil) then temperature_int_mod4 = ""; end if (humidite_int_mod4==nil) then humidite_int_mod4 = ""; end if (co2_mod4==nil) then co2_mod4 = ""; end if(refreshUI==nil) then -- Loads in memory only the first occurence function refreshUI(ext, bruit, titre, tempmod, co2mod, humidmod, lastupdate, laststatus) fibaro:call(selfId,"setProperty","ui.ext.value",ext); fibaro:call(selfId,"setProperty","ui.bruit.value",bruit); fibaro:call(selfId,"setProperty","ui.titre.value",titre); fibaro:call(selfId,"setProperty","ui.tempmod.value",tempmod); fibaro:call(selfId,"setProperty","ui.co2mod.value",co2mod); fibaro:call(selfId,"setProperty","ui.humidmod.value",humidmod); fibaro:call(selfId,"setProperty","ui.lastupdate.value",lastupdate); fibaro:call(selfId,"setProperty","ui.laststatus.value",laststatus); end; end if(getExt==nil) then -- Loads in memory only the first occurence function getExt(retry) retry = retry or 0 -- Setting up the connection data local FHTE = Net.FHttp(domaine, 80); -- Netatmo extérieur local response = FHTE:GET("/netatmo/netatmo.php?parameter=ext"); -- decoding json string to table if (response~= nil) then local result = nil; result = json.decode(response); if (result ~= nil) then -- prevent: attempt to index field 'body' (a nil value) if (result.body ~= nil) then temperature_exterieure = result.body[1].value[1][1] or "n.c"; humidite_exterieure =result.body[1].value[1][2] or "n.c"; -- variable globale pour info sms local msg = "Température extérieure : "..temperature_exterieure.."°C"; fibaro:setGlobal("tempext", msg); return true; else fibaro:debug("Netatmo EXT: erreur le " .. os.date()); if (result.error ~= nil) then fibaro:debug("error code: "..result.error.code..", message: "..result.error.message); end end else fibaro:debug("Netatmo EXT: erreur decodage json le " .. os.date()); end else fibaro:debug("Netatmo EXT:la reponse est null !"); end if ((retry or 5)< 5) then fibaro:debug("Retry #"..retry.."process, please wait..."); fibaro:sleep(5000); return getInt(tonumber(retry+1)); else return false; end end; end if(getInt==nil) then -- Loads in memory only the first occurence function getInt(retry) retry = retry or 0; -- Setting up the connection data local FHTE = Net.FHttp(domaine, 80); -- Netatmo intérieur local response = FHTE:GET("/netatmo/netatmo.php?parameter=int"); -- decoding json string to table if (response~= nil) then local result = nil; result = json.decode(response); if (result ~= nil) then -- prevent: attempt to index field 'body' (a nil value) if (result.body ~= nil) then temperature_interieure = result.body[1].value[1][1] or "n.c"; humidite_interieure = result.body[1].value[1][3] or "n.c"; co2 = result.body[1].value[1][2] or "n.c"; pression = result.body[1].value[1][4] or "n.c"; bruit = result.body[1].value[1][5] or "n.c"; -- variable globale pour info sms fibaro:setGlobal("tempint", "Température intérieure : "..temperature_interieure.."°C"); return true; else fibaro:debug("Netatmo INT: erreur le " .. os.date()); if (result.error ~= nil) then fibaro:debug("error code: "..result.error.code..", message: "..result.error.message); end end else fibaro:debug("Netatmo INT: erreur decodage json le " .. os.date()); end else fibaro:debug("Netatmo INT:la reponse est null !"); end if ((retry or 5)< 5) then fibaro:debug("Retry #"..retry.."process, please wait..."); fibaro:sleep(5000); return getExt(tonumber(retry+1)); else return false; end end; end if(getMod2==nil) then -- Loads in memory only the first occurence function getMod2(retry) retry = retry or 0; -- Setting up the connection data local FHTE = Net.FHttp(domaine, 80); -- Netatmo intérieur local response = FHTE:GET("/netatmo/netatmo.php?parameter=mod2"); -- decoding json string to table if (response~= nil) then local result = nil; result = json.decode(response); if (result ~= nil) then -- prevent: attempt to index field 'body' (a nil value) if (result.body ~= nil) then temperature_int_mod2 = result.body[1].value[1][1] or "n.c"; humidite_int_mod2 = result.body[1].value[1][2] or "n.c"; co2_mod2 = result.body[1].value[1][3] or "n.c"; -- variable globale pour info sms -- fibaro:setGlobal("tempint", "Température intérieure : "..temperature_interieure.."°C"); return true; else fibaro:debug("Netatmo INT_mod2: erreur le " .. os.date()); if (result.error ~= nil) then fibaro:debug("error code: "..result.error.code..", message: "..result.error.message); end end else fibaro:debug("Netatmo INT_mod2: erreur decodage json le " .. os.date()); end else fibaro:debug("Netatmo INT_mod2:la reponse est null !"); end if ((retry or 5)< 5) then fibaro:debug("Retry #"..retry.."process, please wait..."); fibaro:sleep(5000); return getExt(tonumber(retry+1)); else return false; end end; end if(getMod3==nil) then -- Loads in memory only the first occurence function getMod3(retry) retry = retry or 0; -- Setting up the connection data local FHTE = Net.FHttp(domaine, 80); -- Netatmo intérieur local response = FHTE:GET("/netatmo/netatmo.php?parameter=mod3"); -- decoding json string to table if (response~= nil) then local result = nil; result = json.decode(response); if (result ~= nil) then -- prevent: attempt to index field 'body' (a nil value) if (result.body ~= nil) then temperature_int_mod3 = result.body[1].value[1][1] or "n.c"; humidite_int_mod3 = result.body[1].value[1][2] or "n.c"; co2_mod3 = result.body[1].value[1][3] or "n.c"; -- variable globale pour info sms -- fibaro:setGlobal("tempint", "Température intérieure : "..temperature_interieure.."°C"); return true; else fibaro:debug("Netatmo INT_mod3: erreur le " .. os.date()); if (result.error ~= nil) then fibaro:debug("error code: "..result.error.code..", message: "..result.error.message); end end else fibaro:debug("Netatmo INT_mod3: erreur decodage json le " .. os.date()); end else fibaro:debug("Netatmo INT_mod3:la reponse est null !"); end if ((retry or 5)< 5) then fibaro:debug("Retry #"..retry.."process, please wait..."); fibaro:sleep(5000); return getExt(tonumber(retry+1)); else return false; end end; end if(getMod4==nil) then -- Loads in memory only the first occurence function getMod4(retry) retry = retry or 0; -- Setting up the connection data local FHTE = Net.FHttp(domaine, 80); -- Netatmo intérieur local response = FHTE:GET("/netatmo/netatmo.php?parameter=mod4"); -- decoding json string to table if (response~= nil) then local result = nil; result = json.decode(response); if (result ~= nil) then -- prevent: attempt to index field 'body' (a nil value) if (result.body ~= nil) then temperature_int_mod4 = result.body[1].value[1][1] or "n.c"; humidite_int_mod4 = result.body[1].value[1][2] or "n.c"; co2_mod4 = result.body[1].value[1][3] or "n.c"; -- variable globale pour info sms -- fibaro:setGlobal("tempint", "Température intérieure : "..temperature_interieure.."°C"); return true; else fibaro:debug("Netatmo INT_mod4: erreur le " .. os.date()); if (result.error ~= nil) then fibaro:debug("error code: "..result.error.code..", message: "..result.error.message); end end else fibaro:debug("Netatmo INT_mod4: erreur decodage json le " .. os.date()); end else fibaro:debug("Netatmo INT_mod4:la reponse est null !"); end if ((retry or 5)< 5) then fibaro:debug("Retry #"..retry.."process, please wait..."); fibaro:sleep(5000); return getExt(tonumber(retry+1)); else return false; end end; end function EmonCMS:Push(payloademon) payloademon = "/input/post.json?json={" .. EmonCMS_Prefix .. payloademon .. "}&apikey=" .. emoncms_api_key response, status, errorCode = emoncms:GET(payloademon); fibaro:debug("Payload: " .. payloademon) ; fibaro:debug("response: " .. response .. " Status: " .. status .. " errorcode: " .. errorCode) ; fibaro:sleep(500); end local function main() -- retrieve values from netatmo.php local resInt, resExt, resMod2, resMod3, resMod4 = false, false, false, false, false; local status, err = pcall(function () resInt = getInt(); end); fibaro:debug("Récupération des données intérieures: " .. tostring(resInt)); if (status == false) then fibaro:debug("err: "..tostring(err or 'n.c')); end local status, err = pcall(function () resExt = getExt(); end); fibaro:debug("Récupération des données extérieures : " .. tostring(resExt)); if (status == false) then fibaro:debug("err: "..tostring(err or 'n.c')); end local status, err = pcall(function () resMod2 = getMod2(); end); fibaro:debug("Récupération des données intérieures Mod2: " .. tostring(resMod2)); if (status == false) then fibaro:debug("err: "..tostring(err or 'n.c')); end local status, err = pcall(function () resMod3 = getMod3(); end); fibaro:debug("Récupération des données intérieures Mod3: " .. tostring(resMod3)); if (status == false) then fibaro:debug("err: "..tostring(err or 'n.c')); end local status, err = pcall(function () resMod4 = getMod4(); end); fibaro:debug("Récupération des données intérieures Mod4: " .. tostring(resMod4)); if (status == false) then fibaro:debug("err: "..tostring(err or 'n.c')); end refreshUI( "Ext: "..temperature_exterieure.." °C - "..humidite_exterieure.." % - "..pression.." mbar", "Bruit Rez: "..bruit.." dB", "Rez - Emilien - Thomas - Parents", temperature_interieure.." - "..temperature_int_mod2.." - "..temperature_int_mod3.." - "..temperature_int_mod4.." °C ", co2.." - "..co2_mod2.." - "..co2_mod3.." - "..co2_mod4.." ppm", humidite_interieure.." - "..humidite_int_mod2.." - "..humidite_int_mod3.." - "..humidite_int_mod4.." % ", os.date("%H:%M"), tostring(resInt).." "..tostring(resExt).." "..tostring(resMod2).." "..tostring(resMod3).." "..tostring(resMod4) ); -- Push To EMONCMS -- if PushToEmonCMS == true then payloademon = "temperature_exterieure:"..temperature_exterieure EmonCMS:Push(payloademon); payloademon = "humidite_exterieure:".. humidite_exterieure EmonCMS:Push(payloademon); payloademon = "pression:".. pression EmonCMS:Push(payloademon); payloademon = "bruit:".. bruit EmonCMS:Push(payloademon); payloademon = "temperature_interieure_Rez:".. temperature_interieure EmonCMS:Push(payloademon); payloademon = "temperature_int_mod2_Emilien:".. temperature_int_mod2 EmonCMS:Push(payloademon); payloademon = "temperature_int_mod3_Thomas:".. temperature_int_mod3 EmonCMS:Push(payloademon); payloademon = "temperature_int_mod4_Parents:".. temperature_int_mod4 EmonCMS:Push(payloademon); payloademon = "humidite_interieure_Rez:".. humidite_interieure EmonCMS:Push(payloademon); payloademon = "humidite_int_mod2_Emilien:".. humidite_int_mod2 EmonCMS:Push(payloademon); payloademon = "humidite_int_mod3_Thomas:".. humidite_int_mod3 EmonCMS:Push(payloademon); payloademon = "humidite_int_mod4_Parents:".. humidite_int_mod4 EmonCMS:Push(payloademon); payloademon = "co2_Rez:".. co2 EmonCMS:Push(payloademon); payloademon = "co2_mod2_Emilien:".. co2_mod2 EmonCMS:Push(payloademon); payloademon = "co2_mod3_Thomas:".. co2_mod3 EmonCMS:Push(payloademon); payloademon = "co2_mod4_Parents:".. co2_mod4 EmonCMS:Push(payloademon); end -- Compute Value MAX CO2 Maison (For VMC Speed VD) if CO2_Max_Value_Local == false then fibaro:debug("not calculating nor storing CO2 Max Value") else CO2_Max_Value_Local = co2 if CO2_Max_Value_Local < co2_mod2 then CO2_Max_Value_Local = co2_mod2 end if CO2_Max_Value_Local < co2_mod3 then CO2_Max_Value_Local = co2_mod3 end if CO2_Max_Value_Local < co2_mod4 then CO2_Max_Value_Local = co2_mod4 end fibaro:setGlobal("CO2_Max_Value", CO2_Max_Value_Local ) fibaro:debug("CO2_Max_Value: ".. CO2_Max_Value_Local ) end end main();
  23. Je voulais partager avec vous la solution que j'ai mis en place pour suivre ma consommation d'eau. Alors j'ai choisi d'un installer un compteur d'eau "Débitmètre avec sortie d'impulsion Compteur d'eau Générateur de débit d'eau 1 Imp./L Qn 1,5m³/h" J'ai connecté l'impulsion sur un détecteur domotique universel FGBS-0001 entre la pin IN2 et GND. Coté HC2, le capteur est vu comme un capteur de présence, dans mon cas j'ai choisi un capteur de porte. Je coche la case qui permet d'exclure ce capteur des alarmes. Je désactive les alarmes (paramètre 13) en mode broadcast disable. Enfin, j'active dans les options avancées du capteur , le mode scène (paramètre 14 positionné sur ON). Je sauvegarde ce paramètre. Ensuite, j'utilise le service ThingSpeak.com pour pouvoir grapher les résultats. Ce service à l'avantage d'être très simple à mettre en place. Il suffit de créé un "Channel" et je nomme le "field1" -> 'Consommation d'eau'. Dans l'onglet "API Keys" du site ThingSpeak, je sauve la valeur de la clé pour le mode écriture ("Write API Key"). Sur le graphique de ce channel, je choisi le mode "SUM 60 minutes en mode ligne" pour avoir un affichage cumulé des consommations sur une période de 1 heure. Je créé un Virtual Device que je nomme "Graph Eau" avec un bouton que je nomme "grapheau". Et J'utilise le code LUA suivant : fibaro:log('Actualisation consommation eau') thingspeak = Net.FHttp('api.thingspeak.com') payload = 'key=VOTREWRITEAPIKEY&field1=1' response, status, errorCode = thingspeak:POST('/update', payload) Je vais dans le menu Scène et je créé une nouvelle scène que je nomme "Graphique Eau", je créé la scène avec le mode utilisant les blocs pour plus de simplicité. Le paramètre 14 du capteur de présence indique que sur l'entrée IN2, un front montant (OFF -> ON) déclenche un code scène 20. Donc j'indique que "SI le capteur du compteur d'eau == "scène activation" 20 alors j’exécute le bouton "grapheau" du virtual device "Graph Eau". Et voilà ! Cela nous donne un graphique heure par heure de la consommation d'eau. Il est à noter que j'ai choisi un compteur qui me donne 1 impulsion par litre rendant l'interprétation des résultats plus facile. J'espère que cela vous sera utile, je trouve la solution assez élégante et facile à mettre en place.
  24. sebcbien

    Topic Unique S. A. R. A. H.

    Voilà , pas trop de temps pour le moment, mais je vais voir ce que je peux pondre comme tuto pour S.A.R.A.H. Comme je l'ai déjà dit, en général l'installation va toute seule mais parfois ça merde et là 'fo du Barbu costO !... En gros: Windows 10 Installé sur un petit laptop c'est top, pas de place, silencieux, économe en énergie... Télécharger SARAH V4 dans c:/sarah Ajouter le plugin sonos Utiliser mon VD Sarah Say it Pour plus de détails, voir le post suivant. Ancien posts: ------------------- Voici un aperçu Pour la qualité, l'enregistrement n'est pas top mais le volume est au minimum car les enfants dorment Pour la vitesse de conversion en TTS, je pense que ça vous donne une idée... Et l'interruption de la musique est impec et reprends juste après. ----------------- et la photo de mon serveur Jeedom/S.A.R.A.H. Le serveur fermé, c'est beau: Ouvert: Comme vous pouvez le voir c'est un vieux laptop récupéré car l'écran est fichu, tombé de haut et utilisable uniquement en remote ou avec un autre écran.. C'est installé avec Windows 10 et je prends en remote avec TeamViewer. J'ai mon Jeedom qui tourne dans VirtualBox et S.A.R.A.H. sur le windows Consommation en charge avec JD et SARAH: 12W à 15W incluant un UPS avec shutdown automatique svp... (la batterie est encore bonne) J'ai presque envie de relancer ma VM xpenology pour transcoder, là il y a plus de hummph que avec mon DS 412+... C'est tout nouveau, je suis très content de ma solution... avant Jeedom tournait sur mon pc principal qui bouffait entre 70 et 90W en permanence...
  25. Pour faire face au problème récurrent de désynchronisation de l'horloge du HC2 voici un vd très largement inspiré par le support Fibaro cf. internal clock Homecenter is slow Il fonctionne a merveille sur mon HC2 qui n'est plus a la traine maintenant La synchronisation avec le serveur NTP sera faite une fois par jour en automatique par le VD mais il est aussi possible de faire une demande en manuel en cliquant sur le bouton Clock Sync dans le détail du VD ou sur le bouton du VD sur la home du HC2. Voici la miniature pour le vd: Pour la configuration du vd c'est très simple: après l'importation dans le HC2 et renseigné l'adresse IP et le port du HC2 dans l'onglet avancé il faut éditer le code du main loop et de modifier la variable synchroTime avec l'heure de mise à jour. Puis editer le code du bouton btnSync et de modifier les variables username et password avec votre userid et votre password admin de votre HC2 afin de pousser la modification sur votre HC2 par l' API Settings.... Le fichier vfib a importer sur le HC2: Clock_Sync.vfib PS: Si l'importation ne marche pas depuis le HC2, veuillez utiliser le Toolkit pour importer le vd Cette solution est du bidouillage mais cela marche très bien donc pour le moment cela me convient ! Amusez-vous bien...
×