Bonjour,
Il existe déjà plusieurs Virtual Devices relatifs à l'Eco-Devices sur le forum mais n'ayant pas trouvé mon bonheur, j'ai entièrement écrit un module de zéro en fonction de mes besoins et en espérant qu'il puisse également servir à d'autres.
Que fait ce Virtual Device ?
1) Suivi en temps réel des statistiques d'un compteur téléinfo (T1 ou T2) HC/HP
2) Affichage temps réel d'une icône de type "jauge" présentant le tarif actuel (HC/HP) ainsi que la valeur de consommation actuelle
3) Affichage temps des index en kWatts au 1000ième, index en cours (HC ou HP) toujours en premier
4) Affichage temps réel d'un compteur de consommation journalier en Watts pour les HP et les HC
5) Affichage temps réel du coà»t de consommation journalier
6) Génération d'un rapport Email de consommation journalière
7) Fonction de remise à zéro manuelle des compteurs journaliers
8) Gestion de l'authentification utilisateur Eco-Devices
Evolutions prévues :
1) Ajout d'un compteur de cumul mensuel
2) Estimation de prochaine facture et publication d'index "Releve Confiance" chez EDF (fera certainement l'objet d'un second module "EDF & Moi")
Voici un aperçu des vues graphiques du Virtual Device :
La liste des icones de jauges :
Deux méthodes sont proposées pour la récupération des statistiques de l'Eco-Devices :
L'existence de ces 2 méthodes est liée à un bug connu de la HC2 lors de l'utilisation de requêtes HTTP dans la mainLoop d'un Virtual Device qui bloque au bout d'un certain temps.
Le moyen de contourner cela est l'utilisation d'un bouton déclenché depuis la mainLoop qui a comme inconvénient de modifier l'icône pour la durée du traitement ce qui personnellement ne me convient pas.
- Méthode 1 (recommandée) : C'est la méthode que j'ai choisi car elle se base sur une scène afin de rafraichir les données et évite ainsi le changement d'icône indésirable durant la récupération des données.
-> Pour utiliser cette méthode, vous devez en plus créer et configurer la scène fournie puis dans la MainLoop, positionner la variable useSceneToRefresh à true
- Méthode 2 (par défaut ) : C'est la méthode configurée par défaut qui évite l'utilisation d'une scène en parallèle mais avec l'inconvénient de l'icône qui sera modifiée à chaque récupération des données. J'ai toutefois crée une icône dédiée à configurer sur ce bouton : afin que ce ne soit pas trop moche.
-> Pour utiliser cette méthode, vous devez simplement positionner la variable useSceneToRefresh à false dans la MainLoop
Comment l'utiliser ?
1) Importer la dernière version du Virtual Device : Eco_Devices_Live_Day_Reporter_V0.1.vfib
2) Renseignez l'adresse IP ainsi que le port (80 par défaut) de votre Eco-Devices
3) Importer la série d'icônes de jauges fournies en respectant l'ogre dans lequel elles sont fournies, c'est très important, puis notez l'Id correspondant à la première
4) Dans la mainLoop, renseignez les valeurs des variables teleInfoNB, baseIconId, userIdsToNotify, useSceneToRefresh et si besoin reportTime
5) Si vous utilisez la Méthode 1 (useSceneToRefresh = true) vous devez créer la scène Eco-Devices Refresh (voir ci-dessous)
6) Dans le code du bouton "Raraîchir" pensez à saisir vos in formations d'authentification si vous l'avez activée sur l'Eco-Devices
7) Pas besoin de créer de variables globales, elles sont automatiquement crées au premier démarrage du Virtual Device
8) Sauvegarder la scène et tout devrait bien fonctionner
Pour ceux qui utilisent la Méthode 1 :
Voici le code de la scènes Eco-Devices Refresh
Il est IMPORTANT de bien renseigner le deviceId correspondant à l'Id de votre Virtual device importé ci-dessus.
Si vous avez activé l'authentification sur l'Eco-Devices, vous devez ici saisir vos informations d'authentification encodées en base64.
Si vous ne l'avez pas déjà fait, il suffit d'aller sur https://www.base64encode.org, d'encoder en UTF8 la chaine correspondante à "<login>:<password>" et de récupérer le résultat.
Par exemple "admin:password" donnera "YWRtaW46cGFzc3dvcmQ="
saut de
--[[
%% autostart
%% properties
%% globals
--]]
-- Récurrence de rafraichissement des stats en secondes
local checkEvery = 3
-- Id du Virtual Device
local deviceId = 228
-- Authentification ("" si pas d'authentification sinon chaine "<login>:<password>" en base64
local base64BasicAuthentication = ""
local sourceTrigger = fibaro:getSourceTrigger()
local ecoDevicesIP = tostring(fibaro:get(deviceId,"IPAddress"))
local ecoDevicesStats = nil
--- Usefull Functions ---
function debug(text, color)
color = color or "white"
fibaro:debug(string.format('<%s style="color:%s;">%s</%s>', "span", color, text, "span"))
end
function setDevicePropertyValue(id, label, value)
fibaro:call(id, "setProperty", "ui."..label..".value", value)
end
function getDevicePropertyValue(vDeviceid, propertyName)
return fibaro:getValue(vDeviceid, "ui."..propertyName..".value")
end
function refreshEcoDevicesStats()
debug("Rafraichissement des statistiques de l'EcoDevices...")
ecoDevicesStats = nil
local http = net.HTTPClient()
http:request("http://"..ecoDevicesIP.."/api/xdevices.json?cmd=10", {
options = {
method = 'GET',
headers = {["Authorization"] = 'BASIC '..base64BasicAuthentication},
},
success = function(response) ecoDevicesStats = response.data refreshEcoDevicesStatsAsync() end,
error = function(err) debug("Error: " ..err, "red") fibaro:sleep(1000) refreshEcoDevicesStats() end
})
end
function refreshEcoDevicesStatsAsync()
fibaro:setGlobal("ecoDevicesStats", ecoDevicesStats)
debug("OK ! "..ecoDevicesStats, "green")
if (sourceTrigger["type"] == "autostart") then
setTimeout(refreshEcoDevicesStats, checkEvery*1000)
end
end
refreshEcoDevicesStats()
lignesaut de ligne
Enfin, voici le code de la MainLoop :
saut de ligne
--------------------------------------------------------
-- Eco-Devices Live & Day Reporter v0.1 --
--------------------------------------------------------
-- Auteur : Brice Cassagnabère --
--------------------------------------------------------
-- Changelog : --
-- --
-- v0.1 : Version initiale --
--------------------------------------------------------
-- Plus d'infos : http://is.gd/tMgWdy --
--------------------------------------------------------
-- Renseignez ici le numéro de téléinfo à prendre en compte, T1 ou T2
teleInfoNB = "T1"
-- Renseignez ici le numéro de la première icône de jauge (HC_0.png)
baseIconId = 1047
-- Renseignez ici les id Utilistaurs à qui transmettre le rapport
userIdsToNotify = {2, 154}
-- Si vous utilisez la scène associée pour la MAJ, passer cette variable à true
useSceneToRefresh = false
-- Heure à laquelle vous souhaitez générer le rapport journalier
reportTime = "23:59"
-- Tarifs des kWh 2015
hcCost = 0.0623
hpCost = 0.1019
deviceId = fibaro:getSelfId()
--- Usefull Functions ---
function debug(text, color)
color = color or "white"
fibaro:debug(string.format('<%s style="color:%s;">%s</%s>', "span", color, text, "span"))
end
function setDevicePropertyValue(id, label, value)
fibaro:call(id, "setProperty", "ui."..label..".value", value)
end
function getDevicePropertyValue(vDeviceid, propertyName)
return fibaro:getValue(vDeviceid, "ui."..propertyName..".value")
end
function createGlobalIfNotExists(varName, defaultValue)
if fibaro:getGlobal(varName) == "" then
debug("Création de la variable "..varName.." avec comme valeur par défaut "..defaultValue)
newVar = {}
newVar.name = varName
newVar.value = defaultValue
HC2 = Net.FHttp("127.0.0.1", 11111)
HC2:POST("/api/globalVariables", json.encode(newVar))
end
end
function refreshEcoDevicesStats()
if not useSceneToRefresh then
fibaro:call(deviceId, "pressButton", 5)
fibaro:sleep(1000)
end
jsonStats = fibaro:getGlobalValue("ecoDevicesStats")
if not string.find(jsonStats, '{"product":"Eco-') then
debug("An error occured -> "..jsonStats, "red")
debug("No stats found, please check documentation and configuration", "orange")
return false
end
ecoDevicesStats = json.decode(jsonStats)
tarif = string.format("%.2s", ecoDevicesStats[teleInfoNB.."_PTEC"])
conso = ecoDevicesStats[teleInfoNB.."_PAPP"]
hcIndex = ecoDevicesStats[teleInfoNB.."_HCHC"]
hpIndex = ecoDevicesStats[teleInfoNB.."_HCHP"]
hcIndexStr = "HC : "..string.format("%.3f", hcIndex/1000)
hpIndexStr = "HP : "..string.format("%.3f", hpIndex/1000)
fibaro:log("Tarif : "..tarif.." - Conso : "..conso.." VA".." - "..hcIndexStr.." - "..hpIndexStr)
iconId = baseIconId
if tarif == "HP" then
activeIndex = hpIndexStr
inactiveIndex = hcIndexStr
iconId = iconId + 9
else
activeIndex = hcIndexStr
inactiveIndex = hpIndexStr
end
-- Mise à jour des Labels
setDevicePropertyValue(deviceId, "labelTarif", tarif)
setDevicePropertyValue(deviceId, "labelConso", conso.." VA")
setDevicePropertyValue(deviceId, "labelActiveIndex", activeIndex.." kW")
setDevicePropertyValue(deviceId, "labelInactiveIndex", inactiveIndex.." kW")
-- Mise à jour de l'icône
conso = ecoDevicesStats[teleInfoNB.."_PAPP"]
if conso >= 1000 then
if conso < 9000 then
iconId = iconId + tonumber(string.format("%.1s", conso))
else
iconId = iconId + 8
end
end
fibaro:call(deviceId, "setProperty", "currentIcon", iconId)
return true
end
function refreshDayStats()
day_HC_Conso = hcIndex - day_HC_Index
day_HP_Conso = hpIndex - day_HP_Index
day_HC_ConsoStr = "HC : "..day_HC_Conso.." W"
day_HP_ConsoStr = "HP : "..day_HP_Conso.." W"
if tarif == "HP" then
activeDayIndex = day_HP_ConsoStr
inactiveDayIndex = day_HC_ConsoStr
else
activeDayIndex = day_HC_ConsoStr
inactiveDayIndex = day_HP_ConsoStr
end
-- Calcul du coà»t en €
dayCost = ((day_HP_Conso * hpCost) + (day_HC_Conso * hcCost)) / 1000
dayCost = dayCost + (dayCost * 0.2)
dayCostStr = "Coà»t : "..string.format("%.2f", dayCost).." €"
setDevicePropertyValue(deviceId, "labelActiveDayIndex", activeDayIndex)
setDevicePropertyValue(deviceId, "labelInactiveDayIndex", inactiveDayIndex)
setDevicePropertyValue(deviceId, "labelToday", dayCostStr)
end
function reportDayStats()
message = "HC : "..day_HC_Conso.." Watts\nHP : "..day_HP_Conso.." Watts\n"..dayCostStr
for k,v in pairs(userIdsToNotify) do
fibaro:call(v, "sendEmail", "Consommation électrique du "..os.date("%d/%m/%Y"), message)
end
end
function checkCptRaz()
-- Tous les jours à minuit, je stockera valeur de l'index en cours
if tostring(os.date("%H:%M")) == reportTime or day_HC_Index == 0 or ecoDevicesStats.raz then
debug("Initialisation du compteur journalier", "green")
if tostring(os.date("%H:%M")) == reportTime then reportDayStats() end
day_HC_Index = hcIndex
day_HP_Index = hpIndex
fibaro:setGlobal("day_HC_Index", day_HC_Index)
fibaro:setGlobal("day_HP_Index", day_HP_Index)
while tostring(os.date("%H:%M")) == reportTime do
fibaro:sleep(1000)
end
end
end
-- Création automatique des variable globales
createGlobalIfNotExists("ecoDevicesStats", "0")
createGlobalIfNotExists("day_HC_Index", "0")
createGlobalIfNotExists("day_HP_Index", "0")
-- Je rafraichis les stats une première fois pour initialiser mes variables locales
if not refreshEcoDevicesStats() then return end
day_HC_Index = tonumber(fibaro:getGlobalValue("day_HC_Index"))
day_HP_Index = tonumber(fibaro:getGlobalValue("day_HP_Index"))
-- Boucle principale
while true do
-- ## Pensez à bien choisir votre méthode de mise à jour des stats
-- ## Méthode 1 (useSceneToRefresh = true) ## : Vous utilisez la Scene de Mise à jour des stats qui évite
-- le changement d'icône indésirable
-- ## Méthode 2 (useSceneToRefresh = false) ## : Pas besoin de créer la scene mais entrainera un court changement
-- de l'icône durant le reresh contrairement à la précédente
if not refreshEcoDevicesStats() then return end
refreshDayStats()
checkCptRaz()
fibaro:sleep(2000)
end
saut de ligne
Historique des versions :
- V0.1 du 11/05/2015 : Eco_Devices_Live_Day_Reporter_V0.1.vfib