dresden-elektronik / deconz-rest-plugin

deCONZ REST-API plugin to control ZigBee devices
BSD 3-Clause "New" or "Revised" License
1.89k stars 498 forks source link

Update time of existing schedule: no conversion to local time #5916

Open bensijtsma opened 2 years ago

bensijtsma commented 2 years ago

Describe the bug

Setting the time in an existing schedule does not lead to an update of the local time and, hence, leads to switching lights on at the wrong time!
On 27 March 2022, first day of summer time, I changed the time via REST API to 18:03:51. Then I used Postman to list all schedules and noticed that the local time was change to 18:43:41, indeed 39 minutes and 50 seconds later than the UTC time. My local time zone is Amsterdam. Today, on March 28, I updated the time field again via the REST API, and observed that the local time did not change. Below the JSON of the updated schedule (nr 34) obtained via Postman. "34": { "activation": "start", "autodelete": false, "command": { "address": "/api/C0F9707DA5/groups/1/scenes/3/recall", "body": {}, "method": "PUT" }, "created": "2022-03-13T17:54:33", "description": null, "etag": "2f4cdfec9dd68e489a515c08b2843dad", "localtime": "W127/T18:43:41", "name": "Woonkamer Aan", "status": "enabled", "time": "W127/T18:05:34" },

If I change in the API call both time and localtime e.g. via the body {"time":"W127/T18:05:20", "localtime":"W127/T20:05:20" } then indeed both time and localtime fields are updated and are correct. However, this is not as the manual says. In the documentation localtime is not a field that can be used for updating a schedule. See JSON output below when setting both time and localtime. "34": { "activation": "start", "autodelete": false, "command": { "address": "/api/C0F9707DA5/groups/1/scenes/3/recall", "body": {}, "method": "PUT" }, "created": "2022-03-13T17:54:33", "description": null, "etag": "d444eb3326112769fa9c82d521278692", "localtime": "W127/T20:05:20", "name": "Woonkamer Aan", "status": "enabled", "time": "W127/T18:05:20" }, Oddly when only updating the local time with 21:05:20 the API call returns [ { "success": { "/schedules/34/time": null } } ] Not the time=null. However listing the schedules again I get { "activation": "start", "autodelete": false, "command": { "address": "/api/C0F9707DA5/groups/1/scenes/3/recall", "body": {}, "method": "PUT" }, "created": "2022-03-13T17:54:33", "description": null, "etag": "9ac55bb9ff19663737c50ebab2673f78", "localtime": "W127/T21:05:20", "name": "Woonkamer Aan", "status": "enabled", "time": "W127/T18:05:20" }

Steps to reproduce the behavior

  1. make API call to change a specific schedule, in my case it was nr 34.
  2. Use Postman to make an API call list all schedules and look up schedule, in my case 34.
  3. Observe the time and local time fields in the JSON.

Expected behavior

OM March 27 the local time should have been 20:03:51. On March 28 it should have been 20:05:34.

Screenshots

timezone ![Uploading timezone.jpg…]()

phoscon schedule

postman

Environment

Deconz version: 2.14.01 / 06/02/2022, firmware 26660700

deCONZ Logs

Additional context

Perhaps this issue only occurs on the day when summertime happens.

manup commented 2 years ago

Indeed it docs need to be updated here, according the C++ code "time" is deprecated in favor for "localtime".

https://github.com/dresden-elektronik/deconz-rest-plugin/blob/ffda04e41a56947cf1aa0db53f98111bfdc4438c/rest_schedules.cpp#L411-L423

Note how the time and timespec variables of "time" get overwritten by "localtime" if specified.

On a first look I can't spot where the code is wrong, it has quite some branches. I've put it on the list for further tests and to also update the docs here.

Oddly when only updating the local time with 21:05:20 the API call returns

[
{
"success": {
"/schedules/34/time": null
}
}
]

Quick test updating localtime works here:

PUT 192.168.3.4:8090/api/12345/schedules/1

{
    "localtime": "W18/T20:35:00"
}

Response

[
    {
        "success": {
            "/schedules/1/localtime": "W18/T20:35:00"
        }
    }
]

However the "time" field was not updated correctly

GET 192.168.3.4:8090/api/12345/schedules/1

{
    "activation": "start",
    "autodelete": false,
    "command": {
        "address": "/api/D5D89C4475/groups/1/action",
        "body": {
            "bri": 0,
            "on": false,
            "transitiontime": 10
        },
        "method": "PUT"
    },
    "created": "2022-03-29T15:31:35",
    "description": null,
    "etag": "fe0245f89d0a4b3a2db076c0515e3b26",
    "localtime": "W18/T20:35:00",
    "name": "Test localtime",
    "status": "enabled",
    "time": "W28/T16:31:00"
}

The same happens the other way around, so the code definitely needs a review.