blind percentage position
Moderator: leecollings
-
megamarco83
- Posts: 109
- Joined: Friday 21 September 2018 15:07
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
blind percentage position
hi, i have an nodemcu where i flash espeasy and i connect 2 relays for my blind: 1relay to UP, and 1relay to DOWN
i have also connect 2 wall switch: 1 switch UP 1switch DOWN
in EspEasy rules i create a rule to identify short press or longpress (pression >= 4seconds of wall swith)
if i use shorpres the corrisponding relay is active for 1sec. if i use longpress the corresponding relay is acrived for 46sec. (46sec. = time to all open or all close the blind)
domoticz is ablo to recognize the moviment UP or DOWN if i use wall switch thanks to command inside domoticz blind switch:
http://192.168.0.154/control?cmd=event, ... N_domoticz
http://192.168.0.154/control?cmd=event, ... P_domoticz
now i want to recognize the position of the blind i have in mind to monitoring the seconds, starting from the activation of the switch. for example the idea is:
starting from all close -> i longress UP on wall swith (relay start to UP with a time of 46sec) -> after 15sec i want to stop my blind i press DOWN shortpress on the wall switch and the blind stop in that position that i choose -> script in domoticz should have counting this 15sec passed and give to domoticz that result: (15sec / 46sec ) * 100= 36% and show on the blind with percentage open 36%
if i use a shortpress wall switch -> i will activate the relay for 1sec -> send to domoticz the value 1sec -> domoticz calcolate (1sec / 46 sec) * 100 = 2% open
if i use again a shorpress from wall swith -> domoticz activate the relay for 1sec -> domoticz calcolate (1sec / 46 sec) * 100 = 2% open + 2% of previous position = 4%open
how i can implement that?
i have also connect 2 wall switch: 1 switch UP 1switch DOWN
in EspEasy rules i create a rule to identify short press or longpress (pression >= 4seconds of wall swith)
if i use shorpres the corrisponding relay is active for 1sec. if i use longpress the corresponding relay is acrived for 46sec. (46sec. = time to all open or all close the blind)
domoticz is ablo to recognize the moviment UP or DOWN if i use wall switch thanks to command inside domoticz blind switch:
http://192.168.0.154/control?cmd=event, ... N_domoticz
http://192.168.0.154/control?cmd=event, ... P_domoticz
now i want to recognize the position of the blind i have in mind to monitoring the seconds, starting from the activation of the switch. for example the idea is:
starting from all close -> i longress UP on wall swith (relay start to UP with a time of 46sec) -> after 15sec i want to stop my blind i press DOWN shortpress on the wall switch and the blind stop in that position that i choose -> script in domoticz should have counting this 15sec passed and give to domoticz that result: (15sec / 46sec ) * 100= 36% and show on the blind with percentage open 36%
if i use a shortpress wall switch -> i will activate the relay for 1sec -> send to domoticz the value 1sec -> domoticz calcolate (1sec / 46 sec) * 100 = 2% open
if i use again a shorpress from wall swith -> domoticz activate the relay for 1sec -> domoticz calcolate (1sec / 46 sec) * 100 = 2% open + 2% of previous position = 4%open
how i can implement that?
- waaren
- Posts: 6028
- Joined: Tuesday 03 January 2017 14:18
- Target OS: Linux
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: blind percentage position
I played a little bit with the idea.megamarco83 wrote: Tuesday 02 October 2018 11:07 ...I want to recognize the position of the blind i have in mind to monitoring the seconds, starting from the activation of the switch. for example the idea is:
starting from all close -> i longress UP on wall swith (relay start to UP with a time of 46sec) -> after 15sec i want to stop my blind i press DOWN shortpress on the wall switch and the blind stop in that position that i choose -> script in domoticz should have counting this 15sec passed and give to domoticz that result: (15sec / 46sec ) * 100= 36% and show on the blind with percentage open 36%
...
This script uses the lastupdate.secondsAgo and state attribute of the blind to estimate the position. Script is not
complete nor failsafe but might help you in design and develop process.
Code: Select all
local blindCheckVar = "checkBlindState" -- type string; need to be created manually
local blindIDX = 296 -- idx of your blind
return {
on = { devices = { blindIDX },
variables = { blindCheckVar }},
logging = { level = domoticz.LOG_DEBUG,
marker = "Blinds position" },
data = { action = { initial = "Open" }, -- device.state
active = { initial = 0 }, -- information only
position = { initial = 0 }}, -- 0 = open / 100 = closed
execute = function(dz, item )
local maxActionTime = 46
local blind = dz.devices(blindIDX)
local idleTime = blind.lastUpdate.secondsAgo
local function updatePersistent(action,active,position)
dz.data.position = dz.utils.round(math.max(math.min(position,100),0)) or dz.data.position
dz.data.active = active or dz.data.active
dz.data.action = action or dz.data.action
end
-- This block will be triggered by the var change and will set
-- the position to completely Open or completely Closed when no stop Command is received
if item.isVariable then
if idleTime > maxActionTime then
if dz.data.action == "Open" then
updatePersistent("Stopped",idleTime,0)
elseif dz.data.action == "Closed" then
updatePersistent("Stopped",idleTime,100)
end
end
return
end
-- This block will do the actual calculation
local position = dz.data.position
if blind.state == "Stopped" or
( blind.state == "Open" and dz.data.action == "Closed" ) or
( blind.state == "Closed" and dz.data.action == "Open" ) then
local factor = 1
if dz.data.action == "Open" then
factor = -1
end
position = dz.data.position + factor * (( idleTime ) * ( 100/maxActionTime ))
end
updatePersistent(blind.state,idleTime,position)
-- Next if block will schedule an update of a uservariable that will force
-- a trigger of this script even when no stop command is given
if blind.state == "Open" or blind.state == "Closed" then
local timeRemains = dz.data.position/100 * maxActionTime
if blind.state == "Closed" then
timeRemains = maxActionTime - timeRemains
end
dz.variables(blindCheckVar).set(blind.state).afterSec(timeRemains + 3)
end
end
}Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
-
megamarco83
- Posts: 109
- Joined: Friday 21 September 2018 15:07
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: blind percentage position
wow thanks so much!!!!
i try to adapt your code and i create this:
i create a user var as string named: "checkBlindState" this is my blind with percentage switch, that as id=31 and this is what is inside: this is your code:
Code: Select all
local blindCheckVar = "checkBlindState" -- type string; need to be created manually
local blindIDX = 31 -- idx of your blind
return {
on = { devices = { blindIDX },
variables = { blindCheckVar }},
logging = { level = domoticz.LOG_DEBUG,
marker = "Blinds position" },
data = { action = { initial = "Open" }, -- device.state
active = { initial = 0 }, -- information only
position = { initial = 0 }}, -- 0 = open / 100 = closed
execute = function(dz, item )
local maxActionTime = 10 -- seconds to completly the action (10 for test)
local blind = dz.devices(blindIDX)
local idleTime = blind.lastUpdate.secondsAgo
local function updatePersistent(action,active,position)
dz.data.position = dz.utils.round(math.max(math.min(position,100),0)) or dz.data.position
dz.data.active = active or dz.data.active
dz.data.action = action or dz.data.action
end
-- This block will be triggered by the var change and will set
-- the position to completely Open or completely Closed when no stop Command is received
if item.isVariable then
if idleTime > maxActionTime then
if dz.data.action == "Open" then
updatePersistent("Stopped",idleTime,0)
elseif dz.data.action == "Closed" then
updatePersistent("Stopped",idleTime,100)
end
end
return
end
-- This block will do the actual calculation
local position = dz.data.position
if blind.state == "Stopped" or
( blind.state == "Open" and dz.data.action == "Closed" ) or
( blind.state == "Closed" and dz.data.action == "Open" ) then
local factor = 1
if dz.data.action == "Open" then
factor = -1
end
position = dz.data.position + factor * (( idleTime ) * ( 100/maxActionTime ))
end
updatePersistent(blind.state,idleTime,position)
-- Next if block will schedule an update of a uservariable that will force
-- a trigger of this script even when no stop command is given
if blind.state == "Open" or blind.state == "Closed" then
local timeRemains = dz.data.position/100 * maxActionTime
if blind.state == "Closed" then
timeRemains = maxActionTime - timeRemains
end
dz.variables(blindCheckVar).set(blind.state).afterSec(timeRemains + 3)
end
end
}
so also in ESPeasy on nodemcu i changed:
shor press down wall switch = 2sec DOWN
short press UP wall switch = 2 sec UP
long press DOWN wall switch = 10 sec down
long press UP wall switch = 10 sec UP
if i press domoticz UP = 10 sec UP relay is activation
if i press domoticz DOWN = 10sec DOWN relay down activation
so all is ok, now related to the percentage:
i started to all close (domoticz 0%) then i short press wall switch UP -> 2sec activation relay UP -> i see in domoticz 40% open (why?!?!?) (the string checkBlindState is closed)
then i short press again wall switch UP-> 2sec activation relay UP -> i see again in domoticz 40% open (same as previous) (the user string checkBlindState is closed)
then i long press again wall switch UP -> 10sec activation relay UP -> i see in domoticz 100% open (the user string checkBlindState now is open)
when i short press wall switch DOWN -> 2sec activation relay DOWN -> i see again in domoticz 0% (all close) (the user string checkBlindState is closed)
when i long press wall switch DOWN -> 10sec activation relay DON -> i see in domoticz 0% (all close) (the user string checkBlindState is closed again)
i do not understand....
if it's needed this is my ESP rules:
Code: Select all
on B_UP#Shortpress do
if [relayp#R_UP]>0
output,relayp,0,0
else
output,relayp,1,0
output,relayp,0,1
SendToHTTP 192.168.0.105,8085,/json.htm?type=command¶m=switchlight&idx=31&switchcmd=Set%20Level&level=40
timerset,1,2
endif
endon
on B_UP#Longpress do
event,event_UP_domoticz
endon
on event_UP_domoticz do
if [relayp#R_UP]>0
output,relayp,0,0
else
output,relayp,1,0
output,relayp,0,1
timerset,1,10 // 10 sec as test to simulate completly UP
SendToHTTP 192.168.0.105,8085,/json.htm?type=command¶m=udevice&idx=31&nvalue=1&svalue=40
endif
endon
on B_DOWN#Shortpress do
if [relayp#R_DOWN]>0
output,relayp,1,0
else
output,relayp,0,0
output,relayp,1,1
SendToHTTP 192.168.0.105,8085,/json.htm?type=command¶m=switchlight&idx=31&switchcmd=Set%20Level&level=0
endif
endon
on B_DOWN#Longpress do
event,event_DOWN_domoticz
endon
on event_DOWN_domoticz do
if [relayp#R_DOWN]>0
output,relayp,1,0
else
output,relayp,0,0
output,relayp,1,1
timerset,2,10 // 10 sec as test to simulate completly DOWN
SendToHTTP 192.168.0.105,8085,/json.htm?type=command¶m=udevice&idx=31&nvalue=0&svalue=0
endif
endon
on Rules#Timer=1 do
output,relayp,0,0
endon
on Rules#Timer=2 do
output,relayp,1,0
endon gpio15= relay UP
gpio12= relay DOWN
gpio1 = wall switch UP
gpio3 = wall switch DOWN
- waaren
- Posts: 6028
- Joined: Tuesday 03 January 2017 14:18
- Target OS: Linux
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: blind percentage position
The script is created for a Blind that return "Open", "Closed" or "Stopped" as state.megamarco83 wrote: Tuesday 02 October 2018 23:15short press down wall switch = 2sec DOWN
short press UP wall switch = 2 sec UP
long press DOWN wall switch = 10 sec down
long press UP wall switch = 10 sec UP
I do not understand....
The %-age "Open" is calculated when a "Stop" command is received or when the time until max. Open or Close has passed (controlled by the afterSeconds command mode)
The script is now just to give an idea. It does not update anything else than the uservariable and dzVents persistent data.
I am a bit busy the next couple of weeks but after that I am happy to look at it again. Probably better to discuss via PM and come back here if /when we have something working. OK ?
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
- emme
- Posts: 909
- Joined: Monday 27 June 2016 11:02
- Target OS: Raspberry Pi / ODroid
- Domoticz version: latest
- Location: Milano, Italy
- Contact:
Re: blind percentage position
be aware that time for rolling up could be NOT the same for rolling down... due to forces, gravity and performances of the actuator. 
you'd better evaluate to split timers into 2 different values
you'd better evaluate to split timers into 2 different values
The most dangerous phrase in any language is:
"We always done this way"
"We always done this way"
- waaren
- Posts: 6028
- Joined: Tuesday 03 January 2017 14:18
- Target OS: Linux
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: blind percentage position
Thx. Will keep that in mindemme wrote: Wednesday 03 October 2018 8:08 be aware that time for rolling up could be NOT the same for rolling down... due to forces, gravity and performances of the actuator.
you'd better evaluate to split timers into 2 different values
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
-
megamarco83
- Posts: 109
- Joined: Friday 21 September 2018 15:07
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: blind percentage position
yes, true. i misured both time UP and DOWN and i have a difference that is only 2 sec, but you are true, if we want to generalize for other person (and i think that is very usefull for many person) is better to follow your suggestion and using 2 timersemme wrote: Wednesday 03 October 2018 8:08 be aware that time for rolling up could be NOT the same for rolling down... due to forces, gravity and performances of the actuator.
you'd better evaluate to split timers into 2 different values
thanks!
-
megamarco83
- Posts: 109
- Joined: Friday 21 September 2018 15:07
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: blind percentage position
ok, no problem for me, that's fantasticwaaren wrote: Wednesday 03 October 2018 0:28
The script is created for a Blind that return "Open", "Closed" or "Stopped" as state.
The %-age "Open" is calculated when a "Stop" command is received or when the time until max. Open or Close has passed (controlled by the afterSeconds command mode)
The script is now just to give an idea. It does not update anything else than the uservariable and dzVents persistent data.
I am a bit busy the next couple of weeks but after that I am happy to look at it again. Probably better to discuss via PM and come back here if /when we have something working. OK ?
i PM you with my contact, then if we succeed i will write here, i think that could be very usefull for many users!
keep in touch, in the meanwhile i'll try to do some tests (i'm a beginner, so very very small steps contribution from my side )
thanks for your kindness as usual
- DewGew
- Posts: 581
- Joined: Thursday 21 April 2016 12:01
- Target OS: Raspberry Pi / ODroid
- Domoticz version: V4.10618
- Location: Sweden
- Contact:
Re: blind percentage position
Any progress with this script? I need this..
Raspberry Pi 3 | domoticz | Aeon Labs Z-Stick GEN5 | RFlink gateway
NanoPi NEO-air | REGO6XX interface | Machinon theme | Homebridge | Domoticz Google Assistant | ideAlarm
NanoPi NEO-air | REGO6XX interface | Machinon theme | Homebridge | Domoticz Google Assistant | ideAlarm
- waaren
- Posts: 6028
- Joined: Tuesday 03 January 2017 14:18
- Target OS: Linux
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: blind percentage position
The script is ready and in use but probably not generic enough to share with a wide audience. I attach it here but I cannot give much support on it.
I will try to answer questions to clarify but will not make modifications. So use it at it is and make the necessary adjustments for your specific situation yourself.
@megamarco83 can share the detailed rules and settings necessary in the nodemcu but in short you will have to setup MQTT as communication and listen to incoming MQTT messages and set the attached relais accordingly.
Have Fun !
Code: Select all
--[[ this scripts handles two way commmunication between domoticz and nodemcu / relais
*** nodemcu to domoticz: nodemcu update the (type string) uservariable blindControl with an MQTT command json string like
Publish domoticz/in,{"command":"setuservariable","idx":55,"value":"blind_1;Up;42"} -- testJSON up
Publish domoticz/in,{"command":"setuservariable","idx":55,"value":"blind_1;Down;2"} -- testJSON down
dzVents will pickup the variable and set the virtual blind accordingly
*** domoticz to relais : dzVents is triggered by a change (open / close / On / Off and setting a percentage with the slider )in any device with a name
that starts with "blind_", it will calculate the number of equivalent seconds and the direction and send that together
with the name of the device back to nodemcu with an MQTT command
the constructed OS command to send the MQTT message looks like:
mosquitto_pub -t LM46_213/blind_1_Down -m 1
The OS Command to send the off signal is scheduled for after n seconds using a delayed URL
the description field of the virtual blind contain the necessary information to identify the nodemcu and the settings there.
Layout: {"nodemcu":"LM46_213","maxUpTime":"42","maxDownTime":"36"}
some history (last action per device and last nodemcu action will be maintained in
dzVenst persistent data. Lay-out in domoticzdir/scripts/dzVents/data/__data_scriptname.lua
also in persistent data is per blind a line setting the until blocktime (in seconds from epoch)
MQTT messages can be monitored on the CLI with mosquitto_sub -F "%U - %t - %p" -v -h <broker IP or broker DNS name> -p 1883 -t '#'
]] --
return {
-- active = false,
on = { devices = { "blind_*" },
variables = { "blindControl" },
httpResponses = { "nodemcu_*" }}, -- wildcard
logging = { level = domoticz.LOG_DEBUG,
marker = "MQTT Blindposition" },
data = { blinds = { initial = {} },
commands = { history = true, maxItems = 10 },
},
execute = function(dz, item, info )
_G.logMarker = info.scriptName -- sets the logmarker for dz.log
local allBlinds = {"blind_1","blind_2","blind_3"} -- blind names in domoticz
local maxBlindDownTime = 36 -- default time in seconds for blind to go from fully open to fully closed (can be overruled in description)
local maxBlindUpTime = 42 -- default time in seconds for blind to go from fully closed to fully open (can be overruled in description)
local control = {}
local entryTime = os.date(os.time())
local function logWrite(str,level)
dz.log(tostring(str),level or dz.LOG_DEBUG)
end
local function dumpPersist()
for k,v in pairs(dz.data.blinds[item.name]) do
logWrite(k .. " ===>>> " ..tostring(v) )
end
logWrite(item.name .. "; state: " .. item.state)
end
-- if item.isDevice then
-- logWrite("\n\n" .. item.name .. "; state: " .. item.state .. "\n" .. item.name .. "; level: " .. item.level .. "\n")
-- return
-- end
local function blockBlind(blind,blockSeconds,blocker)
dz.data.blinds[blind] = dz.data.blinds[blind] or {}
dz.data.blinds[blind].blockedUntil = math.ceil(os.date(os.time() + blockSeconds+1)) -- blocked until
dz.data.blinds[blind].blockedBy = blocker
dz.data.blinds[blind].blockedFrom = os.date(os.time())
dz.data.blinds[blind].levelFrom = dz.devices(blind).lastLevel
logWrite(blind .. " is blocked until " .. os.date("%X",os.time() + blockSeconds))
end
local function isBlocked(blind)
if dz.data.blinds[blind] == nil then dz.data.blinds[blind] = {} end
dz.log("isBlocked = ".. tostring((tonumber(dz.data.blinds[blind].blockedUntil or 0)) > tonumber(os.date(os.time()))),dz.LOG_DEBUG)
return (tonumber(dz.data.blinds[blind].blockedUntil or 0) > tonumber(os.date(os.time())))
end
local function delta2Seconds(delta)
local maxUpTime = control.maxUpTime or maxBlindUpTime
local maxDownTime = control.maxDownTime or maxBlindDownTime
if delta > 0 then return "Up", math.abs(math.ceil(math.min((delta * maxUpTime / 100 ),maxUpTime))) end
return "Down" , math.abs(math.ceil(math.min((delta * maxDownTime / 100 ),maxDownTime)))
end
local function keepTrack(origin,targetLevel)
local tail, info
if item.level ~= nil then info = "; level to " .. item.level .. "%" -- when triggered by variable, there is no level
else if bTable.s then tail = " for " .. bTable.s .. " seconds" -- variable contain s (seconds)
else tail = "; level " .. bTable.p end -- variable contain p (position)
info = ", moving " .. bTable.d .. tail
end
dz.data.blinds[origin].levelTo = targetLevel
dz.data.blinds[origin].info = dz.data.blinds[origin].info or {}
dz.data.blinds[origin].info[dz.data.blinds[origin].direction] = dz.time.rawDate .. " " .. dz.time.rawTime .. info
end
local function newLevel(direction, duration, oldLevel, screenInversion)
logWrite("1 ---------")
logWrite(tostring(inverted))
local factor = 100 * screenInversion
local maxTime = control.maxUpTime or maxBlindUpTime
if direction ~= "Down" and not inverted then
factor = -1 * factor
maxTime = control.maxUpTime or maxBlindDownTime -- time in seconds for blind to go from fully closed to fully open
elseif direction ~= "Up" and inverted then
factor = -1 * factor
maxTime = control.maxDownTime or maxBlindDownTime -- time in seconds for blind to go from fully closed to fully open
end
return dz.utils.round(math.min(math.max(oldLevel + ( factor * duration / maxTime ),0),100))
end
local function delayedURL(callback,seconds)
callback = "nodemcu_" .. callback
local url = dz.settings['Domoticz url'] .. "/json.htm?type=command¶m=addlogmessage&message=" ..
callback .. "%20Scheduled%20for%20after%20" .. seconds .. "%20seconds."
dz.openURL ({ url = url , method = "GET", callback = callback,}).afterSec(seconds)
end
local function makeTableFromVar(str)
local bTable = {}
bTable.n = item.value:match("[a-zA-Z0-9_]+") -- blind name
bTable.d = item.value:match(";[A-Z][a-z]+"):sub(2) -- direction
local seconds = item.value:gsub(bTable.n .. ";" .. bTable.d .. ";","")
bTable.s = tonumber( seconds )
logWrite("Seconds: " .. bTable.s)
return bTable
end
local function osExecute(cmd)
logWrite("command for osEexecute: ".. cmd)
local fileHandle = assert(io.popen(cmd, 'r'))
local commandOutput = assert(fileHandle:read('*a'))
local returnTable = {fileHandle:close()}
logWrite("commandOutput: " .. commandOutput)
logWrite("returncode : " .. returnTable[3])
return commandOutput,returnTable[3] -- rc[3] contains returnCode
end
local function sendMQTT(nodemcu,blind,direction,seconds)
local seconds = tonumber(seconds) or 0
local baseMQTT = "mosquitto_pub -t " .. nodemcu .. "/" .. blind .. "_" .. direction .. " -m "
if seconds == 0 then
osExecute(baseMQTT .. "0" )
elseif seconds >= 1 then
osExecute(baseMQTT .. "1")
delayedURL(blind,seconds)
else
osExecute(baseMQTT .. "1")
osExecute("sleep 0.5")
osExecute(baseMQTT .. "0")
end
dz.data.blinds[blind].nodemcu = nodemcu
dz.data.blinds[blind].direction = direction
end
local function initPersistentBlind(blind)
dz.data.blinds[blind] = dz.data.blinds[blind] or {}
end
local function Response2Parms(str)
str = str:gsub("nodemcu_","")
return dz.data.blinds[str].nodemcu, str, dz.data.blinds[str].direction
end
local function setLevelAfterInterrupt(blind)
-- When a blind action is interrupted, the new level should take this into acount
local deltaLevel = dz.data.blinds[blind].levelFrom - dz.data.blinds[blind].levelTo
local deltaTime = dz.data.blinds[blind].blockedUntil - dz.data.blinds[blind].blockedFrom
local newTime = entryTime - dz.data.blinds[blind].blockedFrom
local newLevel = dz.utils.round(dz.data.blinds[blind].levelFrom - newTime / deltaTime * deltaLevel )
dz.devices(blind).dimTo(newLevel).silent()
dz.data.blinds[blind].blockedUntil = os.date(os.time()) -- unblock blind
dz.data.blinds[blind].levelTo = newLevel
end
local function isCut(silent)
local closed = 99
local opened = 1
if item.state == "Closed" then
item.dimTo(closed)
return true
elseif item.state == "Open" then
item.dimTo(opened)
return true
elseif item.level == 100 then
if inverted then
item.dimTo(opened)
else
item.dimTo(closed)
end
return true
elseif item.level == 0 then
if inverted then
item.dimTo(closed)
else
item.dimTo(opened)
end
return true
end
return false
end
local function handleBlind(blind)
initPersistentBlind(blind)
control = dz.utils.fromJSON(dz.devices(blind).description)
local targetLevel
if isBlocked(blind) then
dz.log("Blind ".. blind .. " is active; Stopping now",dz.LOG_DEBUG)
sendMQTT(control.nodemcu,blind,"Up",0)
sendMQTT(control.nodemcu,blind,"Down",0)
setLevelAfterInterrupt(blind)
return
else
blockBlind(blind,bTable.s,control.nodemcu)
end
local factor = 1
if inverted then factor = -1 end
targetLevel = newLevel(bTable.d,bTable.s,dz.devices(blind).level,factor)
dz.devices(blind).dimTo(targetLevel).silent()
sendMQTT(control.nodemcu,blind,bTable.d,bTable.s)
keepTrack(blind,targetLevel)
end
local function dzHandleBlind(blindName)
local blind = dz.devices(blindName)
local control = dz.utils.fromJSON(blind.description)
local direction
local delta = control.maxUpTime or maxBlindUpTime
if not(isBlocked(blindName)) then -- too Quick
if isCut() then
dumpPersist()
return
end
if dz.data.blinds[blindName].levelTo == 1 then
direction, delta = delta2Seconds(blind.lastLevel - 1)
direction = "Up"
elseif dz.data.blinds[blindName].levelTo == 99 then
direction, delta = delta2Seconds(blind.lastLevel - 99)
direction = "Down"
else
direction, delta = delta2Seconds(blind.lastLevel - blind.level)
end
dumpPersist()
logWrite("lastLevel: " .. blind.lastLevel)
logWrite("level: " .. blind.level)
logWrite("direction: " .. direction)
logWrite("delta: " .. delta)
sendMQTT(control.nodemcu,blindName,direction,delta)
blockBlind(blindName,delta,"dzVents")
else
dz.log("Not enough time (still blocked) ...", dz.LOG_DEBUG)
blind.dimTo(blind.lastLevel).silent()
return
end
keepTrack(blind.name,blind.level) -- We are here because blind was set in domoticz so blind.level is targetLevel
end
--- Main code
if item.isHTTPResponse then -- Used for switching relais off only
local nodemcu,blind,direction = Response2Parms(item.trigger)
sendMQTT(nodemcu,blind,direction,0)
elseif item.isVariable then -- triggered by nodemcu
bTable = makeTableFromVar(item.value)
inverted = dz.devices(bTable.n).switchType == "Blinds Percentage Inverted"
if bTable.n ~= "ALLBLINDS" then
blinds2Handle = {bTable.n}
else
blinds2Handle = allBlinds
end
for i = 1,#blinds2Handle do
handleBlind(blinds2Handle[i])
logWrite(blinds2Handle[i])
end
else -- triggered by device
local inverted = item.switchType == "Blinds Percentage Inverted"
if item.name == "blind_Master" then
if isCut() then return end
for i = 1,#allBlinds do
dz.devices(allBlinds[i]).dimTo(math.max(math.min(item.level,99),1))
end
else
if isCut() then
return
end
dzHandleBlind(item.name)
end
end
end
}Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Who is online
Users browsing this forum: No registered users and 1 guest