Python: PersistenceExtensions

Dear all,

I started to use PersistenceExtensions. Many methods are working, but I have an issue with methods that return DecimalType like ‘deltaSince’

value = PersistenceExtensions.sumSince​(ir.getItem("ITEMNAME"), ZonedDateTime.now().minusMinutes(60))

It returns in the log:
Cannot create PyString with non-byte value

How can I fix that?

Never used persistence like this myself, but work backwards from what data type the call returns and then find a way to convert that into something Jython can handle. I suspect you are getting some kind of Java structure back and you’ll need to pull out a certain property or use .toString().

Try logging the result of calling type() and passing your persistence call.

Hi Ivan,
tried somethong si,milar with str() and tested .toString(), too. Same result:
Cannot create PyString with non-byte value

Does anybody use this PersistenceExtensions?
My impression is that only a minority is using python in openhab at all.

Here is an example that I use and which works
OH3.1 Jython 2.7.2


from core.rules import rule
from core.triggers import when
import personal.util
reload(personal.util)
from core.actions import PersistenceExtensions
from core.log import logging, LOG_PREFIX
# OH2
#from org.joda.time import DateTime
from java.time import ZonedDateTime, ZoneId

LOG = logging.getLogger("{}.{}".format(LOG_PREFIX, rules_filename))
euroPerKwH = 0.2029  

@rule("Stromverbrauch des Vortages", description = u"Stromverbrauch des Vortages Entfeucheter - " + rules_filename) # description and tags are optional
@when("Time cron 0 0 0 1/1 * ?")
def Stromverbrauch_Vortag(event):
	MeterDayBegin = 0.0
	MeterDayEnd = 0.0
	MeterUse = 0.0

	# OH2
	#MeterDayBegin = PersistenceExtensions.historicState(ir.getItem("ZWaveNode2_PowerNode_ElectricMeterkWh"), DateTime.now().minusDays(1)).state
	#MeterDayEnd = PersistenceExtensions.historicState(ir.getItem("ZWaveNode2_PowerNode_ElectricMeterkWh"), DateTime.now()).state
	# OH3 --> das unten geht in OH2 nicht, weil "PersistenceExtensions" in OH2 nicht mit ZonedDateTime umgehen kann, in OH3 aber schon!
	MeterDayBegin = PersistenceExtensions.historicState(ir.getItem("ZWaveNode2_PowerNode_ElectricMeterkWh"), ZonedDateTime.now().minusDays(1)).state
	MeterDayEnd = PersistenceExtensions.historicState(ir.getItem("ZWaveNode2_PowerNode_ElectricMeterkWh"), ZonedDateTime.now()).state

	if MeterDayEnd >= MeterDayBegin:
		MeterUse = float(str(MeterDayEnd)) - float(str(MeterDayBegin))
	else:
		MeterUse = MeterDayEnd

	events.postUpdate(ir.getItem("ZWaveNode2_PowerNode_ElectricMeterkwH_Day"), MeterUse)
	LOG.info("powerusageDay fertig: %s", str(MeterUse))

@rule("Stromverbrauch des Vormonats", description = u"Stromverbrauch des Vormonats Entfeucheter - " + rules_filename) # description and tags are optional
@when("Time cron 0 0 0 * 1/1 ?")
def Stromverbrauch_Vormonat(event):
	MeterMonthUse = 0.0

	# OH2
	#MeterMonthUse = PersistenceExtensions.sumSince(ir.getItem("ZWaveNode2_PowerNode_ElectricMeterkwH_Day"), DateTime.now().minusDays(DateTime.now().getDayOfMonth()))
	# OH3 --> das unten geht in OH2 nicht, weil "PersistenceExtensions" in OH2 nicht mit ZonedDateTime umgehen kann, in OH3 aber schon!
	MeterMonthUse = PersistenceExtensions.sumSince(ir.getItem("ZWaveNode2_PowerNode_ElectricMeterkwH_Day"), ZonedDateTime.now().minusDays(ZonedDateTime.now().getDayOfMonth()))
	events.postUpdate(ir.getItem("ZWaveNode2_PowerNode_ElectricMeterkwH_Month"), MeterMonthUse)
	LOG.info("powerusageMonth fertig: %s", str(MeterMonthUse))

@rule("Gesamtverbrauch Entfeuchter", description = u"Gesamtstromverbrauch des Entfeucheters - " + rules_filename) # description and tags are optional
@when("Time cron 0 0 0 1/1 * ?")
def Stromverbrauch_Gesamt(event):
	MeterUseSum = 0.0

	# OH2
	#MeterUseSum = PersistenceExtensions.sumSince(ir.getItem("ZWaveNode2_PowerNode_ElectricMeterkwH_Day"), DateTime(2019, 3, 1, 0, 0, 0, 0))
	# OH3 --> das unten geht in OH2 nicht, weil "PersistenceExtensions" in OH2 nicht mit ZonedDateTime umgehen kann, in OH3 aber schon!
	MeterUseSum = PersistenceExtensions.sumSince(ir.getItem("ZWaveNode2_PowerNode_ElectricMeterkwH_Day"), ZonedDateTime.of ( 2019, 3, 1, 0, 0, 0, 000, ZoneId.of ( "Europe/Berlin" )))
	events.postUpdate(ir.getItem("ZWaveNode2_PowerNode_ElectricMeterkWhSum"), MeterUseSum)
	LOG.info("powerusageSum fertig: %s", str(MeterUseSum))

2 Likes

Thank you Andi!
This is wokring for me. I didn’t found the issue in my code, but I adapted your approach to my needs.
And it was really interesting to see how you calculate you power consumption in this rule, because I try to find a good concept for that, too.

Hello Jan,

most of the code I got from the forum, I then adapted it to my needs. Look also here: [SOLVED] Using deltaSince to get data for every day of the week

Glad that it’s working, but like I said in my earlier post you need to determine what the persistence call is returning using type() so that we can determine how to handle it.

PersistenceExtensionsType = type(PersistenceExtensions.sumSince(ir.getItem("ZWaveNode2_PowerNode_ElectricMeterkwH_Day"), ZonedDateTime.now().minusDays(ZonedDateTime.now().getDayOfMonth())))
LOG.info("PersistenceExtensionsType: {}".format(PersistenceExtensionsType))

2021-08-09 19:27:49.316 [INFO ] [jsr223.jython.test.py               ] - PersistenceExtensionsType: <type 'org.openhab.core.library.types.DecimalType'>

Ah, that explains why Jython doesn’t know how to get a value from it. That data type is a custom one used by openHAB. You can use the method .intValue() or .floatValue() to get a value that Jython will know what to do with.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.