Page 1 of 1

Get device Timers

Posted: Wednesday 29 May 2024 19:59
by mvleusden
Hi,

I'm trying to find out if i can get the Timer info of a device\group:
2024-05-29 19_53_46-Thuis — Mozilla Firefox.jpg
2024-05-29 19_53_46-Thuis — Mozilla Firefox.jpg (57.9 KiB) Viewed 1844 times
didn't found anything in the documenation. What i need is wen this device\groep is turned off. here above 23.00. Any idea's?

Marcel

Re: Get device Timers

Posted: Wednesday 29 May 2024 23:14
by janpep
mvleusden wrote: Wednesday 29 May 2024 19:59 I'm trying to find out if i can get the Timer info of a device\group:
Perhaps this helps?

Code: Select all

https://<IP>:<PORT>/json.htm?type=schedules

Re: Get device Timers

Posted: Thursday 30 May 2024 10:18
by lost
Hello,

Adding to jeanpep answer, the API changed sometime in 2023, even if old one may still work (with a deprecated warning in logs). That's now the otherwise usual 'command' API made more specific with 'getschedules'.

Take care this sends out... all configured timers! Unfortunately, there is nothing to filter out based on device for instance.

On my side I wrote this python script a few years ago, to be able to activate/unactivate some devices schedules for some time (so using a user variable to handle auto-reverse).

This may be a base to tune for your own needs, showing how to filter out the timers of interest for you:

Code: Select all

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Schedule activation modification for device (with wildcards support)
# Date for state change, if an 'hour' parameter is given, is stored in
# a user var than can be checked by a lua time script that'll reverse current state...
#
# Changelog :
# 17/12/2016, YL, 1st version.
# 07/01/2023, Pylint checks/python3 support
# 23/06/2023, JSON API change for dmtJsonGetSched.

import getopt
import logging
import json
import sys
import datetime
from   fnmatch  import fnmatch
import requests

#####################
# EDITABLE SETTINGS #
#####################

logLevel='INFO' # DEBUG / INFO

# Domoticz json API url
dmtJurl         = 'http://127.0.0.1:8080/json.htm?'

# Command parameters in json format (only change if API change!)
#dmtJsonGetSched = {"type":"schedules"}
dmtJsonGetSched = {"type":"command", "param":"getschedules"}
dmtJsonActTimer = {"type":"command", "param":"enabledisabletimer", "idx":"999"}
dmtJsonUpdVar   = {"type":"command", "param":"updateuservariable",
                   "vname":"reverseSchedule", "vtype":2, "vvalue":0}

# Domoticz time format on LUA side:
dmtLuaTimeFmt   = "%Y-%m-%d %H:%M:%S"

#####################
def usage():
    """
    Display usage
    """

    sys.stderr.write( "Usage: ScheduleMod.py [-h] [-s<on/off>] [-t<timeInMn>] -n<device>\n")
    sys.stderr.write( "       If no 's', current state is reversed.\n")
    sys.stderr.write( "       If    't', a time for state reversal (mn) is stored for domoticz.\n")

#####################
def dmtJsonApi(url, jsonApiCmd, logger):
    """
    Send Domoticz json command
    """

    try:
        # Connect to Domoticz via JSON API and send data
        dmtRget=requests.get(url, params=jsonApiCmd)
    except requests.exceptions.RequestException as dmtErr:
        logger.log(logging.ERROR, "Unable to connect with URL=%s \nGet requests error %s" % (dmtRget.url, dmtErr))
    finally:
        logger.log(logging.DEBUG, "Sent data: [%s]" % (dmtRget.url))

    return dmtRget.json()

