Hi it’s me again. Question about converting some rules, that have a defined timer that I can cancel at later events.
Consider this:
rule "Door last close"
when
Item Dsc_Zone1_General_Status changed from OPEN to CLOSED or
Item Dsc_Zone2_General_Status changed from OPEN to CLOSED or
Item Dsc_Zone3_General_Status changed from OPEN to CLOSED
then
if(tAlarmCheck!==null) {
tAlarmCheck.cancel
tAlarmCheck = null
}
tAlarmCheck = createTimer(now.plusMinutes(5)) [|
postSlack.apply("Remember to set alarm!")
]
end
Everything time this rule runs, it will first check for existing instances of timer, cancel it then reset it.
In habapp, I can do self.run_at, but if the event got triggered in in less than 5 minutes, how do I cancel the previous scheduled event?
I understand there is a cancel function. However, I don’t understand how to “find” the scheduled callback and then cancel it.
Do I have to loop thru self.__future_events? Since it’s a private member, I don’t have any mean to access that.
For example,
class SomeRules(HABApp.Rule):
def __init__(self):
super().__init__()
self.listen_event("Dsc_Zone1_General_Status", self.__send_reminder, ItemStateChangedEvent)
self.listen_event("Dsc_Zone2_General_Status", self.__send_reminder, ItemStateChangedEvent)
self.listen_event("Dsc_Zone3_General_Status", self.__send_reminder, ItemStateChangedEvent)
def __send_reminder(self, event)
#if event already exists <-------------This part I don't know how to do????
ScheduledCallback.cancel()
self.run_at(
time=datetime.timedelta(seconds=600),
callback=somefunction
)
The part I can’t figure out is let say if Dsc_Zone1_General_Status triggers and scheduled a callback at 10 minutes later. Then Dsc_Zone2_General_Status triggers 5 minutes later. How do cancel the scheduled callback set by Dsc_Zone1_General_Status before scheduling another callback?
The rule is supposed to keep cancelling callbacks (or timers in Openhab Rules) and set new ones if any of those item triggers during the 10 minute scheduled time.
I have enjoyed reading about your project. Any thoughts on using your work as a means of adding extensions (“binding”) for OH? I have a couple of python projects that communicate with OH via MQTT and Homie. It doesn’t really work the way I would like. Reading your documentation, it should be possible to add items to OH, receive control events from OH and update the items from my code - correct?
Building wheels for collected packages: watchdog, ujson, voluptuous, pathtools
Building wheel for watchdog (setup.py) ... done
Stored in directory: C:\Users\mike\AppData\Local\pip\Cache\wheels\61\1d\d0\04cfe495619be2095eb8d89a31c42adb4e42b76495bc8f784c
Building wheel for ujson (setup.py) ... error
ERROR: Complete output from command 'c:\program files (x86)\python37-32\python.exe' -u -c 'import setuptools, tokenize;__file__='"'"'C:\\Users\\mike\\AppData\\Local\\Temp\\pip-install-9gihwnks\\ujson\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d 'C:\Users\mike\AppData\Local\Temp\pip-wheel-09ykeo7k' --python-tag cp37:
ERROR: Warning: 'classifiers' should be a list, got type 'filter'
running bdist_wheel
running build
running build_ext
building 'ujson' extension
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": https://visualstudio.microsoft.com/downloads/
----------------------------------------
ERROR: Failed building wheel for ujson
Running setup.py clean for ujson
Building wheel for voluptuous (setup.py) ... done
Stored in directory: C:\Users\mike\AppData\Local\pip\Cache\wheels\e8\e3\d0\a2d476b9cd09b8f5979789e0aaf07119726a3cfb19ee67aa1e
Building wheel for pathtools (setup.py) ... done
Stored in directory: C:\Users\mike\AppData\Local\pip\Cache\wheels\0b\04\79\c3b0c3a0266a3cb4376da31e5bfe8bba0c489246968a68e843
Successfully built watchdog voluptuous pathtools
Failed to build ujson
Installing collected packages: argh, pathtools, watchdog, ujson, aiohttp-sse-client, voluptuous, ruamel.yaml.clib, ruamel.yaml, HABApp
Running setup.py install for ujson ... error
ERROR: Complete output from command 'c:\program files (x86)\python37-32\python.exe' -u -c 'import setuptools, tokenize;__file__='"'"'C:\\Users\\mike\\AppData\\Local\\Temp\\pip-install-9gihwnks\\ujson\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\mike\AppData\Local\Temp\pip-record-btk0fvr5\install-record.txt' --single-version-externally-managed --compile:
ERROR: Warning: 'classifiers' should be a list, got type 'filter'
running install
running build
running build_ext
building 'ujson' extension
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": https://visualstudio.microsoft.com/downloads/
----------------------------------------
ERROR: Command "'c:\program files (x86)\python37-32\python.exe' -u -c 'import setuptools, tokenize;__file__='"'"'C:\\Users\\mike\\AppData\\Local\\Temp\\pip-install-9gihwnks\\ujson\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\mike\AppData\Local\Temp\pip-record-btk0fvr5\install-record.txt' --single-version-externally-managed --compile" failed with error code 1 in C:\Users\mike\AppData\Local\Temp\pip-install-9gihwnks\ujson\
WARNING: You are using pip version 19.1.1, however version 19.2.3 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
I haven’t dug in deep yet - just have played with the examples. My use will be different from what you have solved for - ie. I mostly want to interact with the REST interface to create items, update their state and receive command from OH to change items. Currently I am using MQTT/Homie ie. Python program -> MQTT -> OH and then back. It works but … So if I could have my python program communicate directly to OH that would be a big benefit and reduce complexity.
[2019-09-27 13:45:37,295] [ MyRule] INFO | HEMUpdate: item_state_update: Item HEM_P2 received update 737.201
[2019-09-27 13:45:37,295] [ MyRule] INFO | HEMLastUpdated: current timestamp: 2019-09-27 13:45:37.223000-04:00
[2019-09-27 13:45:37,297] [ MyRule] INFO | HEMLastUpdated: updated timestamp to : 2019-09-27 13:45:37.223000
But the date/time in the UI does not update. I notice the TZ info is missing, so I tried formatting it as a string, see if passing a string works, but so far no luck.
Any hints on how to update DateTime items in OH?
UPDATE:
OK my stupid, I thought that once I had the item, I could just update it. no I have to post it back to OH. So this works:
How can I tell what kind of item an OH item is? I see isinstance, but there are a limited number of Item types.
For example, how can I tell if an Item is a Number, String or DatetTime Item? These all seem to be just “Items”.
The issue is that some of my Items that display dates/times are strings, and some are DateTime Items.
I have a function in OH that checks the Item type, and if it’s a string returns a timestamp in a specified string format, otherwise it just returns a new DateTime Item, and leaves the formatting up to OH.
Here is my function:
val Functions$Function2<GenericItem, String, String> getTimestamp = [ //function (lambda) to get a timestamp. Returns formatted string and optionally updates an item
item,
date_format |
var date_time_format = date_format
if(date_format == "" || date_format === null) date_time_format = "%1$ta %1$tT" //default format Day Hour:Minute:Seconds
var String Timestamp = String::format( date_time_format, new Date() )
if(item != NULL && item !== null) {
var t = new DateTimeType()
if(item instanceof DateTimeItem) {
item.postUpdate(t) ////postUpdate(item, t)
logInfo("Last Update", item.name + " DateTimeItem updated at: " + Timestamp )
}
else if(item instanceof StringItem) {
item.postUpdate(Timestamp) //postUpdate(item, Timestamp)
logInfo("Last Update", item.name + " StringItem updated at: " + Timestamp )
}
else
logWarn("Last Update", item.name + " is not DateTime or String - not updating")
}
Timestamp
]
How would I implement this? I’m not sure how to identify it an item is a string or not (as opposed to a DateTime item).