Hey DSL Rules Specilists,
I have a json string stored in a string item. i would like to iterate over all elements/tuples. the length (count of tuples) is not fixed. can this be achieved with dsl rules ?
somthing like:
for obj in transform(“JSONPATH”, “$.schedules”, json)
in a rule i would like to iterate over the elements to control e.g. my battery…
with that informations several items are set, but differnty depending on “mode”
Another way to put it is that your Item state has no elements, it is just a string so far as rules are concerned.
In DSL rules, you could split that out into an array of substrings for further parsing etc.,but there is no native JSON handling.
Or you might use another rules language, like javascript with its inbuilt JSON capabilities.
There is no way to get the keys out of the json using the version of jsonpath that is used by OH. It looks like you may know what the possible keys may be though, so you can make your own list to iterate over…
val KEYS = newArrayList("mode", "acPowerIn", "acPowerInMin", "acPowerInMax", "acPowerOut", "thisDoesNotExistInTheCurrentData")
val TEST_DATA = '{"mode": "auto", "acPowerIn": 3000, "acPowerInMin": 200, "acPowerInMax": 3680, "acPowerOut": 3000}'
for (key: KEYS) {
val RESULT = transform("JSONPATH", "$." + key, TEST_DATA)
if (RESULT != TEST_DATA) {
logWarn("Test", "{}: {}", key, RESULT)
}
}
Using a real scripting language, like Jython, you can easily convert to json and iterate through the keys. The logging will be simpler in a rule, but…
import json
from core.log import logging, LOG_PREFIX#, log_traceback
LOG = logging.getLogger("{}.TEST_3".format(LOG_PREFIX))
TEST = '{"mode": "auto", "acPowerIn": 3000, "acPowerInMin": 200, "acPowerInMax": 3680, "acPowerOut": 3000}'
CONVERTED_TO_JSON = json.loads(TEST)
for key, value in CONVERTED_TO_JSON.iteritems():
LOG.warn("{}: {}".format(key, value))
thank you for your input, i played around with all your hints. my goal was to have a more or less compatible solution for DSL Rules, scripting and grafana (postgres). grafana to graph the settings…
Well that helps! Functionally, everything looks good to me, except…
… you can’t get a historicState from a time in the future . If it doesn’t throw an error, then it must be returning the current state. Why not just use the state of mqtt_topic_ems_battery_activeLoadProfile?
Instead of the while loop, you could do…
(0..arLength - 1).forEach[i|
While not necessary, it is bets to use parameterized logging…
I’ve never tried that. Surprised it does not throw an error, but can see how it works … historicState() will return the newest record at, or from before, the given time. Makes sense that a future date that would return the very newest record from db (which may or may not be the same as current state).
the json is calculated outside openhab and written directly to the database. with historicstate i cyclic fetch the value from database…
the dataset are aligned to 1/4-hour. i call the rule each 5 minute, without the additional 10 seconds, rule execution at the 1/4-hour will not retrieve the related value… i don’t know why
after updating solarforecast/market proces, i would like to calculate an loadprofile for the future 1/4-Hour intervals and i need some future calculations, as you mentioned, future calculations might be difficult in OH, isn’t it ?
Probably, but it won’t be easy at all.
The difficulty you are up against is that openHAB is a home automation system, not crafted for extensive statistical analysis etc.
The good news is that openHAB provides lots of ways to interface with other more specialist tools - like Grafana or MySQL.