#####################
def main(argv):
    """
    Main
    """

    logging.basicConfig()
    logger = logging.getLogger()
    handler = logging.StreamHandler(sys.stdout)

    # Checks the parameters
    try:
        opts, args = getopt.getopt(argv, "h:s:n:t:",["help","state","name","time"])
    except getopt.GetoptError:
        usage()
        sys.exit(2)

    # Defaults
    SchedActivate = 'reverse'
    devName       = 'nil'
    reverseTimeMn = 0

    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        if o in ("-s", "--state" ):
            SchedActivate=('disabletimer','enabletimer')[a == 'on']
        if o in ("-n", "--name" ):
            devName=a
        if o in ("-t", "--time" ):
            reverseTimeMn=int(a)

    # Configure the logger
    handler.setFormatter(
        logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
    logger.setLevel(logLevel)

    logger.log(logging.INFO, "Device(s)=%s, update schedules to '%s', reverse after %dmn." %(devName, SchedActivate, reverseTimeMn))

    # Get all schedules
    schedules = dmtJsonApi(dmtJurl, dmtJsonGetSched, logger)
    #logger.log(logging.DEBUG, "Schedules: [%s]" % (schedules))

    # Modify active setting for dev name...
    schedNb=len(schedules['result'])
    logger.log(logging.DEBUG, "Found %d schedules, extract those for %s" % (schedNb, devName))

    # Change schedule(s) for device(s) matching name (wildcard support):
    for sched in schedules['result']:
        if fnmatch(sched['DevName'], devName):
            logger.log(logging.DEBUG, 'Found : %s , state=%s, idx=%d',
                       sched['DevName'],
                       sched['Active'],
                       sched['TimerID'])

            curState = ('disabletimer','enabletimer')[sched['Active'] == 'true']
            revState = ('enabletimer','disabletimer')[sched['Active'] == 'true']

            if curState != SchedActivate:
                # Update domoticz request parameters
                dmtJsonActTimer['param'] = (SchedActivate, revState)[SchedActivate == 'reverse']
                dmtJsonActTimer['idx']   = sched['TimerID']

                # Send request...
                dmtJsonApi(dmtJurl, dmtJsonActTimer, logger)

    # Set user var to current date + time given for reversal (in mn), if any...
    if reverseTimeMn != 0:
        revDate = datetime.datetime.now() + datetime.timedelta(minutes=reverseTimeMn)
        revDate = devName + ';' + revDate.strftime(dmtLuaTimeFmt)
        logger.log(logging.DEBUG, "Reverse time stored for Domoticz : %s", revDate)
        dmtJsonUpdVar['vvalue'] = revDate
        dmtJsonApi(dmtJurl, dmtJsonUpdVar, logger)
    else:
        dmtJsonUpdVar['vvalue'] = 'nil'
        dmtJsonApi(dmtJurl, dmtJsonUpdVar, logger)

    # Happy ending!
    logger.log(logging.INFO, "DONE !")

if __name__ == "__main__":
    main(sys.argv[1:])
FYI, my use case is to disable heaters schedules for a configurable time (calling script from a virtual multi-level switch) when I use my chimney. Script support wildcards & I use a naming prefix convention 'HeaterXXX' for the devices that control heaters on/off/level, so I can disable all calling this script with device name 'Heater*'.

scheduleMod.py -nHeater* -soff -t600

Will disable all my home heaters schedules for 10 hours (600mn ; a lua time script handles the auto-revert acting on the virtual multi-level switch when 'reverseSchedule' user var delay is reached).

So that's a bit specific but may be modified for your own needs...

Re: Get device Timers

Posted: Thursday 30 May 2024 10:46
by gizmocuz
Just open your browser, open the developers console (F12) (let it dock at the bottom of your browser if not already) select the network tab,
and go to the timer page
You will now see the URL to call

Re: Get device Timers

Posted: Thursday 30 May 2024 11:35
by lost
gizmocuz wrote: Thursday 30 May 2024 10:46 You will now see the URL to call
Thanks for the tip, so there is (now?) this API using a device idx that'll show it's timers directly filtered out for instance:

Code: Select all

/json.htm?idx=XXX&param=gettimers&type=command
When I needed the feature, I only checked HTTP/JSON APIs wiki & sticked to what was documented there. Anyway, with what was documented at the time I choose to allow wildcards/use a prefix naming convention to minimize such global/heavy request use... So this IMO still make sense for this specific use-case.

Re: Get device Timers

Posted: Thursday 30 May 2024 12:23
by janpep
lost wrote: Thursday 30 May 2024 10:18 Adding to janpep answer, the API changed sometime in 2023, even if old one may still work (with a deprecated warning in logs). That's now the otherwise usual 'command' API made more specific with 'getschedules'.
Take care this sends out... all configured timers! Unfortunately, there is nothing to filter out based on device for instance.
On my side I wrote this python script a few years ago, to be able to activate/unactivate some devices schedules for some time (so using a user variable to handle auto-reverse).
Thank you for your remark. Seems to be a feature that gets lost. I now see that I have corrected in all my bash and dzVents script to the new (where type is always a command :-) ). But I was not aware this was still in my custom pages.
I like it, to have this quick overview of all the timers to browse through and check. It looks like there is no similar alternative to catch them all in stead of by idx. I will look at your script, but I fear that it will not be easy to have the same kind of "one line command" to put in my custom page.

