Created
January 7, 2018 12:47
-
-
Save euphi/e56f2be0c88017d4cb97bc7c188957f6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Created on 09.10.2017 | |
@author: ian | |
''' | |
from openhab.log import logging | |
from openhab.triggers import time_triggered, EVERY_MINUTE, item_group_triggered | |
from org.openhab.core.items import ItemNotFoundException | |
import org.eclipse.smarthome.core.items.ItemNotFoundException | |
import time | |
from threading import _Timer | |
class PWMTimer(_Timer): | |
started_at = None | |
def start(self): | |
self.started_at = time.time() | |
_Timer.start(self) | |
def elapsed(self): | |
return time.time() - self.started_at | |
def remaining(self): | |
return self.interval - self.elapsed() | |
class PWM: | |
counter = 0 | |
myTimer = [None]*11 | |
# Map Counter ID to Heating name - MUST be adapted to the configured prefixes | |
# last (11) empty -> Spare | |
nameMapper = ["o1", "o2", "o", "u4", "u5", "u6", "o7", "o8", "o9", "o10", None] | |
def get_counter(self): | |
return self.counter | |
def inc_counter(self): | |
self.counter += 1 | |
if (self.counter >= 11): self.counter = 0 | |
def get_prefix(self): | |
return self.nameMapper[self.counter]+"_heat" | |
p = PWM() | |
@time_triggered(EVERY_MINUTE) | |
def check_pwm(): | |
plog = logging.getLogger("RULES.Heating.PWM") | |
p.inc_counter() | |
count = p.get_counter() | |
prefix = p.get_prefix() | |
plog.debug(u"PWM for Counter {} [{}]".format(count, prefix)) | |
item_auto = prefix+"_auto" | |
item_perc = prefix+"_percentage" | |
item_timer = prefix+"_timer" | |
def timerCB(arg): | |
try: | |
plog.info(u"Callback for Timer PWM%d" % (arg)) | |
events.sendCommand(item_timer, u"OFF") | |
except Exception as e: | |
plog.debug(unicode(e)) | |
try: | |
plog.debug(u"Getting item "+ item_auto) | |
automode = itemRegistry.getItem(item_auto) | |
plog.debug(u"Getting item "+ item_perc) | |
percentage = itemRegistry.getItem(item_perc) | |
plog.debug(u"Getting item "+ item_timer) | |
timer_item = itemRegistry.getItem(item_timer) | |
except org.eclipse.smarthome.core.items.ItemNotFoundException: | |
plog.warn(item_auto + u" not found") | |
return | |
if (automode.state == OFF): | |
plog.info(u"Automode for ID {} is off - nothing to do".format(count)) | |
return | |
perc = percentage.getState().intValue() | |
plog.info(u"Automode for ID {} with {}%".format(count, perc)) | |
duration = 60*4 * perc / 100 | |
if duration < 30: | |
plog.info("PWM timer less than 30 s - not switching on") | |
events.sendCommand(item_timer, OFF) | |
return | |
if duration > (60*4)-30: | |
plog.info("Duration equal or close to PWM cycle time - not starting timer, just switch valve on") | |
events.sendCommand(item_timer, ON) | |
return | |
p.myTimer[count]=PWMTimer(duration,timerCB, [count]) | |
p.myTimer[count].start() | |
plog.debug("Timer started for duration {}s [{}%]".format(duration, perc)) | |
events.sendCommand(item_timer, u"ON") | |
@item_group_triggered("heizung_pwm") | |
def switch_pwm(event): | |
plog = logging.getLogger("RULES.Heating.PWM.Switch") | |
item = event.getItemName() | |
prefix = item[:item.index("_")] | |
heizung_switch_item = prefix+"_heizung" | |
new_state = event.getItemState() | |
plog.debug("Prefix {}, Item {} [{}], State {} [{}]".format(prefix, heizung_switch_item, heizung_switch_item.__class__, new_state, new_state.__class__)) | |
events.sendCommand(heizung_switch_item, new_state) | |
@item_group_triggered("heizung_automatik") | |
@item_group_triggered("heizung_solltemp") | |
@item_group_triggered("temp_innen") | |
def therm_temp_changed(event): | |
plog = logging.getLogger("RULES.Heating.Thermostat") | |
item = event.getItemName() | |
prefix = item[:item.index("_")] | |
# Get related Item states | |
act_temp = prefix + "_temp" | |
set_temp = prefix+"_solltemp" | |
item_auto = prefix+"_heat_auto" | |
item_switch = prefix+"_heizung" | |
#C++-Code of ThermostatNode: | |
# const String mode_id[LAST] = { "Manual_ON", "Manual_OFF", "Auto_ON", "Auto_OFF" }; | |
item_mode = prefix+"_thermomode" | |
try: | |
plog.debug(u"Getting item "+ act_temp) | |
act_temp_value = itemRegistry.getItem(act_temp).getState() | |
plog.debug(u"Getting item "+ set_temp) | |
set_temp_value = itemRegistry.getItem(set_temp).getState() | |
plog.debug(u"Getting item "+ item_auto) | |
auto_mode = itemRegistry.getItem(item_auto).getState() | |
plog.debug(u"Getting item "+ item_switch) | |
switch_state = itemRegistry.getItem(item_switch).getState() | |
except org.eclipse.smarthome.core.items.ItemNotFoundException as e: | |
plog.warn(unicode(e)) | |
plog.warn(u"No or not all items found for prefix %s" % (prefix)) | |
return | |
plog.debug(u"Prefix %s: Ist: %s - Soll: %s - Zustand: %s [Automatik: %s]" % (prefix, unicode(act_temp_value), unicode(set_temp_value), unicode(switch_state), unicode(auto_mode))) | |
if auto_mode == OFF: | |
plog.debug(u"Automatik aus") | |
return | |
if set_temp_value > act_temp_value: | |
if switch_state == ON: | |
plog.debug(u"Bereits eingeschaltet") | |
return | |
plog.info(u"Schalte Heizung für %s ein.", prefix) | |
events.sendCommand(item_switch, u"ON") | |
events.sendCommand(item_mode, "Auto_ON") | |
elif (set_temp_value.floatValue()+0.1) < act_temp_value.floatValue(): | |
if switch_state == OFF: | |
plog.debug(u"Bereits ausgeschaltet") | |
return | |
plog.info(u"Schalte Heizung für %s aus.", prefix) | |
events.sendCommand(item_switch, u"OFF") | |
events.sendCommand(item_mode, "Auto_OFF") | |
else: | |
plog.debug(u"Im Hysterese-Bereich") | |
@item_group_triggered("heizung_automatik") | |
def therm_mode_changed(event): | |
plog = logging.getLogger("RULES.Heating.Mode") | |
item = event.getItemName() | |
prefix = item[:item.index("_")] | |
item_mode = prefix+"_thermomode" | |
item_switch = prefix+"_heizung" | |
item_auto = prefix+"_auto" | |
switch_state = itemRegistry.getItem(item_switch).getState() | |
auto_mode = itemRegistry.getItem(item_auto).getState() | |
plog.debug(u"Prefix %s: Zustand: %s [Automatik: %s]" % (prefix, unicode(switch_state), unicode(auto_mode))) | |
newModeStr = "Auto_" if auto_mode==ON else "Manual_" | |
newModeStr += "ON" if switch_state==ON else "OFF" | |
events.sendCommand(item_mode, newModeStr) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment