First thing: after following your .trigger
hint, i can see in the logs that the CronTrigger
gets scheduled correctly AND is executed, so the rule works correctly again. Thank you!
For the sake of completion:
from core.rules import rule
from core.triggers import CronTrigger
import org.joda.time.DateTime as DateTime
import org.joda.time.Minutes as Minutes
from org.eclipse.smarthome.model.persistence.extensions import PersistenceExtensions as pe
# Regel zum Auswerten der Stromzaehler
GESAMT = 'Stromzaehler_Gesamt'
HEIZUNG = 'Stromzaehler_Heizung'
GESAMT_WATT = 'Stromzaehler_Gesamt_Watt'
HEIZUNG_WATT = 'Stromzaehler_Heizung_Watt'
GESAMT_AVG10 = 'Stromzaehler_Gesamt_AVG10'
HEIZUNG_AVG10 = 'Stromzaehler_Heizung_AVG10'
@rule("Stromzaehler Rule")
class StromzaehlerRule(object):
def __init__(self):
self._heizung_itm = ir.getItem(HEIZUNG)
self._gesamt_itm = ir.getItem(GESAMT)
self._heizung_watt_itm = ir.getItem(HEIZUNG_WATT)
self._gesamt_watt_itm = ir.getItem(GESAMT_WATT)
self._heizung_avg10_itm = ir.getItem(HEIZUNG_AVG10)
self._gesamt_avg10_itm = ir.getItem(GESAMT_AVG10)
def getEventTriggers(self):
return [
CronTrigger('58 * * * * ?', triggerName='StromzaehlerRuleTrigger').trigger
]
def execute(self, module, inputs):
pow_ges = self.calcPower(self._gesamt_itm)
pow_hz = self.calcPower(self._heizung_itm)
events.sendCommand(self._gesamt_watt_itm, str(pow_ges))
events.sendCommand(self._heizung_watt_itm, str(pow_hz))
avg_hz = self.calcPowerAVG10(self._heizung_watt_itm)
avg_ges = self.calcPowerAVG10(self._gesamt_watt_itm)
events.sendCommand(self._heizung_avg10_itm, str(avg_hz))
events.sendCommand(self._gesamt_avg10_itm, str(avg_ges))
def calcPower(self, item):
curVal = item.state.intValue() if hasattr(item.state, 'intValue') else 0
curTime = DateTime.now()
hist = pe.historicState(item, DateTime.now())
histVal = hist.state
histTime = DateTime(hist.timestamp)
self.log.debug("Current state of item {}: {}, Historic state: {} at {}".format(item.name, curVal, histVal, histTime))
timeDiff = Minutes.minutesBetween(curTime, histTime).getMinutes()
if (timeDiff < 1): timeDiff = 1
power = 0.0
diff = curVal - histVal.intValue()
if (diff > 0):
power = diff * (60.0 / timeDiff)
self.log.debug("Difference ticks: {}, min: {}, Power: {}".format(diff, timeDiff, power))
return power
def calcPowerAVG10(self, item):
return pe.averageSince(item, DateTime.now().minusMinutes(10))
That’s the rule right now - working
To test, i commented the whole getEventTriggers(self)
function and added the following decorator right after @rule
before the classname:
@when("Time cron 58 * * * * ?")
which yields the following log entry:
2019-08-04 09:46:31.043 [INFO ] [rt.internal.loader.ScriptFileWatcher] - Loading script 'python/personal/090_stromzaehler.py'
2019-08-04 09:46:31.268 [DEBUG] [jsr223.jython.core.triggers ] - when: target=[Time cron 58 * * * * ?], target_type=Time, trigger_target=cron, trigger_type=58 * * * * ?, old_state=None, new_state=None
2019-08-04 09:46:31.277 [DEBUG] [jsr223.jython.core.triggers ] - when: Created cron_trigger: [Time_cron_58_]
2019-08-04 09:46:31.308 [DEBUG] [jsr223.jython.core.rules ] - Added rule [Stromzaehler Rule]
2019-08-04 09:46:31.328 [DEBUG] [rt.internal.loader.ScriptFileWatcher] - Script loaded: python/personal/090_stromzaehler.py
But it does NOT get executed - nothing in the logs afterwards (not even an error).
How does the decorator figure out which function to execute in the class? Should it follow the same methodology as the @rule
decorator by using the execute(self, module, inputs)
method?
Best regards,
Alex
P.S.: Any comment on improving my code is more than welcome