Re: Get device Timers

Posted: Thursday 30 May 2024 12:54
by janpep
Depending on what you want to do an addition that might be of help.
A bash script, that is called from Domoticz, gets my vacation start and end date-times from agenda and parses the ics file.

To clear the schedule of my Vacation switch:

Code: Select all

response=$(curl -u ${DOMOTICZ_USER}:${DOMOTICZ_PASS} --connect-timeout 10 -k -s "${DOMOTICZ_HTTPS_URL}/json.htm?type=command&param=cleartimers&idx=99999&passcode=${DOMOTICZ_SWITCH_PASS}")
verbose "Vakantietimer opgeschoond in Domoticz: ${response}"
To set the new schedule in a loop add all the found vacation dates with start and end times in variables:

Code: Select all

#Start
response=$(curl -u ${DOMOTICZ_USER}:${DOMOTICZ_PASS} --connect-timeout 10 -k -s "${DOMOTICZ_HTTPS_URL}/json.htm?type=command&param=addtimer&idx=99999&active=true&timertype=5&date=$Sdate&hour=$Sh&min=$Sm&randomness=false&command=0&days=1234567&passcode=${DOMOTICZ_SWITCH_PASS}")
verbose "Vakantietimer Starttijd $Sdate in Domoticz: ${response}"

#End
response=$(curl -u ${DOMOTICZ_USER}:${DOMOTICZ_PASS} --connect-timeout 10 -k -s "${DOMOTICZ_HTTPS_URL}/json.htm?type=command&param=addtimer&idx=99999&active=true&timertype=5&date=$Edate&hour=$Eh&min=$Em&randomness=false&command=1&days=1234567&passcode=${DOMOTICZ_SWITCH_PASS}")
verbose "Vakantietimer Eindtijd $Edate in Domoticz: ${response}"

Re: Get device Timers

Posted: Tuesday 11 June 2024 11:52
by janpep
lost wrote: Thursday 30 May 2024 10:18 Adding to janpep answer, the API changed sometime in 2023, even if old one may still work (with a deprecated warning in logs). That's now the otherwise usual 'command' API made more specific with 'getschedules'.
Meanwhile I have changed my html files with the right command options. I do not know who takes care for it, but I have to point out that the 'old' ...

Code: Select all

/json.htm?type=schedules
... is still in the wiki.
See: https://www.domoticz.com/wiki/Domoticz_ ... 8timers.29

Re: Get device Timers

Posted: Tuesday 11 June 2024 14:05
by lost
janpep wrote: Tuesday 11 June 2024 11:52 I have to point out that the 'old' ...

Code: Select all

/json.htm?type=schedules
... is still in the wiki.
See: https://www.domoticz.com/wiki/Domoticz_ ... 8timers.29
You're right, looks this one was forgotten even if ahead in the wiki, the added warning notice for this change was correct:
https://www.domoticz.com/wiki/Domoticz_ ... d_newer.29

Code: Select all

/json.htm?type=**old command** -> /json.htm?type=command&param=**new command**
(...)
"schedules" -> "getschedules"
(...)
Unfortunately, wiki edition is no more allowed to anyone having an account (probably too much abuse to clean, as everything kept 'open' nowadays). So you may send a PM to waltervi?

Re: Get device Timers

Posted: Tuesday 11 June 2024 14:26
by janpep
Yes, sometimes it takes a bit of searching and then you take what turns out to work. At that moment you look no further.
I'm glad you pointed it out to me and I have to say that I am very excited about all the possibilities with the API approach. For example, I access my Synology with various API commands from Domoticz and I access Domoticz from scripts in tasks on my synology and Macrodroid app on my phone.
Because of your comment, I also found that the events can be retrieved with their ID and with that also can be enabled and disabled via the API. I had not thought of that before. It gave me inspiration to enable or disable certain scripts from dzVents automatically when my "vacation mode" is active.

Re: Get device Timers

