How to read a device's schedule (timer) in dzVents  [Solved]

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
jefft
Posts: 75
Joined: Monday 23 January 2017 23:30
Target OS: Linux
Domoticz version: 2023.1
Location: UK
Contact:

How to read a device's schedule (timer) in dzVents

Post by jefft »

Is there a way to read a device's schedule - i.e., to iterate through the times and values set via the domoticz UI timers page - in dzVents?

I'm building a heating control algorithm and I'd like to use thermostat setpoint devices with scheduled changes to control the thing.

Thanks!
Domoticz, Z-Stick Gen.5, zzh Zigbee, rxftrx433XL on Ubuntu 22.04, HP 290 G1.
Node Red, MQTT, 80+ Z-wave, ESP8266 & Shelly, handful of Zigbee bulbs. EMS-ESP gateway for Bosch boiler. Controlicz, until it dies :-(
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: How to read a device's schedule (timer) in dzVents

Post by waaren »

jefft wrote: Tuesday 08 September 2020 17:52 Is there a way to read a device's schedule - i.e., to iterate through the times and values set via the domoticz UI timers page - in dzVents?
Not with a native dzVents command but you can get all timers for a device with an API call

Code: Select all

http://<domoticz IP:domoticz PORT>/json.htm?idx=<device ID>&type=timers
or

Code: Select all

 http://<domoticz IP:domoticz PORT>/json.htm?idx=<device ID>&type=setpointtimers
or (for all devices)

Code: Select all

http://<domoticz IP:domoticz PORT>/json.htm?type=schedules
it will return something like
Spoiler: show

Code: Select all

{
"result": [
{
"Active": "true",
"Cmd": 0,
"Color": "",
"Date": "",
"Days": 128,
"Level": 100,
"MDay": 0,
"Month": 0,
"Occurence": 0,
"Randomness": "false",
"Time": "00:00",
"Type": 0,
"idx": "1"
},
{
"Active": "true",
"Cmd": 0,
"Color": "",
"Date": "",
"Days": 128,
"Level": 100,
"MDay": 0,
"Month": 1,
"Occurence": 0,
"Randomness": "false",
"Time": "01:00",
"Type": 12,
"idx": "3"
}
],
"status": "OK",
"title": "Timers"
}
or
Spoiler: show

Code: Select all

{
"result": [
{
"Active": "true",
"Date": "",
"Days": 128,
"MDay": 0,
"Month": 0,
"Occurence": 0,
"Temperature": 12,
"Time": "00:00",
"Type": 0,
"idx": "1"
},
{
"Active": "true",
"Date": "",
"Days": 512,
"MDay": 0,
"Month": 0,
"Occurence": 0,
"Temperature": 13,
"Time": "00:06",
"Type": 2,
"idx": "2"
},
{
"Active": "true",
"Date": "",
"Days": 256,
"MDay": 0,
"Month": 0,
"Occurence": 0,
"Temperature": 14,
"Time": "00:01",
"Type": 2,
"idx": "3"
},
{
"Active": "true",
"Date": "",
"Days": 256,
"MDay": 0,
"Month": 0,
"Occurence": 0,
"Temperature": 21,
"Time": "00:02",
"Type": 2,
"idx": "4"
}
],
"status": "OK",
"title": "SetpointTimers"
}
or
Spoiler: show

Code: Select all

{
"result": [
{
"Active": "true",
"Color": "",
"Date": "",
"Days": 128,
"DevName": "switch 1",
"DeviceRowID": 1,
"IsThermostat": "false",
"Level": 100,
"MDay": 0,
"Month": 0,
"Occurence": 0,
"Randomness": "false",
"ScheduleDate": "2020-09-09 07:02:00",
"Time": "00:00",
"TimerCmd": 0,
"TimerID": 1,
"TimerType": 0,
"TimerTypeStr": "Before Sunrise",
"Type": "Device"
},
{
"Active": "true",
"Color": "",
"Date": "",
"Days": 128,
"DevName": "switch 1",
"DeviceRowID": 1,
"IsThermostat": "false",
"Level": 100,
"MDay": 0,
"Month": 1,
"Occurence": 0,
"Randomness": "false",
"ScheduleDate": "",
"Time": "01:00",
"TimerCmd": 0,
"TimerID": 3,
"TimerType": 12,
"TimerTypeStr": "Yearly",
"Type": "Device"
},
{
"Active": "true",
"Date": "",
"Days": 128,
"DevName": "thermostat1",
"DeviceRowID": 43,
"IsThermostat": "true",
"MDay": 0,
"Month": 0,
"Occurence": 0,
"ScheduleDate": "2020-09-09 07:02:00",
"Temperature": "12.0",
"Time": "00:00",
"TimerID": 1,
"TimerType": 0,
"TimerTypeStr": "Before Sunrise",
"Type": "Device"
},
{
"Active": "true",
"Date": "",
"Days": 256,
"DevName": "thermostat1",
"DeviceRowID": 43,
"IsThermostat": "true",
"MDay": 0,
"Month": 0,
"Occurence": 0,
"ScheduleDate": "2020-09-09 00:01:00",
"Temperature": "14.0",
"Time": "00:01",
"TimerID": 3,
"TimerType": 2,
"TimerTypeStr": "On Time",
"Type": "Device"
},
{
"Active": "true",
"Date": "",
"Days": 127,
"DevName": "thermostat1",
"DeviceRowID": 43,
"IsThermostat": "true",
"MDay": 0,
"Month": 0,
"Occurence": 0,
"ScheduleDate": "2020-09-09 00:02:00",
"Temperature": "21.0",
"Time": "00:02",
"TimerID": 4,
"TimerType": 2,
"TimerTypeStr": "On Time",
"Type": "Device"
},
{
"Active": "true",
"Date": "",
"Days": 128,
"DevName": "thermostat1",
"DeviceRowID": 43,
"IsThermostat": "true",
"MDay": 7,
"Month": 11,
"Occurence": 0,
"ScheduleDate": "2020-11-07 00:02:00",
"Temperature": "21.0",
"Time": "00:02",
"TimerID": 5,
"TimerType": 12,
"TimerTypeStr": "Yearly",
"Type": "Device"
},
{
"Active": "true",
"Date": "",
"Days": 512,
"DevName": "thermostat1",
"DeviceRowID": 43,
"IsThermostat": "true",
"MDay": 0,
"Month": 0,
"Occurence": 0,
"ScheduleDate": "2020-09-09 00:06:00",
"Temperature": "13.0",
"Time": "00:06",
"TimerID": 2,
"TimerType": 2,
"TimerTypeStr": "On Time",
"Type": "Device"
}
],
"status": "OK",
"title": "Schedules"
}
And this can be relatively simple interpreted by a dzVents script
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
jefft
Posts: 75
Joined: Monday 23 January 2017 23:30
Target OS: Linux
Domoticz version: 2023.1
Location: UK
Contact:

Re: How to read a device's schedule (timer) in dzVents

Post by jefft »

Ah, the old parse-the-JSON routine. Thanks waaren, I'll give that a go :-)
Domoticz, Z-Stick Gen.5, zzh Zigbee, rxftrx433XL on Ubuntu 22.04, HP 290 G1.
Node Red, MQTT, 80+ Z-wave, ESP8266 & Shelly, handful of Zigbee bulbs. EMS-ESP gateway for Bosch boiler. Controlicz, until it dies :-(
lost
Posts: 699
Joined: Thursday 10 November 2016 9:30
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: How to read a device's schedule (timer) in dzVents

Post by lost »

jefft wrote: Wednesday 09 September 2020 12:33 Ah, the old parse-the-JSON routine. Thanks waaren, I'll give that a go :-)
Already used this for global (in)validate of schedules per device name (with possible wildcards,quite easy if you have a common naming prefix for your devices , like "heaterSomething" here). Maybe easier in Python indeed.

There is IMO 2 missing features in Domoticz for shedules:
-This capacity to (in)validate them globally (or for a timeframe).
-Getting current time shedule command for a device: I have a few adaptative scripts, especially for heaters, to be able to set them in normal mode for half an hour (using "FOR time" in command) if a PIR detects someone presence, current temperature is low, and heater current setting is <= eco mode. This allow to heat when someone comes in out of expected presence time. Problem is after these 30 mn, current setting may have been changed by a schedule and will be reverted to the schedule setting that was in use when the adaptative command triggered. As well, some electricity offloading (to avoid going over contractual allowed max power) done in SW I plan to code will be much more complex (and parsing takes time) to do without this.

Anyway, I can post my python script for validate stuff if this may help you.
jefft
Posts: 75
Joined: Monday 23 January 2017 23:30
Target OS: Linux
Domoticz version: 2023.1
Location: UK
Contact:

Re: How to read a device's schedule (timer) in dzVents

Post by jefft »

Thanks :-) It's always good to see how others have solved the challenge!

I plan to start simple - parse the JSON only for day-of-week schedule items (no fixed dates, sunset, etc), expand them into full datetime values, sort the list and then use it for a 'getNextSetpoint' function. The plan then, is to pass the current & next setpoints for heating and hot water into my heat loss/input calculation to decide for how long and at what temperature to run the boiler. For version 1, I'll further simplify (and improve performance) by requiring that every setpoint device have at least one scheduled value each day of the week, so that I need only look one day ahead.

Ideally, I'd like to cache fully-expanded schedules in persistent data, to avoid re-calculating it all every 15 minutes, but I don't know of any way to detect when someone edits a device schedule, so 'reload schedules' would probably have to be a manual trigger. I guess the overhead of recalculating these small schedules isn't too bad in reality, CPUs are quick.

It'd be a great addition to dzVents to have '.NextTimer()' as a built-in for the relevant device types, that would return the value and datetime of the next scheduled change.

I assume that domoticz itself decodes the timer data in some way - and probably caches it for performance - so maybe something with more access to the internal workings of domoticz could get at that data to avoid recalculating it so much.

Re (in)validating schedules - could TimerPlans help you there? If you switch plan, then the API returns only those schedule items valid in the active plan.
Domoticz, Z-Stick Gen.5, zzh Zigbee, rxftrx433XL on Ubuntu 22.04, HP 290 G1.
Node Red, MQTT, 80+ Z-wave, ESP8266 & Shelly, handful of Zigbee bulbs. EMS-ESP gateway for Bosch boiler. Controlicz, until it dies :-(
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: How to read a device's schedule (timer) in dzVents

Post by waaren »

jefft wrote: Thursday 10 September 2020 9:39 It'd be a great addition to dzVents to have '.NextTimer()' as a built-in for the relevant device types, that would return the value and datetime of the next scheduled change.
Very unlikely that this is ever going to happen. The dzVents process would need to select data from two database tables using extra sqlite calls for every cycle and even then it could never be sure the next time is accurate as another timerplan may have different timers.

My approach to a requirement where you need time based changes to thermostats and these changes also depending on other conditions would probably be build completely in dzVents with the timer- and other condition settings either set in the script variables or in the device description fields.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
jefft
Posts: 75
Joined: Monday 23 January 2017 23:30
Target OS: Linux
Domoticz version: 2023.1
Location: UK
Contact:

Re: How to read a device's schedule (timer) in dzVents

Post by jefft »

Understood, @waaren; it's not an easy one and could be a big processing overhead.

I reckon that domoticz itself must somehow expand the timer schedules and cache that view, else it'd be recalculating them every minute to identify when to act on them, which seems unlikely and horribly inefficient. When I've more time, maybe I'll take a look inside to see how it does it and whether there'd be any way to expose 'next scheduled event' or a pre-expanded version of the schedule data through the API.

Out of interest; what is dzVents actually written in and how does it link with the core of domoticz? Sounds like you're directly accessing the database rather than going via the APIs; is it all done in Lua or is dzVents partly C++ under the covers?
Domoticz, Z-Stick Gen.5, zzh Zigbee, rxftrx433XL on Ubuntu 22.04, HP 290 G1.
Node Red, MQTT, 80+ Z-wave, ESP8266 & Shelly, handful of Zigbee bulbs. EMS-ESP gateway for Bosch boiler. Controlicz, until it dies :-(
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: How to read a device's schedule (timer) in dzVents

Post by waaren »

jefft wrote: Thursday 10 September 2020 23:16 Out of interest; what is dzVents actually written in and how does it link with the core of domoticz? Sounds like you're directly accessing the database rather than going via the APIs; is it all done in Lua or is dzVents partly C++ under the covers?
dzVents receives > 95% of the objects (device, variables, scenes, etc..) attributes directly from the domoticz event system (main/EventSystem.cpp) and use C++ (main/dzVents.cpp ) to get the remaining data directly from the database and to send the combined data as a Lua table to the Lua code in <domoticz dir>/dzVents/runtime.
From dzVents to domoticz it's 99% via the Lua table commandArray and the remaining methods are send via the API/JSON commands.
(No direct poking in the database)

persistent data is stored as flat OS files
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
jefft
Posts: 75
Joined: Monday 23 January 2017 23:30
Target OS: Linux
Domoticz version: 2023.1
Location: UK
Contact:

Re: How to read a device's schedule (timer) in dzVents

Post by jefft »

Thanks @waaren, interesting to know!

I've hit a strange error when playing with dates and times... not sure why it's failing. What do you think?

I'm trying to get a datetime value that is 00:00:00 today, so that I can then add times to it later in my function. When I pass what looks like a valid date/time string to 'Time()', it fails with an error in Time.lua. Initially, I tried to pass just the rawDate() value into Time() and that said something about 'sDate invalid, reset to...', so then I forced ' 00:00:00' on the end and got the error below.

<<UPDATE: I've narrowed it down; it's actually the act of trying to log a datetime value that causes the error in Time.lua - seems that domoticz.log doesn't handle the time type well>>

Code:

Code: Select all

        local Time = require('Time')
        local currentTime = Time()
	local dayToday = currentTime.wday - 1      -- dzVents uses Sun=1 whereas the domoticz timer data uses Mon=1
	if dayToday == 0 then
	    dayToday = 7
	end
        local dayTomorrow = dayToday + 1
        if dayTomorrow == 8 then
            dayTomorrow = 1
        end

        local dateToday = currentTime.rawDate .. ' 00:00:00'
        domoticz.log('##' .. dateToday .. '##')
	local startToday = Time(dateToday)    -- date part only, to add times to later
	domoticz.log(startToday)
Log:

Code: Select all

2020-09-11 10:25:59.163 Status: dzVents: Info: ------ Start internal script: Script #1: Device: "Trigger2 (Dummy1)", Index: 17
2020-09-11 10:25:59.163 Status: dzVents: Info: ##2020-09-11 00:00:00##
2020-09-11 10:25:59.163 Status: dzVents: Info: ------ Finished Script #1
2020-09-11 10:25:59.163 Error: dzVents: Error: (3.0.12) An error occurred when calling event handler Script #1
2020-09-11 10:25:59.163 Error: dzVents: Error: (3.0.12) /home/domoticz/domoticz/dzVents/runtime/Time.lua:628: bad argument #1 to 'match' (string expected, got nil)
Domoticz, Z-Stick Gen.5, zzh Zigbee, rxftrx433XL on Ubuntu 22.04, HP 290 G1.
Node Red, MQTT, 80+ Z-wave, ESP8266 & Shelly, handful of Zigbee bulbs. EMS-ESP gateway for Bosch boiler. Controlicz, until it dies :-(
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: How to read a device's schedule (timer) in dzVents

Post by waaren »

jefft wrote: Friday 11 September 2020 11:33 <<UPDATE: I've narrowed it down; it's actually the act of trying to log a datetime value that causes the error in Time.lua - seems that domoticz.log doesn't handle the time type well>>
You try to log a time object ( a time object is a table with attributes, subtables and functions) the dzVents log method cannot handle all these functions as some do require extra parms) What you probably intend is to log one attribute of your new time object.

This snippet would do that

Code: Select all

return
{
    on =
    {
        timer =
        {
            'every minute'
        },
    },

    logging =
    {
        level = domoticz.LOG_DEBUG,
        marker = ' times' ,
    },

        execute = function(dz, triggeredItem)
            local dayToday = dz.time.wday - 1
            if dayToday == 0 then
                dayToday = 7 -- dzVents uses Sun=1 whereas the dz timer data uses Mon=1
            end

            local dayTomorrow = dayToday + 1
            if dayTomorrow == 8 then
                dayTomorrow = 1
            end

            local dateToday = dz.time.rawDateTime
            dz.log('##' .. dateToday .. '##')
            local startToday = dz.time.rawDate    -- date part only, to add times to later
            dz.log(startToday)
    end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
jefft
Posts: 75
Joined: Monday 23 January 2017 23:30
Target OS: Linux
Domoticz version: 2023.1
Location: UK
Contact:

Re: How to read a device's schedule (timer) in dzVents  [Solved]

Post by jefft »

Okay, makes sense. I changed it already to use rawDate .. 'T' .. rawTime; that does the job. I wasn't sure what types domoticz.log could handle and hadn't realised at first that a time object is a table (in most languages and OS'es, it's a number). Can't say I'm a big fan of Lua's handling of date/time, but at least you've made it easier within dzVents!
Domoticz, Z-Stick Gen.5, zzh Zigbee, rxftrx433XL on Ubuntu 22.04, HP 290 G1.
Node Red, MQTT, 80+ Z-wave, ESP8266 & Shelly, handful of Zigbee bulbs. EMS-ESP gateway for Bosch boiler. Controlicz, until it dies :-(
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest