Page 1 sur 1

Script LUA :/ Planning : SetPoint écrasé par Domoticz

Posté : 12 janv. 2020, 13:31
par hairv
Hello,

j'essaie actuellement d'intégrer du matériel Schneider Electric (Wiser Smart) à Domoticz par le biais de la Zigate.
Grâce au super boulot réalisé par Pipiche, le matériel (actionneur radiateur électrique, thermostat et prise) est reconnu.

Le protocole étant spécifique à SE et non documenté, nous sommes parvenus à un fonctionnement un poil bancal (qui devrait s'améliorer dans de futures versions) : en positionnant le setpoint de l'actionneur à une certaine valeur (> 27), le radiateur s'allume, à une valeur inférieure il s'éteint ( :shock: ).

En attendant mieux, j'ai décidé de faire un script pour gérer ce mode de fonctionnement "particulier" en utilisant les plannings Domoticz.
Je compare la température remontée par le thermostat (distinct de l'actionneur du radiateur) à la température du planning et selon le cas je positionne le setpoint de l'actionneur à 33 ou 1 selon que je veux éteindre ou allumer le radiateur.
Le script fonctionne, au delta prés, que la valeur qu'il positionne est immédiatement écrasée par le mécanisme interne Domoticz lors d'un changement planifié. (donc oui le script, de fait, ne sert à rien :mrgreen: )

Quelqu'un connait-il un moyen pour faire en sorte qu'il s'exécute après le mécanisme interne Domoticz mais avant que celui-ci ne modifie le planning ? (qui semble être re-calculé dynamiquement ==> l'entrée traitée par le système est supprimée et l'entrée "+24h" est créée, sinon ce serait trop simple)
... ou a une autre idée ?

Ci-dessous la v0 du script

Code : Tout sélectionner

ON="1"
OFF="33"
OnOff=OFF
APIURL="http://127.0.01:8080/json.htm?"
CURL="/usr/bin/curl"
JQ="/usr/bin/jq"

----------------------------------------
-- timedifference
----------------------------------------
function timedifference (s)

  year = string.sub(s, 1, 4)
  month = string.sub(s, 6, 7)
  day = string.sub(s, 9, 10)
  hour = string.sub(s, 12, 13)
  minutes = string.sub(s, 15, 16)
  seconds = string.sub(s, 18, 19)
  t1 = os.time()
  t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
  difference = os.difftime (t1, t2)
  return difference
end

----------------------------------------
-- tablelength
----------------------------------------
function tablelength(T)
  local count = 0
  for _ in pairs(T) do count = count + 1 end
  return count
end

----------------------------------------
-- os.capture
----------------------------------------
function os.capture(cmd, raw)
  local f = assert(io.popen(cmd, 'r'))
  local s = assert(f:read('*a'))
  f:close()
  if raw then return s end
  s = string.gsub(s, '^%s+', '')
  s = string.gsub(s, '%s+$', '')
  s = string.gsub(s, '[\n\r]+', ' ')
  return s
end


----------------------------------------
-- OnOffRegardingScheduledTemp
----------------------------------------
function OnOffRegardingScheduledTemp(idxRadiateur, temperature)
   local config=assert(io.popen(CURL .. " '" .. APIURL .. "type=schedules&rid="..idxRadiateur.."'"))
    local blocjson = config:read('*all')
    config:close()
    local jsonValeur = json:decode(blocjson)
    
    local i=1
    
    local nbElem=tablelength(jsonValeur.result)
    local differencetime = -1
    while (i <= nbElem and differencetime < 0)
    do
        --print (jsonValeur.result[i].ScheduleDate .. "-->" .. timedifference(jsonValeur.result[i].ScheduleDate) .. " : " .. jsonValeur.result[i].Temperature)
     
        differencetime = timedifference(jsonValeur.result[i].ScheduleDate)
        if ( (tonumber(jsonValeur.result[i].DeviceRowID) == tonumber(idxRadiateur)) 
              and (differencetime >= 0) 
              and (jsonValeur.result[i].Active == "true") )
        then
            if (tonumber(temperature) > tonumber(jsonValeur.result[i].Temperature)) 
            then
                 return OFF
            else
                return ON
            end
            
        end
        
        i=i+1
    end
    return "NOCHANGE"
end

----------------------------------------
-- setOnOff
----------------------------------------
function setOnOff(idxThermostat,idxRadiateur)
    -- Récupération de la température actuelle depuis le thermostat
    local temperature = os.capture(CURL .. " -s '" .. APIURL .. "type=devices&rid="..idxThermostat.."'| " .. JQ .. " -r '.result[] |.Temp'")
    
    OnOff=OnOffRegardingScheduledTemp(idxRadiateur, temperature)
    
    if (OnOff == "NOCHANGE")
    then
        -- Aucune température récupérée dans le planning pour ce device, on repositionne la température actuelle (juste pour éviter un dé-appairage qui peut survenir sans actione pendant plus de 15 min)
        local config=assert(io.popen(CURL .. " '" .. APIURL .. "type=devices&rid="..idxRadiateur.."'"))
        local blocjson = config:read('*all')
        config:close()
        local jsonValeur = json:decode(blocjson)
        config=assert(io.popen(CURL .. " '" .. APIURL .. "type=command&param=setsetpoint&idx=116&setpoint=" .. jsonValeur.result[1].Data .. "'"))
     
    else
        config=assert(io.popen(CURL .. " '" .. APIURL .. "type=command&param=setsetpoint&idx=" .. idxRadiateur .. "&setpoint=" .. OnOff .. "'"))
    end
    
end

----------------------------------------
-- Main
----------------------------------------

commandArray = {}
json = (loadfile "/root/domoticz/scripts/lua/JSON.lua")() -- Synology docker

if  (timedifference(tostring(uservariables_lastupdate['LastTimeSetOnOff'])) >  uservariables['LastTimeSetOnOff'])
then
    setOnOff("118","116")
    commandArray['Variable:LastTimeSetOnOff']=tostring(uservariables['LastTimeSetOnOff'])
end
return commandArray
En espérant avoir été clair (sans réellement y croire ;) )
Merci pour votre aide