Posted: Tuesday 11 June 2024 14:29
by waltervl
lost wrote: Tuesday 11 June 2024 14:05 Unfortunately, wiki edition is no more allowed to anyone having an account (probably too much abuse to clean, as everything kept 'open' nowadays). So you may send a PM to waltervi?
Fixed the incorrect updated API calls now. Thanks for reporting.

Re: Get device Timers

Posted: Tuesday 11 June 2024 17:55
by janpep
Great. Thank you.

Re: Get device Timers

Posted: Wednesday 12 June 2024 7:16
by lost
janpep wrote: Tuesday 11 June 2024 14:26 It gave me inspiration to enable or disable certain scripts from dzVents automatically when my "vacation mode" is active.
For this kind of usage, you can also have several timer plans. I have myself one for home/working (so less day heating), another for home/presence. On top of those I have vacations (I can reverse remotely the day before to come back to have hot water/heating when back...) and a last one for heavy electricity price days (for those, I almost only use my chimney).

I mostly use scripted timers activation changes when easier than building/adding another timer plan.

Timer plans are not easy to find/switch from menus (WAF is important!), but you can do this through a virtual selector switch & "action" commands using the API, like this (locally):

Code: Select all

http://127.0.0.1:8080/json.htm?type=command&param=setactivetimerplan&ActiveTimerPlan=1
+ Thanks valtervi for the update!

Re: Get device Timers

Posted: Thursday 13 June 2024 17:09
by janpep
lost wrote: Wednesday 12 June 2024 7:16 For this kind of usage, you can also have several timer plans.
Thanks for your tip. I saw this option later (or the functionality only came after I had already set it up). It is still on my list to look at although I have a good working and flexible situation now. Because it still has everything to do with obtaining and setting timers, I will consider it on-topic and will elaborate a bit on it. Maybe it will give someone another idea.

My experience with fixed timers was that when I went to bed later, I was suddenly sitting in the dark. :-)
I now have the following 'layered' approach to achieve a more 'dynamic' setup. This is especially good in my case, because I have a number of timer settings that may or may not be active under certain conditions. Some issues can be resolved in more than one way and are a matter of preference.

1. The basis lies in the time of day and whether someone is home.
A. A personal switch is made with an 'online checker' for my wife and a geofence for myself.
Changing these switches triggers a script. This sets the user variable 'someone's home' to 0 or 1. This can be used anywhere to check.

B. A DayEveningNight script is triggered by Domoticz system start, or time, or device.
-'between 8:00 and 16 minutes before sunset' I call it day.
-'between 15 minutes before sunset and 23:59' I call it evening
- When a specific light switches off and time 'at 10:00 PM-02:30 AM' (I go to bed) I call it night.
uservariable 'DayEveningNightStand' is set to 1, 2 or 3.

2. Actions based on this take place in TV-Switch-byTimeAndPresence.
Triggered on variable change, or time (for a few specific conditional switches)
It is divided into three parts if dayeveningnight = 1 or 2 or 3.
In each part is divided into 4 parts: always switch off, always switch on, actions when someone at home = 0, actions when someone at home = 1

Advantatage is that you can set conditions and also have everything with dependencies together in one place.
A couple of devices that have a fixed timer that are set on the device itself.

3. Next to this I have a my Vacationtimer.
This is a dummy switch which has its own timer, that is set by a bash script. This script gets iCal information from my Synology Calendar, parses out the vacation start and end datetimes from it and sets this timer. On/Off switching on its turn triggers my vacation script, where depending the on the on or off status, this script switches On/Off some devices, some scene schedules, my EvoHome and my repeater.
Finally I just added to switch on/off some dzVents scripts during my vacation.

Re: Get device Timers

Posted: Thursday 13 June 2024 17:44
by lost
To better manage dependancies and ability to somehow mix some dynamic device settings (scripted) there is IMO a miss in how schedules are managed.

I see 2 options here:
Being able to get current setting for a device at current time (in case your scripted changes must be reversed).
Ensure should-be state is set if a timer is activated after (missed) set time change.

Main issue in my setting is I have to manage a few timers for some sync purpose in each plan in case I switch from one to another and cannot restore should be state on script driven desactivation/reactivation without using (potentially lot) of user var.

Re: Get device Timers

Posted: Friday 14 June 2024 20:58
by janpep
For now I will stick to the switches, variables and scripts and timers as mentioned. Over time, it has been continuously adapted and improved to what it is today, and it actually works without any problems. I shall see what further developments will bring, but I am already VERY satisfied with the current options.