Add a switch to remove the planning. Fix issue #1
This commit is contained in:
63
plugin.py
63
plugin.py
@@ -5,14 +5,13 @@
|
|||||||
|
|
||||||
#pylint: disable=line-too-long, invalid-name, undefined-variable, global-at-module-level
|
#pylint: disable=line-too-long, invalid-name, undefined-variable, global-at-module-level
|
||||||
"""
|
"""
|
||||||
<plugin key="Hygrostat" name="Hygrostat" author="fjumelle" version="1.0.0" wikilink="" externallink="">
|
<plugin key="Hygrostat" name="Hygrostat" author="fjumelle" version="2.0.0" wikilink="" externallink="">
|
||||||
<description>
|
<description>
|
||||||
<h2>Hygrostat</h2><br/>
|
<h2>Hygrostat</h2><br/>
|
||||||
Implementation of an hygrostat as a Domoticz Plugin.<br/>
|
Implementation of an hygrostat as a Domoticz Plugin.
|
||||||
Planning shall be configure like that: '[Monday]/.../[Sunday]' where each day is defined with 'Start-End' (Start and End format is HH:mm).
|
|
||||||
</description>
|
</description>
|
||||||
<params>
|
<params>
|
||||||
<param field="Address" label="Domoticz IP Address" width="200px" required="true" default="127.0.0.1"/>
|
<param field="Address" label="Domoticz IP Address" width="200px" required="true" default="localhost"/>
|
||||||
<param field="Port" label="Port" width="40px" required="true" default="8080"/>
|
<param field="Port" label="Port" width="40px" required="true" default="8080"/>
|
||||||
<param field="Username" label="Domoticz Username" width="200px" required="false" default=""/>
|
<param field="Username" label="Domoticz Username" width="200px" required="false" default=""/>
|
||||||
<param field="Password" label="Domoticz Password" width="200px" required="false" default="" password="true"/>
|
<param field="Password" label="Domoticz Password" width="200px" required="false" default="" password="true"/>
|
||||||
@@ -20,7 +19,6 @@
|
|||||||
<param field="Mode2" label="In/Out idx" width="200px"/>
|
<param field="Mode2" label="In/Out idx" width="200px"/>
|
||||||
<param field="Mode3" label="Rule" width="600px"/>
|
<param field="Mode3" label="Rule" width="600px"/>
|
||||||
<param field="Mode4" label="Min duration (min)" width="200px"/>
|
<param field="Mode4" label="Min duration (min)" width="200px"/>
|
||||||
<param field="Mode5" label="Planning" width="600px"/>
|
|
||||||
<param field="Mode6" label="Logging Level" width="200px">
|
<param field="Mode6" label="Logging Level" width="200px">
|
||||||
<options>
|
<options>
|
||||||
<option label="Normal" value="0" default="true"/>
|
<option label="Normal" value="0" default="true"/>
|
||||||
@@ -47,6 +45,8 @@ DEFAULT_POOLING = 30 #multiple of 15 sec
|
|||||||
DEFAULT_DURATION = 30
|
DEFAULT_DURATION = 30
|
||||||
DEFAULT_RULE = "h_in > 70"
|
DEFAULT_RULE = "h_in > 70"
|
||||||
|
|
||||||
|
DEVICE_UNIT = 1 #Id of the device crerated by the module
|
||||||
|
|
||||||
class BasePlugin(object):
|
class BasePlugin(object):
|
||||||
"""Base class"""
|
"""Base class"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -67,8 +67,6 @@ class BasePlugin(object):
|
|||||||
self.rule = False
|
self.rule = False
|
||||||
# Min duration (min)
|
# Min duration (min)
|
||||||
self.min_duration = DEFAULT_DURATION
|
self.min_duration = DEFAULT_DURATION
|
||||||
# Planning
|
|
||||||
self.planning = [("00:00", "23:59"), ("00:00", "23:59"), ("00:00", "23:59"), ("00:00", "23:59"), ("00:00", "23:59"), ("00:00", "23:59"), ("00:00", "23:59")] # From Monday to Sunday
|
|
||||||
# Current mode
|
# Current mode
|
||||||
self.mode = False #Off
|
self.mode = False #Off
|
||||||
# Last time rule is True or switch manually on
|
# Last time rule is True or switch manually on
|
||||||
@@ -122,20 +120,22 @@ class BasePlugin(object):
|
|||||||
duration = DEFAULT_DURATION
|
duration = DEFAULT_DURATION
|
||||||
self.min_duration = duration
|
self.min_duration = duration
|
||||||
|
|
||||||
# Read planning
|
#Create the device(s) if needed
|
||||||
self.planning = []
|
if DEVICE_UNIT not in Devices:
|
||||||
for day in Parameters["Mode5"].split("/"):
|
#Create the Pause device
|
||||||
start_end = day.split("-", 1)
|
Domoticz.Device(Unit=DEVICE_UNIT,
|
||||||
self.planning.append((start_end[0], start_end[1]))
|
Name="Pause",
|
||||||
if len(self.planning) != 7:
|
TypeName="Switch",
|
||||||
raise ValueError("Incorrect planning...")
|
Image=9,
|
||||||
|
Used=1
|
||||||
|
).Create()
|
||||||
|
|
||||||
|
|
||||||
def onHeartbeat(self): #NOSONAR
|
def onHeartbeat(self): #NOSONAR
|
||||||
"""Plugin heartbeat"""
|
"""Plugin heartbeat"""
|
||||||
if self.pooling_current_step == self.pooling_steps:
|
if self.pooling_current_step == self.pooling_steps:
|
||||||
#Now
|
#Now
|
||||||
now = time.time()
|
now = time.time()
|
||||||
weekday = datetime.today().weekday()
|
|
||||||
|
|
||||||
# Get device values
|
# Get device values
|
||||||
n_in, t_in, h_in, dp_in, lu_in = get_temp_devide_info(self.in_id)
|
n_in, t_in, h_in, dp_in, lu_in = get_temp_devide_info(self.in_id)
|
||||||
@@ -162,7 +162,7 @@ class BasePlugin(object):
|
|||||||
if check_rule(self.rule, t_in, h_in, dp_in, lu_in, t_out, h_out, dp_out, lu_out, self.histo_hum):
|
if check_rule(self.rule, t_in, h_in, dp_in, lu_in, t_out, h_out, dp_out, lu_out, self.histo_hum):
|
||||||
self.mode = True #On
|
self.mode = True #On
|
||||||
#We also keep the time, but only if in the authorized time range
|
#We also keep the time, but only if in the authorized time range
|
||||||
if is_between(time.strftime("%H:%M", time.localtime(now)), self.planning[weekday]):
|
if Devices[DEVICE_UNIT].nValue == 0:
|
||||||
self.last_time = now
|
self.last_time = now
|
||||||
Domoticz.Debug("Condition satisfied ==> ON")
|
Domoticz.Debug("Condition satisfied ==> ON")
|
||||||
Domoticz.Debug(f"Start delay={now}")
|
Domoticz.Debug(f"Start delay={now}")
|
||||||
@@ -175,10 +175,9 @@ class BasePlugin(object):
|
|||||||
|
|
||||||
if self.mode:
|
if self.mode:
|
||||||
#Switch 'On' immediately if not the time range
|
#Switch 'On' immediately if not the time range
|
||||||
if is_between(time.strftime("%H:%M", time.localtime(now)), self.planning[weekday]):
|
if Devices[DEVICE_UNIT].nValue == 0 and self.mode != s_sw:
|
||||||
if self.mode != s_sw:
|
print_status(self.in_id, n_in, t_in, h_in, dp_in, self.histo_hum, self.out_id, n_out, t_out, h_out, dp_out)
|
||||||
print_status(self.in_id, n_in, t_in, h_in, dp_in, self.histo_hum, self.out_id, n_out, t_out, h_out, dp_out)
|
switch_on_off(self.switch_id, self.mode)
|
||||||
switch_on_off(self.switch_id, self.mode)
|
|
||||||
elif not self.mode and now - self.last_time > self.min_duration*60:
|
elif not self.mode and now - self.last_time > self.min_duration*60:
|
||||||
#Switch 'Off' only after the delay
|
#Switch 'Off' only after the delay
|
||||||
if self.mode != s_sw:
|
if self.mode != s_sw:
|
||||||
@@ -197,6 +196,20 @@ class BasePlugin(object):
|
|||||||
else:
|
else:
|
||||||
self.pooling_current_step = self.pooling_current_step + 1
|
self.pooling_current_step = self.pooling_current_step + 1
|
||||||
|
|
||||||
|
def onCommand(self, Unit, Command, Level, Color): #pylint: disable=unused-argument #NOSONAR
|
||||||
|
"""Plugin command"""
|
||||||
|
Domoticz.Debug(f"onCommand called for Unit {Unit}: Command '{Command}', Level: {Level}")
|
||||||
|
|
||||||
|
if Unit == DEVICE_UNIT: # pause switch
|
||||||
|
svalue = str(Command)
|
||||||
|
if str(Command) == "On":
|
||||||
|
nvalue = 1
|
||||||
|
else:
|
||||||
|
nvalue = 0
|
||||||
|
|
||||||
|
Devices[Unit].Update(nValue=nvalue, sValue=svalue)
|
||||||
|
|
||||||
|
|
||||||
global _plugin
|
global _plugin
|
||||||
_plugin = BasePlugin()
|
_plugin = BasePlugin()
|
||||||
|
|
||||||
@@ -208,6 +221,10 @@ def onHeartbeat(): #NOSONAR
|
|||||||
"""Plugin heartbeat"""
|
"""Plugin heartbeat"""
|
||||||
_plugin.onHeartbeat()
|
_plugin.onHeartbeat()
|
||||||
|
|
||||||
|
def onCommand(Unit, Command, Level, Color): #NOSONAR
|
||||||
|
"""Plugin command"""
|
||||||
|
_plugin.onCommand(Unit, Command, Level, Color)
|
||||||
|
|
||||||
def get_temp_devide_info(idx):
|
def get_temp_devide_info(idx):
|
||||||
"""Get data from temp/hum devide idx"""
|
"""Get data from temp/hum devide idx"""
|
||||||
res = domoticz_api(f"type=devices&rid={idx}")
|
res = domoticz_api(f"type=devices&rid={idx}")
|
||||||
@@ -251,12 +268,6 @@ def check_rule(exp, t_in, h_in, dp_in, lu_in, t_out, h_out, dp_out, lu_out, hist
|
|||||||
Domoticz.Debug(f"Check rule: {exp} ==> {res}")
|
Domoticz.Debug(f"Check rule: {exp} ==> {res}")
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def is_between(time_current, time_range):
|
|
||||||
"""Check if time_current is in the time range"""
|
|
||||||
if time_range[1] < time_range[0]:
|
|
||||||
return time_current >= time_range[0] or time_current < time_range[1]
|
|
||||||
return time_range[0] <= time_current < time_range[1]
|
|
||||||
|
|
||||||
def print_status(idx_in, n_in, t_in, h_in, dp_in, histo_h_in, idx_out, n_out, t_out, h_out, dp_out):
|
def print_status(idx_in, n_in, t_in, h_in, dp_in, histo_h_in, idx_out, n_out, t_out, h_out, dp_out):
|
||||||
"""Print indoor/outdoor status"""
|
"""Print indoor/outdoor status"""
|
||||||
Domoticz.Status(f"Indoor (#{idx_in}): {n_in} / T={t_in}°C / H={h_in}% ({histo_h_in}) / DP={dp_in:.1f}°C")
|
Domoticz.Status(f"Indoor (#{idx_in}): {n_in} / T={t_in}°C / H={h_in}% ({histo_h_in}) / DP={dp_in:.1f}°C")
|
||||||
|
|||||||
Reference in New Issue
Block a user