Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] weekly_schedule expose #5550

Merged
merged 5 commits into from
May 7, 2023
Merged

[WIP] weekly_schedule expose #5550

merged 5 commits into from
May 7, 2023

Conversation

sjorge
Copy link
Sponsor Contributor

@sjorge sjorge commented Mar 4, 2023

  • Fixed a bug that snuck into the last PR
  • Start calculated derived values: mode and numoftrans
    • if we encounter a heatSetPoint we add "heat" to mode
    • if we encouter a coolSetPoint we add "cool" to mode
    • numoftrans = transitions.length (we now check if it's an array and error out otherwise)
  • expose data

Since we now calculate the derived values, this should make the exposes data simpler.

The following now works correctly:

mosquitto_pub -t zigbee2mqtt/trv/office/set -m '{"weekly_schedule":{"dayofweek":["saturday","sunday"],"transitions":[{"transitionTime":"00:00","heatSetpoint":16},{"transitionTime":"09:00","heatSetpoint":20},{"transitionTime":"22:00","heatSetpoint":16}]}}'

@sjorge

This comment was marked as resolved.

@Koenkk
Copy link
Owner

Koenkk commented Mar 5, 2023

  • exposes.composit should be exposes.composite
  • "???" (dayofweek) should become e.g. exposes.enum('identify', ea.SET, ['monday', 'sunday']) (add all other days)

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Mar 5, 2023

Oh neat, I guess the main error was the typo in composite. Using an enum is indeed a nice solution for the fix set of options.

I got a bit further but hitting some new problems now:

  • frontend seems unstable with this exposes data, see the video. (I tried Firefox and Safari)
  • List exposes type seem to be igorning min/max length ? (Or side effect of the one above)
  • Can't make coolSetpoint/heatSetpoint optional. I can list one or both. (I think we can fix this once I move this to the Climate exposes class in a withWeeklySchedule() where I can specify if its heat,cool or both.
  • I can't get rid of the 'undefined' entry in the dayofweek list in the payload when hitting apply (When I can get there!)
  • Used numeric for transitionTime as I couldn't find a way to get a 24h time picker. I guess an enum in 15 min intervals cool work but might not be fine grained enough for people ?

I pushed the commit (for now only on the device I'm testing with) so you can see what I have so far, once it works I think it probably should be moved to the climate() class as a 'withWeeklySchedule()`

Screen.Recording.2023-03-05.at.11.25.03.mov

e.g. generated payload if I race like a mad man before the frontend resets

{"weekly_schedule":{"dayofweek":[{"undefined":"saturday"},{"undefined":"sunday"}],"transitions":[{"heatSetpoint":22,"transitionTime":0}]}}'

@sjorge sjorge force-pushed the hvacschedule branch 4 times, most recently from 19e06ff to 6f4bde2 Compare March 5, 2023 10:56
@Koenkk
Copy link
Owner

Koenkk commented Mar 6, 2023

frontend seems unstable with this exposes data, see the video. (I tried Firefox and Safari)

Could it be that the device publishes it state when this happens? (can you provide the debug log when this happens)

List exposes type seem to be igorning min/max length ? (Or side effect of the one above)

min/max is indeed ignored by the frontend.

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Mar 6, 2023

frontend seems unstable with this exposes data, see the video. (I tried Firefox and Safari)

Could it be that the device publishes it state when this happens? (can you provide the debug log when this happens)

There is certainly stuff being publish when this is happening, but from other devices (trv/office is the one I had open on the exposes tab on the frontend):

debug 2023-03-06 16:45:44: Received Zigbee message from 'power/home', type 'attributeReport', cluster 'haElectricalMeasurement', data '{"activePower":420}' from endpoint 1 with groupID 0
debug 2023-03-06 16:45:44: Received Zigbee message from 'motion/entrance', type 'commandStatusChangeNotification', cluster 'ssIasZone', data '{"extendedstatus":0,"zonestatus":48}' from endpoint 35 with groupID 0
info  2023-03-06 16:45:44: MQTT publish: topic 'zigbee2mqtt/power/home', payload '{"linkquality":145,"power":420,"power_alarm_active":false,"power_alarm_active_value":0,"power_alarm_enabled":0,"power_alarm_wh_threshold":0,"power_apparent":null}'
info  2023-03-06 16:45:45: MQTT publish: topic 'zigbee2mqtt/motion/entrance', payload '{"battery":80,"battery_low":false,"illuminance":6719,"illuminance_lux":5,"led_control":"motion_only","linkquality":91,"occupancy":false,"occupancy_timeout":60,"tamper":false,"temperature":18.93,"update":{"installed_version":262147,"latest_version":262146,"state":"idle"},"voltage":2900}'
debug 2023-03-06 16:45:45: Received Zigbee message from 'light/kitchen/table/bulb3', type 'commandQueryNextImageRequest', cluster 'genOta', data '{"fieldControl":0,"fileVersion":16784922,"imageType":276,"manufacturerCode":4107}' from endpoint 11 with groupID 0
debug 2023-03-06 16:45:45: Device 'light/kitchen/table/bulb3' requested OTA
debug 2023-03-06 16:45:45: Received Zigbee message from 'airquality/office', type 'attributeReport', cluster 'msRelativeHumidity', data '{"measuredValue":3760,"tolerance":200}' from endpoint 38 with groupID 0
info  2023-03-06 16:45:45: MQTT publish: topic 'zigbee2mqtt/airquality/office', payload '{"air_quality":"good","battery":80,"battery_low":false,"humidity":37.6,"linkquality":87,"temperature":18.3,"update":{"installed_version":262145,"latest_version":262145,"state":"idle"},"voc":833,"voltage":2900}'
debug 2023-03-06 16:45:46: Received Zigbee message from 'light/livingroom/main/bulb3', type 'commandQueryNextImageRequest', cluster 'genOta', data '{"fieldControl":0,"fileVersion":16784922,"imageType":276,"manufacturerCode":4107}' from endpoint 11 with groupID 0
debug 2023-03-06 16:45:46: Device 'light/livingroom/main/bulb3' requested OTA
debug 2023-03-06 16:45:48: Received Zigbee message from 'outlet/office/desk', type 'attributeReport', cluster 'seMetering', data '{"currentSummDelivered":[0,7004]}' from endpoint 1 with groupID 0
info  2023-03-06 16:45:49: MQTT publish: topic 'zigbee2mqtt/outlet/office/desk', payload '{"energy":70.04,"linkquality":61,"power":0,"power_on_behavior":"previous","state":"OFF"}'
debug 2023-03-06 16:45:49: Received Zigbee message from 'switch/pantry/light', type 'attributeReport', cluster 'genOnOff', data '{"onOff":1}' from endpoint 1 with groupID 0
info  2023-03-06 16:45:49: MQTT publish: topic 'zigbee2mqtt/switch/pantry/light', payload '{"energy":0.49,"linkquality":109,"power":0,"power_on_behavior":"on","state":"ON","update":{"installed_version":34735108,"latest_version":34735108,"state":"idle"}}'
debug 2023-03-06 16:45:50: Received Zigbee message from 'outlet/bathroom/upper', type 'attributeReport', cluster 'seMetering', data '{"currentSummDelivered":[0,303]}' from endpoint 1 with groupID 0
info  2023-03-06 16:45:51: MQTT publish: topic 'zigbee2mqtt/outlet/bathroom/upper', payload '{"child_lock":"UNLOCK","current":0,"energy":0.03,"led_enable":true,"linkquality":91,"power":0,"state":"OFF","voltage":236.1}'
debug 2023-03-06 16:45:51: Received Zigbee message from 'th/pantry', type 'attributeReport', cluster 'msTemperatureMeasurement', data '{"measuredValue":2690,"tolerance":50}' from endpoint 38 with groupID 0
debug 2023-03-06 16:45:52: Received Zigbee message from 'power/home', type 'attributeReport', cluster 'haElectricalMeasurement', data '{"activePower":408}' from endpoint 1 with groupID 0
info  2023-03-06 16:45:52: MQTT publish: topic 'zigbee2mqtt/th/pantry', payload '{"battery":86,"battery_low":false,"humidity":27,"linkquality":87,"temperature":26.9,"voltage":3100}'
info  2023-03-06 16:45:52: MQTT publish: topic 'zigbee2mqtt/power/home', payload '{"linkquality":145,"power":408,"power_alarm_active":false,"power_alarm_active_value":0,"power_alarm_enabled":0,"power_alarm_wh_threshold":0,"power_apparent":null}'
debug 2023-03-06 16:45:53: Received Zigbee message from 'light/livingroom/main/bulb1', type 'commandQueryNextImageRequest', cluster 'genOta', data '{"fieldControl":0,"fileVersion":16784922,"imageType":276,"manufacturerCode":4107}' from endpoint 11 with groupID 0
debug 2023-03-06 16:45:53: Device 'light/livingroom/main/bulb1' requested OTA
debug 2023-03-06 16:45:55: Received Zigbee message from 'light/kitchen/table/bulb3', type 'commandQueryNextImageRequest', cluster 'genOta', data '{"fieldControl":0,"fileVersion":16784922,"imageType":276,"manufacturerCode":4107}' from endpoint 11 with groupID 0
debug 2023-03-06 16:45:55: Device 'light/kitchen/table/bulb3' requested OTA
debug 2023-03-06 16:45:55: Received Zigbee message from 'switch/entrance/light', type 'attributeReport', cluster 'genOnOff', data '{"onOff":1}' from endpoint 1 with groupID 0
info  2023-03-06 16:45:56: MQTT publish: topic 'zigbee2mqtt/switch/entrance/light', payload '{"energy":0.02,"linkquality":43,"power":0,"power_on_behavior":"on","state":"ON","update":{"installed_version":34735108,"latest_version":34735108,"state":"idle"}}'
debug 2023-03-06 16:45:56: Received Zigbee message from 'light/livingroom/main/bulb3', type 'commandQueryNextImageRequest', cluster 'genOta', data '{"fieldControl":0,"fileVersion":16784922,"imageType":276,"manufacturerCode":4107}' from endpoint 11 with groupID 0
debug 2023-03-06 16:45:56: Device 'light/livingroom/main/bulb3' requested OTA

I had it reset the view a few times, this was the activity during that time.

Firefox also showed no requests or messages on the webdeveloper console when this is happening.

List exposes type seem to be igorning min/max length ? (Or side effect of the one above)

min/max is indeed ignored by the frontend.
That's unfortunate.

@Koenkk
Copy link
Owner

Koenkk commented Mar 6, 2023

Seems similar to Koenkk/zigbee2mqtt#16940

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Mar 6, 2023

Seems similar to Koenkk/zigbee2mqtt#16940

Yep that looks like the exact same problem.

So I think that just leaves:

  • {"weekly_schedule":{"dayofweek":[{"undefined":"saturday"},{"undefined":"sunday"}],"transitions":[{"heatSetpoint":22,"transitionTime":0}]}} where dayofweek is not build correctly
  • no way to have a nice time picker. I wonder if dynamically building a large enum with 15 min intervals would be OK for now ? That's something that should be easy enough to generate with a loop ?

@Koenkk
Copy link
Owner

Koenkk commented Mar 6, 2023

no way to have a nice time picker. I wonder if dynamically building a large enum with 15 min intervals would be OK for now ? That's something that should be easy enough to generate with a loop ?

I think it will be better to use two input number fields (hours and minutes)

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Mar 6, 2023

no way to have a nice time picker. I wonder if dynamically building a large enum with 15 min intervals would be OK for now ? That's something that should be easy enough to generate with a loop ?

I think it will be better to use two input number fields (hours and minutes)

Then we can't have the attribute accept both str and int though

Edit: Well i can make it accept int,str and object with little extra work, that probably a nice way to do it

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Mar 10, 2023

OK we now accept either:

  • minutes since 00:00 as a number
  • "19:30" format as a string (prefer this as human writing the payload in say node-red)
  • {"hour": 19, "minute": 30} as an object (to make the expose data easier)
Zigbee2MQTT:debug 2023-03-10 18:23:35: Received MQTT message on 'zigbee2mqtt/0x00158d0001ffaffc/set' with data '{"weekly_schedule":{"dayofweek":["saturday","sunday"],"transitions":[{"heatSetpoint":22,"transitionTime": 1170}]}}'
Zigbee2MQTT:debug 2023-03-10 18:23:35: Publishing 'set' 'weekly_schedule' to '0x00158d0001ffaffc'
Zigbee2MQTT:error 2023-03-10 18:23:35: {"dayofweek":65,"transitions":[{"heatSetpoint":2200,"transitionTime":1170}],"numoftrans":1,"mode":1}
Zigbee2MQTT:debug 2023-03-10 18:21:33: Received MQTT message on 'zigbee2mqtt/0x00158d0001ffaffc/set' with data '{"weekly_schedule":{"dayofweek":["saturday","sunday"],"transitions":[{"heatSetpoint":22,"transitionTime":{"hour":19,"minute":30}}]}}'
Zigbee2MQTT:debug 2023-03-10 18:21:33: Publishing 'set' 'weekly_schedule' to '0x00158d0001ffaffc'
Zigbee2MQTT:error 2023-03-10 18:21:33: {"dayofweek":65,"transitions":[{"heatSetpoint":2200,"transitionTime":1170}],"numoftrans":1,"mode":1}
Zigbee2MQTT:debug 2023-03-10 18:21:54: Received MQTT message on 'zigbee2mqtt/0x00158d0001ffaffc/set' with data '{"weekly_schedule":{"dayofweek":["saturday","sunday"],"transitions":[{"heatSetpoint":22,"transitionTime": "19:30"}]}}'
Zigbee2MQTT:debug 2023-03-10 18:21:54: Publishing 'set' 'weekly_schedule' to '0x00158d0001ffaffc'
Zigbee2MQTT:error 2023-03-10 18:21:54: {"dayofweek":65,"transitions":[{"heatSetpoint":2200,"transitionTime":1170}],"numoftrans":1,"mode":1}

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Mar 10, 2023

@Koenkk aside from the frontend bug currently making this usable because it keeps resetting... there is still the dayofweek issue where the list ends up like [{"undefined":"saturday"},{"undefined":"sunday"}] I tried a few things but I can't fix it.

Maybe this is another bug on how the frontend handles it?

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Mar 10, 2023

@Koenkk more interesting behavior :(

I moved everything over to Climate() and now the frontend doesn't render an apply button!
image

Here are the respective payloads the frontend sees:

{"access":7,"features":[{"access":2,"description":"Days on which the schedule will be active.","item_type":{"access":2,"name":"day","type":"enum","values":["monday","tuesday","wednesday","thursday","friday","saturday","sunday","away_or_vacation"]},"length_max":8,"length_min":1,"name":"dayofweek","property":"dayofweek","type":"list"},{"access":2,"item_type":{"access":2,"features":[{"access":2,"description":"Trigger transition X minutes after 00:00.","features":[{"access":2,"name":"hour","property":"hour","type":"numeric"},{"access":2,"name":"minute","property":"minute","type":"numeric"}],"name":"time","property":"transitionTime","type":"composite"},{"access":2,"description":"Target heat setpoint","name":"heatSetpoint","property":"heatSetpoint","type":"numeric"}],"name":"transition","type":"composite"},"length_max":10,"length_min":1,"name":"transitions","property":"transitions","type":"list"}],"name":"schedule_old","property":"weekly_schedule","type":"composite"}

and

{"access":7,"features":[{"access":2,"description":"Days on which the schedule will be active.","item_type":{"access":2,"name":"day","type":"enum","values":["monday","tuesday","wednesday","thursday","friday","saturday","sunday","away_or_vacation"]},"length_max":8,"length_min":1,"name":"dayofweek","property":"dayofweek","type":"list"},{"access":2,"item_type":{"access":2,"features":[{"access":2,"description":"Trigger transition X minutes after 00:00.","features":[{"access":2,"name":"hour","property":"hour","type":"numeric"},{"access":2,"name":"minute","property":"minute","type":"numeric"}],"name":"time","property":"transitionTime","type":"composite"},{"access":2,"description":"Target heat setpoint","name":"heatSetpoint","property":"heatSetpoint","type":"numeric"}],"name":"transition","type":"composite"},"length_max":10,"length_min":1,"name":"transitions","property":"transitions","type":"list"}],"name":"schedule","property":"weekly_schedule","type":"composite"}

Aside from the name they are identical!

The _old variant was generated by:

            exposes.composite('schedule', 'weekly_schedule', ea.ALL)
                .withFeature(exposes.list('dayofweek', ea.SET, exposes.enum('day', ea.SET, [
                    'monday', 'tuesday', 'wednesday', 'thursday', 'friday',
                    'saturday', 'sunday', 'away_or_vacation',
                ])).withLengthMin(1).withLengthMax(8).withDescription('Days on which the schedule will be active.'))
                .withFeature(exposes.list('transitions', ea.SET, exposes.composite('transition', 'transition', ea.SET)
                    .withFeature(exposes.composite('time', 'transitionTime', ea.SET)
                        .withFeature(exposes.numeric('hour', ea.SET))
                        .withFeature(exposes.numeric('minute', ea.SET))
                        .withDescription('Trigger transition X minutes after 00:00.')
                    )
                    .withFeature(exposes.numeric('heatSetpoint', ea.SET)
                        .withDescription('Target heat setpoint')
                    )
                    /* XXX: set heatSP, coolSP based on systemMode support
                    .withFeature(exposes.numeric('coolSetpoint', ea.SET)
                       .withDescription('Target cool setpoint')
                    )
                    */
                ).withLengthMin(1).withLengthMax(10)
            ),

The other one by the new code in this PR.

@Koenkk
Copy link
Owner

Koenkk commented Mar 11, 2023

@Koenkk aside from the frontend bug currently making this usable because it keeps resetting... there is still the dayofweek issue where the list ends up like [{"undefined":"saturday"},{"undefined":"sunday"}] I tried a few things but I can't fix it.

Maybe this is another bug on how the frontend handles it?

Probably yes, @nurikk do you have time to look into this?

@Koenkk
Copy link
Owner

Koenkk commented Mar 20, 2023

@nurikk pushed a possible fix for this, @sjorge can you check again?

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Mar 20, 2023

@Koenkk Still seems pretty broken, it seems to 'reset' less though.

  • day enum still has undefined as a key
  • adding a single day now triggers and immediate set
Zigbee2MQTT:debug 2023-03-20 20:02:11: Received MQTT message on 'zigbee2mqtt/0x00158d0001ffaffc/set' with data '{"weekly_schedule":{"dayofweek":[{"undefined":"monday"}]}}'
  • hitting apply on the first transition also triggers an imediat update
Zigbee2MQTT:debug 2023-03-20 20:03:31: Received MQTT message on 'zigbee2mqtt/0x00158d0001ffaffc/set' with data '{"weekly_schedule":{"dayofweek":[{"undefined":"monday"}],"transitions":[{"heatSetpoint":22,"transitionTime":{"hour":9,"minute":30}}]}}'
  • apply button for the entire weekly_schedule composite is missing (probably related to the above?)

Here is the debug log

Zigbee2MQTT:debug 2023-03-20 20:09:49: Received MQTT message on 'zigbee2mqtt/0x00158d0001ffaffc/set' with data '{"weekly_schedule":{"dayofweek":[{"undefined":"monday"},{}]}}'
Zigbee2MQTT:debug 2023-03-20 20:09:49: Publishing 'set' 'weekly_schedule' to '0x00158d0001ffaffc'
Zigbee2MQTT:error 2023-03-20 20:09:49: weekly_schedule: transitions is not an array!
Zigbee2MQTT:debug 2023-03-20 20:09:51: Received MQTT message on 'zigbee2mqtt/0x00158d0001ffaffc/set' with data '{"weekly_schedule":{"dayofweek":[{"undefined":"monday"},{"undefined":"tuesday"}]}}'
Zigbee2MQTT:debug 2023-03-20 20:09:51: Publishing 'set' 'weekly_schedule' to '0x00158d0001ffaffc'
Zigbee2MQTT:error 2023-03-20 20:09:51: weekly_schedule: transitions is not an array!
Zigbee2MQTT:debug 2023-03-20 20:10:00: Received MQTT message on 'zigbee2mqtt/0x00158d0001ffaffc/set' with data '{"weekly_schedule":{"dayofweek":[{"undefined":"monday"},{"undefined":"tuesday"}],"transitions":[{"heatSetpoint":22,"transitionTime":{"hour":9,"minute":30}}]}}'
Zigbee2MQTT:debug 2023-03-20 20:10:00: Publishing 'set' 'weekly_schedule' to '0x00158d0001ffaffc'
Zigbee2MQTT:error 2023-03-20 20:10:00: Publish 'set' 'weekly_schedule' to '0x00158d0001ffaffc' failed: 'TypeError: d.toLowerCase is not a function'
Zigbee2MQTT:debug 2023-03-20 20:10:00: TypeError: d.toLowerCase is not a function
    at Object.convertSet (/Users/sjorge/Documents/repos/zigbee-herdsman-converters/converters/toZigbee.js:1319:71)
    at Publish.onMQTTMessage (/opt/zigbee2mqtt/lib/extension/publish.ts:247:52)
    at EventEmitter.emit (node:events:524:35)
    at EventBus.emitMQTTMessage (/opt/zigbee2mqtt/lib/eventBus.ts:109:22)
    at MQTT.onMessage (/opt/zigbee2mqtt/lib/mqtt.ts:140:27)
    at WebSocket.<anonymous> (/opt/zigbee2mqtt/lib/extension/frontend.ts:121:27)
    at WebSocket.emit (node:events:512:28)
    at Receiver.receiverOnMessage (/opt/zigbee2mqtt/node_modules/ws/lib/websocket.js:1184:20)
    at Receiver.emit (node:events:512:28)
    at Receiver.dataMessage (/opt/zigbee2mqtt/node_modules/ws/lib/receiver.js:541:14)
Zigbee2MQTT:info  2023-03-20 20:10:00: MQTT publish: topic 'zigbee2mqtt/bridge/log', payload '{"message":"Publish 'set' 'weekly_schedule' to '0x00158d0001ffaffc' failed: 'TypeError: d.toLowerCase is not a function'","meta":{"friendly_name":"0x00158d0001ffaffc"},"type":"zigbee_publish_error"}'
Zigbee2MQTT:debug 2023-03-20 20:10:03: Saving state to file /opt/zigbee2mqtt/data/state.json
Zigbee2MQTT:debug 2023-03-20 20:10:09: Received MQTT message on 'zigbee2mqtt/0x00158d0001ffaffc/set' with data '{"weekly_schedule":{"dayofweek":[{"undefined":"monday"},{"undefined":"tuesday"}],"transitions":[{"heatSetpoint":22,"transitionTime":{"hour":9,"minute":30}},{"heatSetpoint":18,"transitionTime":{"hour":10,"minute":30}}]}}'
Zigbee2MQTT:debug 2023-03-20 20:10:09: Publishing 'set' 'weekly_schedule' to '0x00158d0001ffaffc'
Zigbee2MQTT:error 2023-03-20 20:10:09: Publish 'set' 'weekly_schedule' to '0x00158d0001ffaffc' failed: 'TypeError: d.toLowerCase is not a function'
Zigbee2MQTT:debug 2023-03-20 20:10:09: TypeError: d.toLowerCase is not a function
    at Object.convertSet (/Users/sjorge/Documents/repos/zigbee-herdsman-converters/converters/toZigbee.js:1319:71)
    at Publish.onMQTTMessage (/opt/zigbee2mqtt/lib/extension/publish.ts:247:52)
    at EventEmitter.emit (node:events:524:35)
    at EventBus.emitMQTTMessage (/opt/zigbee2mqtt/lib/eventBus.ts:109:22)
    at MQTT.onMessage (/opt/zigbee2mqtt/lib/mqtt.ts:140:27)
    at WebSocket.<anonymous> (/opt/zigbee2mqtt/lib/extension/frontend.ts:121:27)
    at WebSocket.emit (node:events:512:28)
    at Receiver.receiverOnMessage (/opt/zigbee2mqtt/node_modules/ws/lib/websocket.js:1184:20)
    at Receiver.emit (node:events:512:28)
    at Receiver.dataMessage (/opt/zigbee2mqtt/node_modules/ws/lib/receiver.js:541:14)
Zigbee2MQTT:info  2023-03-20 20:10:09: MQTT publish: topic 'zigbee2mqtt/bridge/log', payload '{"message":"Publish 'set' 'weekly_schedule' to '0x00158d0001ffaffc' failed: 'TypeError: d.toLowerCase is not a function'","meta":{"friendly_name":"0x00158d0001ffaffc"},"type":"zigbee_publish_error"}'
Screen.Recording.2023-03-20.at.20.09.45.mov

@nurikk
Copy link
Contributor

nurikk commented Mar 20, 2023

Hi!
Can you attach complete state.json file from Settings -> Tools -> Download state ?

@nurikk
Copy link
Contributor

nurikk commented Mar 20, 2023

And btw, according to exposé’s definitions enum has to have “key” attribute. Exposes specification doesn’t support primitive types other than “number” for array type.

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Mar 20, 2023

And btw, according to exposé’s definitions enum has to have “key” attribute. Exposes specification doesn’t support primitive types other than “number” for array type.

@Koenkk I guess we can't expose dayofweek as a list of enum then. Any other way to describe this? Or should something new be added?

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Mar 20, 2023

Hi! Can you attach complete state.json file from Settings -> Tools -> Download state ?

state.json.zip

@nurikk
Copy link
Contributor

nurikk commented Mar 21, 2023

And btw, according to exposé’s definitions enum has to have “key” attribute. Exposes specification doesn’t support primitive types other than “number” for array type.

@Koenkk I guess we can't expose dayofweek as a list of enum then. Any other way to describe this? Or should something new be added?

you just add key='day' to your enum definition. then it will become [{"day":"saturday"},{"day":"sunday"}]

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Mar 31, 2023

Wrapping it in another composite abstraction gets rid of the undefined but all other mentioned bugs are still present. It's also a bit silly and a lot of extra code that we really shouldn't be needing with all the additional composites. I feel like a list of str (based on an enum) seems like something we should somehow support.

As described above there is not 'apply' button for the weekly_schedule level, the seperate apply button in the nested composites trigger incomplete (and thus invalid) payloads. Also by the time you have your desired payload a bunch of broken ones are queued up that are all sent once the device wakes up. I managed to crash my test TRV.

image

state.json.zip

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Apr 8, 2023

@Koenkk I think with the workaround by adding an extra abstraction level for the daysofweek this now works, aside form the bugs in the frontend that are still present? Or am I missing something else.

@nurikk
Copy link
Contributor

nurikk commented May 1, 2023

hi @sjorge , can you please try following version. npm install zigbee2mqtt-frontend@0.6.128 there're many changes and I hesitate to merge into dev before proper testings

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented May 2, 2023

hi @sjorge , can you please try following version. npm install zigbee2mqtt-frontend@0.6.128 there're many changes and I hesitate to merge into dev before proper testings

Will try this version tomorrow, going to be a long day at work today.

sjorge added 5 commits May 2, 2023 20:04
…9, "minute": 30} object

This so that we can make actually have it described somewhat as expose data as we have no 'time' or 'datetime' picker.
This is getting redicilous, maybe some additions to the exposes format are needed.
@sjorge
Copy link
Sponsor Contributor Author

sjorge commented May 2, 2023

hi @sjorge , can you please try following version. npm install zigbee2mqtt-frontend@0.6.128 there're many changes and I hesitate to merge into dev before proper testings

Looking good so far:

Zigbee2MQTT:debug 2023-05-02 20:13:47: Received Zigbee message from '0x90fd9ffffe4a612f', type 'attributeReport', cluster 'hvacThermostat', data '{"localTemp":2297}' from endpoint 1 with groupID 0
Zigbee2MQTT:info  2023-05-02 20:13:47: MQTT publish: topic 'zigbee2mqtt/0x90fd9ffffe4a612f', payload '{"battery":60,"keypad_lockout":0,"linkquality":225,"local_temperature":22.97,"occupied_heating_setpoint":25}'
Zigbee2MQTT:debug 2023-05-02 20:14:00: Received Zigbee message from '0x90fd9ffffe4a612f', type 'commandQueryNextImageRequest', cluster 'genOta', data '{"fieldControl":0,"fileVersion":512,"imageType":0,"manufacturerCode":4641}' from endpoint 1 with groupID 0
Zigbee2MQTT:debug 2023-05-02 20:14:00: Device '0x90fd9ffffe4a612f' requested OTA
Zigbee2MQTT:debug 2023-05-02 20:14:01: Responded to OTA request of '0x90fd9ffffe4a612f' with 'NO_IMAGE_AVAILABLE'
Zigbee2MQTT:debug 2023-05-02 20:14:38: Received MQTT message on 'zigbee2mqtt/0x90fd9ffffe4a612f/set' with data '{"weekly_schedule":{"dayofweek":[{"day":"monday"},{"day":"tuesday"},{"day":"wednesday"}],"transitions":[{"heatSetpoint":16,"transitionTime":{"hour":0,"minute":0}},{"heatSetpoint":20,"transitionTime":{"hour":5,"minute":30}},{"heatSetpoint":19,"transitionTime":{"hour":7,"minute":0}}]}}'
Zigbee2MQTT:debug 2023-05-02 20:14:38: Publishing 'set' 'weekly_schedule' to '0x90fd9ffffe4a612f'
Zigbee2MQTT:debug 2023-05-02 20:14:47: Received Zigbee message from '0x90fd9ffffe4a612f', type 'attributeReport', cluster 'hvacThermostat', data '{"localTemp":2309}' from endpoint 1 with groupID 0
Zigbee2MQTT:info  2023-05-02 20:14:47: MQTT publish: topic 'zigbee2mqtt/0x90fd9ffffe4a612f', payload '{"battery":60,"keypad_lockout":0,"linkquality":214,"local_temperature":23.09,"occupied_heating_setpoint":25}'
Zigbee2MQTT:debug 2023-05-02 20:15:05: Received Zigbee message from '0x90fd9ffffe4a612f', type 'commandCheckIn', cluster 'genPollCtrl', data '{}' from endpoint 1 with groupID 0

Only published once I hit apply (which is what is expected)

Screen.Recording.2023-05-02.at.20.16.23.mov

So LGTM

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented May 2, 2023

I also did a few more tries while sending get requests for other attribute so messages for the device are arriving, the interface does not seem to reset so thats also good.

@sjorge sjorge marked this pull request as ready for review May 7, 2023 14:49
@sjorge
Copy link
Sponsor Contributor Author

sjorge commented May 7, 2023

@Koenkk should be mergable now that we have Koenkk/zigbee2mqtt@b8e4607

@Koenkk
Copy link
Owner

Koenkk commented May 7, 2023

Cool thanks again!

@Koenkk Koenkk merged commit 35089f7 into Koenkk:master May 7, 2023
1 check passed
@photomoose
Copy link
Contributor

@sjorge is my understanding correct in that this schedule functionality allows us to only define a number of schedule transitions that can be applied to one or more days.... but it is not currently possible to define different transitions for different days?

The Sonoff TRVs (and the ZCL specification) allow a different schedule to be configured for each day, so I guess I'd be looking for something similar to this:

{
    "weekly_schedule": {
        "monday": {
            "transitions": [
                {
                    "heatSetpoint": 16,
                    "transitionTime": {
                        "hour": 0,
                        "minute": 0
                    }
                },
                {
                    "heatSetpoint": 20,
                    "transitionTime": {
                        "hour": 18,
                        "minute": 0
                    }
                },
                {
                    "heatSetpoint": 16,
                    "transitionTime": {
                        "hour": 19,
                        "minute": 30
                    }
                }
            ]
        },
        "tuesday": {
            "transitions": [
                {
                    "heatSetpoint": 16,
                    "transitionTime": {
                        "hour": 0,
                        "minute": 0
                    }
                },
                {
                    "heatSetpoint": 20,
                    "transitionTime": {
                        "hour": 18,
                        "minute": 0
                    }
                }
            ]
        },
        "wednesday": {
            "transitions": [
                {
                    "heatSetpoint": 16,
                    "transitionTime": {
                        "hour": 0,
                        "minute": 0
                    }
                }
            ]
        },
        "thursday": {
            "transitions": [
                {
                    "heatSetpoint": 16,
                    "transitionTime": {
                        "hour": 0,
                        "minute": 0
                    }
                },
                {
                    "heatSetpoint": 20,
                    "transitionTime": {
                        "hour": 18,
                        "minute": 0
                    }
                },
                {
                    "heatSetpoint": 16,
                    "transitionTime": {
                        "hour": 19,
                        "minute": 30
                    }
                },
                {
                    "heatSetpoint": 20,
                    "transitionTime": {
                        "hour": 21,
                        "minute": 00
                    }
                }
            ]
        },
		...
    }
}

Was this something you ever considered?

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Nov 14, 2023

You can specify different schedules for different days.

export name=trv/office
mosquitto_pub -t zigbee2mqtt/${name}/set/clear_weekly_schedule -m ''
mosquitto_pub -t zigbee2mqtt/${name}/set -m '{"weekly_schedule":{"dayofweek":["monday","tuesday","wednesday","thursday","friday"],"transitions":[{"transitionTime":"00:00","heatSetpoint":16},{"transitionTime":"07:00","heatSetpoint":18}]}}'
mosquitto_pub -t zigbee2mqtt/${name}/set -m '{"weekly_schedule":{"dayofweek":["saturday","sunday"],"transitions":[{"transitionTime":"00:00","heatSetpoint":16},{"transitionTime":"09:00","heatSetpoint":18}]}}'

If the device supports it you can add multiple schedules, the H1 seems to be rather picky as in theory since my schedule is the same, I could set it fro all days of the week but then the device doesn't execute it and the on device ui is broken.

Of I do weekdays + weekend days it works fine in 2 schedules. I also tested up to 4. It seems the Ubisys H1 at least support that as long as they don't overlap.

In theory the device can tell you about the limits, but I never tried to push the Ubisys H1 that far.
Screenshot 2023-11-14 at 10 35 17

It should support up to 10 transitions on a given day and that for each day of the week (10 * 7 = 70)

@photomoose
Copy link
Contributor

Yeah, I've seen multiple schedules working via MQTT, as you so describe - however, it looks the ability to do this in the frontend is lacking, if I'm not mistaken. I haven't yet seen a way to define multiple schedules in the UI.

Just considering whether it's worth changing the frontend to do this...

@sjorge
Copy link
Sponsor Contributor Author

sjorge commented Nov 14, 2023

/*
* We want to support a simple human creatable format to send a schedule:
{"weekly_schedule": {
"dayofweek": ["monday", "tuesday"],
"transitions": [
{"heatSetpoint": 16, "transitionTime": "0:00"},
{"heatSetpoint": 20, "transitionTime": "18:00"},
{"heatSetpoint": 16, "transitionTime": "19:30"}
]}}
* However exposes is not flexible enough to describe something like this. There is a
* much more verbose format we also support so that exposes work.
{"weekly_schedule": {
"dayofweek": [
{"day": "monday"},
{"day": "tuesday"}
],
"transitions": [
{"heatSetpoint": 16, "transitionTime": {"hour": 0, "minute": 0}},
{"heatSetpoint": 20, "transitionTime": {"hour": 18, "minute": 0}},
{"heatSetpoint": 16, "transitionTime": {"hour": 19, "minute": 30}}
]}}
*/

It was already very hard to get it to work in the frontend at all :(

You can in theory apply one, refresh the page and apply the 2nd one, .. repeat
Not sure there is a easy way to execute the clear all the schedule though, neither of the TRV I had at hand to test seem to support reading back the schedule, although there is technically a command for that on the hvacThermostat cluster.

I just use it over MQTT and clear + set + set, everytime I want to change something

@photomoose
Copy link
Contributor

My Sonoff TRVs only report back the schedule when the device is first paired and when the schedule is modified for a given day. The schedule is reported back in a series of messages, one per day, with each day having its own schedule. This obviously causes issues with the state in Z2M - fromZigbee.ts assumes only one message will be received, so the last message received is the winner when updating the state. It wouldn't be too difficult for me to change that behaviour, however.

Maybe I'll look at it, maybe I won't...it's not a feature I will personally use anyway (I use Home Assistant for scheduling) - however I always like a challenge. (And perhaps it might be useful to some people out there who use Z2M simply as a hub replacement rather than integration with HA, if there are indeed any!).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants