WTH Why doesn't home assistant know that a scene is active?

Hello @frenck,

My name is Hanan and for the past couple of years, I have been working on a project that aims to revolutionize smart homes and make them accessible to everyone.
I named it Ciara, and it is designed to create a dream automated home without the need for complex manual setup and maintenance.

Ciara generates a beautiful and responsive interface, along with advanced automations based on the devices in your home, without requiring any coding. My target audience includes everyone, including my mom and dad. It connects seamlessly with all the devices in your home, building a smart home interface and automations through a simple and minimal onboarding process.

Additionally, Ciara runs a full home assistant under the hood, ensuring that advanced users have the flexibility they desire.
Here are a few reference screenshots:

Since stateful scenes are very important for Ciara,
I have implemented stateful scenes by creating mqtt scenes (used as triggers only) and attaching an external scene_info sensor to each scene. It seems to be working just fine, at least with the 150+ different devices I have tested it.

Initially, I did not consider the possibility that a device might convert the requested state and attributes of an entity into another format. Thank you for reminding me of this potential issue. To address it, I implemented a simple solution:

  1. The first state for a newly created scene is set to “never_ran”.
  2. After first execution, I record the changes for all the entities in this “never_ran” scene. (I assume that if the scene.apply actually changed an entity, this is how the scene needs it to be when it’s active).
    The way I ensure all the relevant entities change their state is by pushing a dummy attribute as one of the entity’s attributes before I apply the scene and expect it to be overwritten when the actual device has done it’s thing and published it’s updated state and attributes.
  3. After that, I just track changes to entities and update scenes that includes the triggered entity by comparing the entity to the first run recorded state.
    The scene state at this phase is either “active” or “not_active” and updates automatically when an entities changes.
  • Bottom line is that my scenes can be in states “never_ran”, “active” or “not_active”.
  • You also need to consider the fact that some entities might not be available when the scene is created. (my fix for that is out of this scope and involves a mechanism that ensures execution of the last desired state of unavailable entities, extremely useful for reliability).

For you guys in home assistant, it should be much easier to implement stateful scenes since the scene editor already sets all the attributes to what the device is reporting when scenes are created from the GUI and you can skip the “never_ran” state that I had to use.
For YAML scenes, you can use my approach with this “never_ran” state.

I hope that you reconsider adding this feature back. I know it’s possible because I already did that.
I’m using them everywhere, querying scenes states in automations makes automations very simple and readable and also very powerful, this is why I spent so much time creating this mechanism.

Do you think I am missing something that might catch me by surprise later?
Unfortunately, my code is communicating with home assistant using API calls (REST and WS) so I can’t contribute it directly, but I will gladly help you with the design.

1 Like

I don’t know if it is still relevant, but how about a drop down helper that contains the numbers 0 to 9 as an example.
In each scene the helper is installed and gets a different value.
Now you would only have to color it somehow with custom button card if the scene has the matching value. It could be an option.

background-color: '[[[ if (states["input_select.scenen_test_aktiv"].state == 3) return "green"; return "red";]]]'

Something like this :sweat_smile:

Edit:

Tested it myself.

          - type: custom:button-card
            entity: scene.stream_orange
            template:
              - room_basic
            color: orange
            name: Orange
            tap_action:
              action: toggle
            styles:
              card:
                - background-color: '[[[ if (states["input_select.szenen_helfer_buro"].state == 4) return "var(--tile-background-color-active)"; return "var(--tile-background-color-inactive)";]]]'
                - color: '[[[ if (states["input_select.szenen_helfer_buro"].state == 4) return "var(--tile-text-color-active)"; return "var(--tile-text-color-inactive)";]]]'

Works like a charm for me. What I’ve also done, since all lights in the room are always in a group, a small automation that sets the dropdown to 0 when all lights are off. You could also activate the scene for “all off” instead.

1 Like

This is the biggest flaw in Home Assistant.

I bought a new home 2 years ago and it had Control4 installed, in the past I controlled all my homes using just home assistant. Honestly I don’t like control4, the only reason I am keeping it is because they’re switches on the wall… AND scene handling.

This is where I think home assistant should take note from their book. Scene handling in control4 is amazing, in home assistant unfortunately it feels years behind and it’s strange because when it comes to smart home preset scenes is the most used feature.

And after years of reading people wanting this feature improved it feels like it gets swept under the rug.

Having sensors that can detect if a scene is active or not it’s such a useful feature for user experience and other use cases. And it also feels like it’s a pretty simple feature to implement.

Also building lighting scenes is not very intuitive on home assistant today. Control 4 has a pretty easy way of selecting the lights you want and then using an action button record the current states of the selected lights so that you can walk around your house adjust the lights until you are happy and then simply “snapshot” it. Maybe this feature has been added since I last played with scenes but have not seen it in any release notes.

Long term home assistant user and fan, this has always been a disappointment in my eyes. Hopefully more people can get behind this to where it feels like an important feature to add.

Based on frenck’s reply last year (third post), you’ll have to live with it for the foreseeable future.

Depending on your requirements, you may find the workaround, I posted above, useful.

Is that spoken from the perspective of a software developer with a deep knowledge of python and Home Assistant’s architecture? Because frenck is.

Yes, I’ve been building software, apps and sites for 15-20 years. Also this is not a fud on Hassio or their development capabilities. To me it’s an overlooked feature mainly because they feel it’s not an important one. But for a while I did smart home installments and actually was trying to push home assistant on client rather than other all in one services and the most important thing for all clients were scene building. And for me to even show em how to build a scene was way to complex, and I agree cause even I who has much experience feels it’s not there yet.

In that case, you may wish to consider contributing to the project. Because it’s an architectural change, your first step is to explain the merits of your proposal and how it will mitigate the challenges frenck mentioned above. You can start the conversation here (note this repo’s Discussion is for developers intending to implement their proposal; it’s not for Feature Requests from the general public).

Or you can try using GitHub - hugobloem/stateful_scenes: Stateful Scenes in Home Assistant (Home Kit scene compatible)

which intends to create this feature - like it did in the past, though i suspect, the same issues around rounding etc. may be an issue.

2 Likes

Hi,

The integration does check for rounding and has a tolerance value to work around this.

My automations update a helper called room_last_scene_set and then my automations can determine their actions based on the helper or if the light group is actually off.

motion → lights off → activate scene walk-in, update helper
motion → lights on → is last scene activated walk-in → extend the motion timer.
motion → lights on → is another scene active → ignore the motion
motion timer expired → is last scene activated still walk-in → then turn off the lights.
light dimmer switch → set scene and update helper

I wonder if it was possible to…

  1. have entities for Areas
  2. be able to set attributes to area.entities
  3. have Scenes automatically update last_scene attribute for each area they change a device state in
  4. be able to read that attribute in any automations which might change the states of devices in the area (well, yes, this is obviously possible, given the first three)

I never had the need for that feature, but I think it should be easy to use a template switch for each scene that you want to have a state:
turn_on action = activate scene
value_template = a template, that checks all the single states if they are in a certain range
e.g. light.a brightness get set to 70% by the scene => check in the template if it’s beween 68 and 72% for example. With and in the template you can check all of them.
As soon as one light changes its brightness or gets turned off, the state of the scene will be off - that’s the behavior I would expect.

value_template could look like this:

{{ (225 < state_attr('light.dim_a', 'brightness') < 235) 
   and (170 < state_attr('light.dim_b', 'brightness') < 180) 
   and is_state('light.on_off_c','on') }}
1 Like

Hi community, I published an integration that enables scenes with states. I am running it in my own instance and it quickly updates the state of a scene when an entity is changed.

I created a thread here.

And the repo is here: https://www.github.com/hugobloem/stateful_scenes

4 Likes

Another solution might be to add a valid attribute to the scene, which is true when the scene is turned_on and false when any of the entities part of the scene changes.

@stevegroom

Could be very useful in my case. Mind share your code ? Much appreciated.

Sure,
not sure how shareable this is

First up to make my flows modular, each room uses a different flow. There are several sub flows that are then shared with these flows.

The flow defines an env var called roominfo which is a json string. This is copied to msg.roominfo before the sub flow is called.

{
    "area": "livingroom",
    "dimmers": [
        {
            "name": "button.livingroom_remote_1_identify",
            "type": "Hue v2",
            "device_ieee": "00:17:88:01:0c:26:5b:0f"
        },
        {
            "name": "button.livingroom_remote_2_identify",
            "type": "Hue v2",
            "device_ieee": "00:17:88:01:0b:dc:74:4c"
        },
        {
            "name": "button.sunroom_dimmer_identify",
            "type": "Hue v1",
            "device_ieee": "00:17:88:01:02:0d:86:a5"
        }
    ],
    "heating": {
        "boost_timer": "timer.livingroom_heating_boost_timer",
        "helper": "input_text.livingroom_heating_target",
        "switch_off": "switch.livingroom_switch_heat_off",
        "switch_set_back": "switch.livingroom_switch_heat_set_back",
        "switch_comfort": "switch.livingroom_switch_heat_comfort",
        "switch_boost": "switch.livingroom_switch_heat_boost",
        "target_set_back": "input_number.livingroom_heating_target_set_back",
        "target_comfort": "input_number.livingroom_heating_target_comfort",
        "target_boost": "input_number.livingroom_heating_target_boost",
        "thermostat": [
            {
                "entity_id": "climate.livingroom_heating_thermostat"
            },
            {
                "entity_id": "climate.sun_room_heating_thermostat"
            }
        ]
    },
    "illuminance_sensors": [
        {
            "name": "sensor.livingroom_sensor_illuminance"
        }
    ],
    "light": "light.livingroom",
    "occupancy_sensors": [
        {
            "name": "binary_sensor.livingroom_sensor_occupancy"
        }
    ],
    "occupancy_timer": "timer.livingroom_occupancy",
    "scene_helper": "input_text.livingroom_last_scene",
    "scene_motion_sensor_enabled": "input_boolean.livingroom_motion_sensor_enabled"
}

This is copied to msg.roominfo whenever it is needed.

The flows then call on sub flows to reduce code duplication. This example gets the room info, sets a scene and records the scene in a text helper.

[{"id":"137ed56e0b5015e1","type":"subflow","name":"Set Scene v5","info":"","category":"","in":[{"x":80,"y":140,"wires":[{"id":"e54cee9257edcdaf"}]}],"out":[{"x":1660,"y":820,"wires":[{"id":"bff43720d24f9d66","port":0},{"id":"5d23706cfe0fb043","port":0},{"id":"7f7e6f274a90526d","port":0}]}],"env":[],"meta":{},"color":"#DDAA99"},{"id":"0b890180283dd5c1","type":"api-call-service","z":"137ed56e0b5015e1","g":"f4120b65f83a5848","name":"Start scene off w/ transition","server":"2be748d3.da7088","version":5,"debugenabled":false,"domain":"scene","service":"turn_on","areaId":[],"deviceId":[],"entityId":["{{payload.scene}}"],"data":"{ \"transition\": 0.5 }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[{"property":"data","propertyType":"msg","value":"","valueType":"data"}],"queue":"none","x":840,"y":620,"wires":[["d09d7d7b8f812c3b","7f7e6f274a90526d","0aeaad46bc62a728"]]},{"id":"394f521d4b3a3f34","type":"api-call-service","z":"137ed56e0b5015e1","g":"87f57958c3cdd168","name":"Record Scene","server":"2be748d3.da7088","version":5,"debugenabled":false,"domain":"input_text","service":"set_value","areaId":[],"deviceId":[],"entityId":["{{roominfo.scene_helper}}"],"data":"{ \"value\": payload.scene }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":400,"y":300,"wires":[["c913c90eb2d292d2","439836154dbadd50","2fdf80784d27261f"]]},{"id":"5f6c4b47b1849d6a","type":"switch","z":"137ed56e0b5015e1","g":"bdcae038ebeb553a","name":"Scene change required?","property":"payload.scene","propertyType":"msg","rules":[{"t":"neq","v":"payload.oldscene","vt":"msg"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":1030,"y":120,"wires":[["fa7214dcfcff0e28"],["cbc5de61a6780765"]],"outputLabels":["true","false"]},{"id":"f2785b29847a70ce","type":"switch","z":"137ed56e0b5015e1","g":"792a93e3f99f6b13","name":"","property":"payload.scene","propertyType":"msg","rules":[{"t":"regex","v":"(_off)$","vt":"str","case":false},{"t":"regex","v":"(_wake_up)$","vt":"str","case":false},{"t":"else"}],"checkall":"true","repair":false,"outputs":3,"x":430,"y":520,"wires":[["43f4e4b4b559f8d9"],["0b81d8a7b27ec6c8"],["cc0f5a900e3f5324"]]},{"id":"217e4a4ad253cbe4","type":"comment","z":"137ed56e0b5015e1","g":"f4120b65f83a5848","name":"Scene off with 2s transition","info":"","x":770,"y":520,"wires":[]},{"id":"456d3062c0dd1cd1","type":"comment","z":"137ed56e0b5015e1","g":"27e329858e567923","name":"Other scenes","info":"","x":730,"y":1020,"wires":[]},{"id":"d01c9f79f338291f","type":"api-call-service","z":"137ed56e0b5015e1","g":"27e329858e567923","name":"Set other scene types ","server":"2be748d3.da7088","version":5,"debugenabled":false,"domain":"scene","service":"turn_on","areaId":[],"deviceId":[],"entityId":["{{payload.scene}}"],"data":"{ \"transition\": 0.5 }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[{"property":"data","propertyType":"msg","value":"","valueType":"data"}],"queue":"none","x":840,"y":1100,"wires":[["c56347f18bb34632","bff43720d24f9d66"]]},{"id":"0aeaad46bc62a728","type":"api-call-service","z":"137ed56e0b5015e1","g":"f4120b65f83a5848","name":"Disable Motion Sensors","server":"2be748d3.da7088","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_off","areaId":[],"deviceId":[],"entityId":["{{roominfo.scene_motion_sensor_enabled}}"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":830,"y":660,"wires":[["0c6ad65519ec71cc","26d4510d57ea190b"]]},{"id":"d6a43b6044a87fd1","type":"api-call-service","z":"137ed56e0b5015e1","g":"f4120b65f83a5848","name":"Re-enable Motion Sensors","server":"2be748d3.da7088","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_on","areaId":[],"deviceId":[],"entityId":["{{roominfo.scene_motion_sensor_enabled}}"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1100,"y":700,"wires":[["47274fc7632c3d2a"]]},{"id":"f9223df401fc3b5f","type":"debug","z":"137ed56e0b5015e1","d":true,"g":"f4120b65f83a5848","name":"Disable motion sensors","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s \")\t& roominfo.area & \" disable motion sensors\"","targetType":"jsonata","statusVal":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s\")\t& \" Set scene w/ 2s transition: \"\t& payload.scene","statusType":"auto","x":830,"y":560,"wires":[]},{"id":"7867d7ecdb4d4bc2","type":"debug","z":"137ed56e0b5015e1","d":true,"g":"27e329858e567923","name":"Set scene other","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s\")\t& \" Set other scene types: \" \t& payload.scene","targetType":"jsonata","statusVal":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s\")\t& \" Set other scene types: \" \t& payload.scene","statusType":"auto","x":820,"y":1060,"wires":[]},{"id":"3571e0243c9f0cfc","type":"api-call-service","z":"137ed56e0b5015e1","g":"7229bbb1472593fd","name":"Start scene 60s transition","server":"2be748d3.da7088","version":5,"debugenabled":false,"domain":"scene","service":"turn_on","areaId":[],"deviceId":[],"entityId":["{{payload.scene}}"],"data":"{ \"transition\": 60 }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[{"property":"data","propertyType":"msg","value":"","valueType":"data"}],"queue":"none","x":830,"y":900,"wires":[["5d23706cfe0fb043"]]},{"id":"73f3834290341f0c","type":"comment","z":"137ed56e0b5015e1","g":"7229bbb1472593fd","name":"Scene on with 60s transition","info":"","x":780,"y":820,"wires":[]},{"id":"355ee809c9ed1f0b","type":"debug","z":"137ed56e0b5015e1","d":true,"g":"7229bbb1472593fd","name":"Set scene w/ 60s transition","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s\") & \" Set scene w/ 60s transition\"","targetType":"jsonata","statusVal":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s\") & \" Set scene w/ 60s transition\"","statusType":"auto","x":840,"y":860,"wires":[]},{"id":"b5cc8749cbc866a1","type":"debug","z":"137ed56e0b5015e1","d":true,"g":"db8c65ba9d3447d6","name":"dimmer check scene?","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"$formatNumber(($millis()-timestamp)/1000,\"#0.000\") & \"s Chg rqd? \" \t& $$.roominfo.scene_helper \t& \" vs. \" & payload.scene ","targetType":"jsonata","statusVal":"$formatNumber(($millis()-timestamp)/1000,\"#0.000\") & \"s Chg rqd? \" \t& $$.roominfo.scene_helper \t& \" vs. \" & payload.scene ","statusType":"auto","x":440,"y":1240,"wires":[]},{"id":"e42655aafa84eb25","type":"switch","z":"137ed56e0b5015e1","g":"db8c65ba9d3447d6","name":"scene == .*_off ? ","property":"payload.scene","propertyType":"msg","rules":[{"t":"regex","v":"(_off)$","vt":"str","case":false},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":510,"y":1320,"wires":[["529425ca9a57e2ec","535f857975b17184"],["30967c299f92b442"]]},{"id":"529425ca9a57e2ec","type":"api-current-state","z":"137ed56e0b5015e1","g":"db8c65ba9d3447d6","name":"Continue if lights are not off","server":"2be748d3.da7088","version":3,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","entity_id":"","state_type":"str","blockInputOverrides":false,"outputProperties":[],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":860,"y":1260,"wires":[[],["097658f886fd0d33"]]},{"id":"30967c299f92b442","type":"api-current-state","z":"137ed56e0b5015e1","g":"db8c65ba9d3447d6","name":"Continue if lights are not on","server":"2be748d3.da7088","version":3,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"","state_type":"str","blockInputOverrides":false,"outputProperties":[],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":860,"y":1300,"wires":[[],["a85c3f3a72d81a81"]]},{"id":"54f1e0390d264951","type":"api-call-service","z":"137ed56e0b5015e1","g":"db8c65ba9d3447d6","name":"Log entry in Logbook","server":"2be748d3.da7088","version":5,"debugenabled":false,"domain":"logbook","service":"log","areaId":[],"deviceId":[],"entityId":[],"data":"{\"name\":\"W01 Subflow Set Scene warning\",\"message\":\"scene mismatch\"}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1360,"y":1260,"wires":[[]]},{"id":"097658f886fd0d33","type":"api-call-service","z":"137ed56e0b5015e1","g":"db8c65ba9d3447d6","name":"Retry scene.{room}_off","server":"2be748d3.da7088","version":5,"debugenabled":true,"domain":"scene","service":"turn_on","areaId":[],"deviceId":[],"entityId":["{{payload.scene}}"],"data":"{ \"transition\": 0.1 }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[{"property":"data","propertyType":"msg","value":"","valueType":"data"}],"queue":"none","x":1120,"y":1260,"wires":[["54f1e0390d264951"]]},{"id":"a85c3f3a72d81a81","type":"api-call-service","z":"137ed56e0b5015e1","g":"db8c65ba9d3447d6","name":"Retry other scene types ","server":"2be748d3.da7088","version":5,"debugenabled":false,"domain":"scene","service":"turn_on","areaId":[],"deviceId":[],"entityId":["{{payload.scene}}"],"data":"{ \"transition\": 0.1 }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[{"property":"data","propertyType":"msg","value":"","valueType":"data"}],"queue":"none","x":1130,"y":1300,"wires":[["599ead04ff8aa180"]]},{"id":"599ead04ff8aa180","type":"api-call-service","z":"137ed56e0b5015e1","g":"db8c65ba9d3447d6","name":"Log entry in Logbook","server":"2be748d3.da7088","version":5,"debugenabled":false,"domain":"logbook","service":"log","areaId":[],"deviceId":[],"entityId":[],"data":"{\"name\":\"W02 Subflow Set Scene warning\",\"message\":\"scene mismatch\"}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1360,"y":1300,"wires":[[]]},{"id":"c913c90eb2d292d2","type":"change","z":"137ed56e0b5015e1","d":true,"g":"87f57958c3cdd168","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"","tot":"date"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":340,"wires":[["1b62bc957585dcfe"]]},{"id":"1b62bc957585dcfe","type":"api-call-service","z":"137ed56e0b5015e1","d":true,"g":"87f57958c3cdd168","name":"Log entry in Logbook","server":"2be748d3.da7088","version":5,"debugenabled":false,"domain":"logbook","service":"log","areaId":[],"deviceId":[],"entityId":[],"data":"{\t   \"name\":\"Debug perf\",\t   \"message\":\"Debug NR rec scene done \" & $fromMillis(payload),\t   \"entity_id\":\"binary_sensor.steves_office_sensor_2_occupancy\"\t}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":800,"y":400,"wires":[[]]},{"id":"66f6af9c9cccedfa","type":"comment","z":"137ed56e0b5015e1","g":"db8c65ba9d3447d6","name":"Handle inconsistancies","info":"","x":440,"y":1200,"wires":[]},{"id":"c56347f18bb34632","type":"change","z":"137ed56e0b5015e1","d":true,"g":"27e329858e567923","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"","tot":"date"}],"action":"","property":"","from":"","to":"","reg":false,"x":1180,"y":1060,"wires":[["fc8dc9c3c6ca8195"]]},{"id":"fc8dc9c3c6ca8195","type":"api-call-service","z":"137ed56e0b5015e1","g":"27e329858e567923","name":"Log entry in Logbook","server":"2be748d3.da7088","version":5,"debugenabled":false,"domain":"logbook","service":"log","areaId":[],"deviceId":[],"entityId":[],"data":"{\t   \"name\":\"Debug perf\",\t   \"message\":\"Debug NR set scene done \" & $fromMillis(payload),\t   \"entity_id\":\"binary_sensor.steves_office_sensor_2_occupancy\"\t}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1400,"y":1060,"wires":[[]]},{"id":"439836154dbadd50","type":"api-call-service","z":"137ed56e0b5015e1","g":"87f57958c3cdd168","name":"Log entry in Logbook","server":"2be748d3.da7088","version":5,"debugenabled":false,"domain":"logbook","service":"log","areaId":[],"deviceId":[],"entityId":[],"data":"{\"name\":\"W04 Subflow Set Scene debug payload\",\"message\": payload.scene}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":800,"y":300,"wires":[[]]},{"id":"b3617cce2531d569","type":"catch","z":"137ed56e0b5015e1","g":"6128cca7d51856c2","name":"Record scene failed?","scope":["394f521d4b3a3f34"],"uncaught":false,"x":360,"y":1460,"wires":[["77747a181fd0c07c"]]},{"id":"77747a181fd0c07c","type":"debug","z":"137ed56e0b5015e1","g":"6128cca7d51856c2","name":"Record scene failed (too long)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":630,"y":1460,"wires":[]},{"id":"2fdf80784d27261f","type":"debug","z":"137ed56e0b5015e1","d":true,"g":"87f57958c3cdd168","name":"debug 372","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":570,"y":360,"wires":[]},{"id":"e54cee9257edcdaf","type":"ha-get-entities","z":"137ed56e0b5015e1","g":"bdcae038ebeb553a","name":"Get old scene from roominfo.scene_helper","server":"2be748d3.da7088","version":0,"rules":[{"property":"entity_id","logic":"is","value":"roominfo.scene_helper","valueType":"msg"}],"output_type":"array","output_empty_results":true,"output_location_type":"msg","output_location":"oldscene","output_results_count":1,"x":410,"y":120,"wires":[["f81d5704c6b45860"]]},{"id":"8ae8db991392096a","type":"debug","z":"137ed56e0b5015e1","d":true,"g":"bdcae038ebeb553a","name":"SetScene","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s\") \t& \" Set scene: \"  & payload.scene","targetType":"jsonata","statusVal":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s\") \t& \" Set scene: \"  & payload.scene","statusType":"auto","x":980,"y":160,"wires":[]},{"id":"f81d5704c6b45860","type":"change","z":"137ed56e0b5015e1","g":"bdcae038ebeb553a","name":"set oldscene","rules":[{"t":"move","p":"oldscene[0].state","pt":"msg","to":"payload.oldscene","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":730,"y":120,"wires":[["8ae8db991392096a","5f6c4b47b1849d6a"]]},{"id":"0c6ad65519ec71cc","type":"debug","z":"137ed56e0b5015e1","d":true,"g":"f4120b65f83a5848","name":"Disable motion sensors","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s \")\t& roominfo.area & \" disabled motion sensors\"","targetType":"jsonata","statusVal":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s\") & \" Disable motion sensors\"","statusType":"auto","x":1130,"y":660,"wires":[]},{"id":"d09d7d7b8f812c3b","type":"debug","z":"137ed56e0b5015e1","d":true,"g":"f4120b65f83a5848","name":"scene w/ transition set","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s \")\t& roominfo.area \t& \" - \" \t& payload.scene\t& \" set.\"","targetType":"jsonata","statusVal":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s\") & \" Set scene w/ 1.5s transition \" & payload.scene","statusType":"auto","x":1120,"y":620,"wires":[]},{"id":"47274fc7632c3d2a","type":"debug","z":"137ed56e0b5015e1","d":true,"g":"f4120b65f83a5848","name":"Re enable motion","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s\") & \" Re-enable motion\"","targetType":"jsonata","statusVal":"$formatNumber(($millis()-timestamp)/1000,\"#0.000s\") & \" Re-enable motion\"","statusType":"auto","x":1410,"y":700,"wires":[]},{"id":"26d4510d57ea190b","type":"ha-wait-until","z":"137ed56e0b5015e1","g":"f4120b65f83a5848","name":"Delay 5 seconds","server":"2be748d3.da7088","version":2,"outputs":2,"entityId":"light.bedroom","entityIdFilterType":"exact","property":"state","comparator":"is","value":"999","valueType":"str","timeout":"5","timeoutType":"num","timeoutUnits":"seconds","checkCurrentState":true,"blockInputOverrides":true,"outputProperties":[],"entityLocation":"data","entityLocationType":"none","x":810,"y":700,"wires":[[],["d6a43b6044a87fd1"]]},{"id":"c4de22ee7980331f","type":"catch","z":"137ed56e0b5015e1","g":"6128cca7d51856c2","name":"General failure","scope":["0b890180283dd5c1","5f6c4b47b1849d6a","f2785b29847a70ce","217e4a4ad253cbe4","456d3062c0dd1cd1","d01c9f79f338291f","0aeaad46bc62a728","d6a43b6044a87fd1","f9223df401fc3b5f","7867d7ecdb4d4bc2","3571e0243c9f0cfc","73f3834290341f0c","355ee809c9ed1f0b","b5cc8749cbc866a1","e42655aafa84eb25","529425ca9a57e2ec","30967c299f92b442","54f1e0390d264951","097658f886fd0d33","a85c3f3a72d81a81","599ead04ff8aa180","c913c90eb2d292d2","1b62bc957585dcfe","66f6af9c9cccedfa","c56347f18bb34632","fc8dc9c3c6ca8195","439836154dbadd50","b3617cce2531d569","77747a181fd0c07c","e54cee9257edcdaf","8ae8db991392096a","f81d5704c6b45860","0c6ad65519ec71cc","d09d7d7b8f812c3b","47274fc7632c3d2a","26d4510d57ea190b","899745db9fe8f088","2fdf80784d27261f"],"uncaught":false,"x":330,"y":1500,"wires":[["899745db9fe8f088"]]},{"id":"899745db9fe8f088","type":"debug","z":"137ed56e0b5015e1","g":"6128cca7d51856c2","name":"general failure","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":580,"y":1500,"wires":[]},{"id":"53344284c0c3c22e","type":"change","z":"137ed56e0b5015e1","g":"db8c65ba9d3447d6","name":"set entityId from roominfo.light ","rules":[{"t":"set","p":"payload.entityId","pt":"msg","to":"roominfo.light","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":1280,"wires":[["e42655aafa84eb25","535f857975b17184"]]},{"id":"535f857975b17184","type":"debug","z":"137ed56e0b5015e1","d":true,"g":"db8c65ba9d3447d6","name":"debug 443","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":830,"y":1340,"wires":[]},{"id":"fa7214dcfcff0e28","type":"link out","z":"137ed56e0b5015e1","g":"bdcae038ebeb553a","name":"link out 94","mode":"link","links":["b6220a5c292e0131","46b449df9122b3ae"],"x":1255,"y":100,"wires":[]},{"id":"b6220a5c292e0131","type":"link in","z":"137ed56e0b5015e1","g":"792a93e3f99f6b13","name":"link in 63","links":["fa7214dcfcff0e28"],"x":265,"y":520,"wires":[["f2785b29847a70ce"]]},{"id":"46b449df9122b3ae","type":"link in","z":"137ed56e0b5015e1","g":"87f57958c3cdd168","name":"link in 64","links":["fa7214dcfcff0e28"],"x":265,"y":300,"wires":[["394f521d4b3a3f34"]]},{"id":"cbc5de61a6780765","type":"link out","z":"137ed56e0b5015e1","g":"bdcae038ebeb553a","name":"link out 95","mode":"link","links":["942bb9d1638646fb"],"x":1255,"y":160,"wires":[]},{"id":"942bb9d1638646fb","type":"link in","z":"137ed56e0b5015e1","g":"db8c65ba9d3447d6","name":"link in 65","links":["cbc5de61a6780765"],"x":275,"y":1200,"wires":[["b5cf3be53a55af57"]]},{"id":"cc0f5a900e3f5324","type":"junction","z":"137ed56e0b5015e1","g":"27e329858e567923","x":660,"y":1080,"wires":[["d01c9f79f338291f","7867d7ecdb4d4bc2"]]},{"id":"bff43720d24f9d66","type":"junction","z":"137ed56e0b5015e1","g":"27e329858e567923","x":1520,"y":1100,"wires":[[]]},{"id":"5d23706cfe0fb043","type":"junction","z":"137ed56e0b5015e1","g":"7229bbb1472593fd","x":1520,"y":900,"wires":[[]]},{"id":"0b81d8a7b27ec6c8","type":"junction","z":"137ed56e0b5015e1","g":"7229bbb1472593fd","x":660,"y":880,"wires":[["3571e0243c9f0cfc","355ee809c9ed1f0b"]]},{"id":"43f4e4b4b559f8d9","type":"junction","z":"137ed56e0b5015e1","g":"f4120b65f83a5848","x":680,"y":580,"wires":[["f9223df401fc3b5f","0b890180283dd5c1"]]},{"id":"7f7e6f274a90526d","type":"junction","z":"137ed56e0b5015e1","g":"f4120b65f83a5848","x":1520,"y":640,"wires":[[]]},{"id":"b5cf3be53a55af57","type":"junction","z":"137ed56e0b5015e1","g":"db8c65ba9d3447d6","x":320,"y":1260,"wires":[["53344284c0c3c22e","b5cc8749cbc866a1"]]},{"id":"c2f77dfb3eb38305","type":"group","z":"137ed56e0b5015e1","name":"Set scene and record in scene_helper","style":{"label":true,"stroke":"#000000","fill":"#e3f3d3","color":"#000000"},"nodes":["27e329858e567923","7229bbb1472593fd","f4120b65f83a5848","6128cca7d51856c2","db8c65ba9d3447d6","87f57958c3cdd168","792a93e3f99f6b13","bdcae038ebeb553a"],"x":188,"y":33},{"id":"27e329858e567923","type":"group","z":"137ed56e0b5015e1","g":"c2f77dfb3eb38305","name":"Normal turn on scenes","style":{"label":true,"fill":"#c8e7a7","color":"#000000"},"nodes":["d01c9f79f338291f","7867d7ecdb4d4bc2","c56347f18bb34632","fc8dc9c3c6ca8195","cc0f5a900e3f5324","456d3062c0dd1cd1","bff43720d24f9d66"],"x":634,"y":979},{"id":"7229bbb1472593fd","type":"group","z":"137ed56e0b5015e1","g":"c2f77dfb3eb38305","name":"Slow turn on scenes","style":{"label":true,"fill":"#c8e7a7","color":"#000000"},"nodes":["3571e0243c9f0cfc","355ee809c9ed1f0b","73f3834290341f0c","0b81d8a7b27ec6c8","5d23706cfe0fb043"],"x":634,"y":779},{"id":"f4120b65f83a5848","type":"group","z":"137ed56e0b5015e1","g":"c2f77dfb3eb38305","name":"Turn off scenes need to disable motion sensors","style":{"label":true,"fill":"#c8e7a7","color":"#000000"},"nodes":["0aeaad46bc62a728","0b890180283dd5c1","26d4510d57ea190b","d6a43b6044a87fd1","47274fc7632c3d2a","d09d7d7b8f812c3b","0c6ad65519ec71cc","f9223df401fc3b5f","217e4a4ad253cbe4","43f4e4b4b559f8d9","7f7e6f274a90526d"],"x":634,"y":479},{"id":"6128cca7d51856c2","type":"group","z":"137ed56e0b5015e1","g":"c2f77dfb3eb38305","name":"Record errors in debug","style":{"stroke":"#000000","label":true,"fill":"#ffbfbf","color":"#000000"},"nodes":["b3617cce2531d569","77747a181fd0c07c","c4de22ee7980331f","899745db9fe8f088"],"x":234,"y":1419},{"id":"db8c65ba9d3447d6","type":"group","z":"137ed56e0b5015e1","g":"c2f77dfb3eb38305","name":"","style":{"fill":"#ffffbf","label":true,"color":"#000000","stroke":"#000000"},"nodes":["b5cc8749cbc866a1","e42655aafa84eb25","529425ca9a57e2ec","30967c299f92b442","54f1e0390d264951","097658f886fd0d33","a85c3f3a72d81a81","599ead04ff8aa180","66f6af9c9cccedfa","53344284c0c3c22e","535f857975b17184","b5cf3be53a55af57","942bb9d1638646fb"],"x":234,"y":1159},{"id":"87f57958c3cdd168","type":"group","z":"137ed56e0b5015e1","g":"c2f77dfb3eb38305","name":"Record scene in helper","style":{"label":true,"fill":"#c8e7a7","color":"#000000"},"nodes":["394f521d4b3a3f34","c913c90eb2d292d2","1b62bc957585dcfe","439836154dbadd50","2fdf80784d27261f","46b449df9122b3ae"],"x":224,"y":259},{"id":"792a93e3f99f6b13","type":"group","z":"137ed56e0b5015e1","g":"c2f77dfb3eb38305","name":"Activate scene","style":{"label":true,"fill":"#c8e7a7","color":"#000000"},"nodes":["f2785b29847a70ce","b6220a5c292e0131"],"x":224,"y":471.5},{"id":"bdcae038ebeb553a","type":"group","z":"137ed56e0b5015e1","g":"c2f77dfb3eb38305","name":"Determine if scene change (or correction)","style":{"label":true,"stroke":"#000000","color":"#000000","fill":"#c8e7a7"},"nodes":["5f6c4b47b1849d6a","e54cee9257edcdaf","8ae8db991392096a","f81d5704c6b45860","fa7214dcfcff0e28","cbc5de61a6780765"],"x":214,"y":59},{"id":"2be748d3.da7088","type":"server","name":"Home Assistant","addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"","connectionDelay":false,"cacheJson":false,"heartbeat":true,"heartbeatInterval":"10","statusSeparator":"","enableGlobalContextStore":false},{"id":"edeb46a5bd917e55","type":"link in","z":"c478a5ca9411e98f","g":"e03f775a6380a8b0","name":"Turn on Sun Room","links":["94ba3d91773e3f7a"],"x":850,"y":1260,"wires":[["353b38701ac679f8"]],"l":true},{"id":"353b38701ac679f8","type":"change","z":"c478a5ca9411e98f","g":"e03f775a6380a8b0","name":"scene=sunroom_on","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"scene\":\"scene.sunroom_on\",\t   \"scene_helper\":\"input_text.sunroom_last_scene\",\t   \"scene_motion_sensor_enabled\":\"input_boolean.sunroom_motion_sensor_enabled\"\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":1300,"wires":[["3a346633bf2f97b0"]]},{"id":"aa6e970a32643fb9","type":"subflow:137ed56e0b5015e1","z":"c478a5ca9411e98f","g":"e03f775a6380a8b0","name":"","x":1350,"y":1600,"wires":[[]]}]

The sub flow can check if the scene was already set etc.

I have a couple of lights that occasionally don’t come on in a scene, I plan to add a test that could retry setting some of the lights on or off if they failed to react.

What I don’t like:
If I am making major updates, I like to clone a sub flow and link to it from one flow, and if ok, update the other flows to use the new sub flow. This results in a lot of manual editing of flows, so is error prone. I’m looking for a better way to manage versions and releases.

Steve

1 Like

Thanks for sharing. It is indeed a clever way to do it with Node-Red.

I’ve slightly improved on this and use the following template switches:

switch:   
- platform: template
  switches:
    scene_away:
      friendly_name: Scene Away
      value_template: |
        {{  
          is_state(      "alarm_control_panel.ha_alarm", "armed_away")      and 
          is_state(      "light.all_lights", "off")                         and
          is_state_attr( "climate.lisa_bedroom",     "preset_mode", "away") and
          is_state_attr( "climate.lisa_living_room", "preset_mode", "away") and
          is_state_attr( "climate.lisa_office",      "preset_mode", "away") 
        }}
            
      turn_on:
        service: script.scene_away
      turn_off:
        service: script.do_nothing

    scene_sleep:
      friendly_name: Scene Sleep
      value_template: |
        {{  
          is_state(      "alarm_control_panel.ha_alarm", "armed_night")       and 
          is_state(      "light.all_lights", "off")                           and
          is_state_attr( "climate.lisa_bedroom",     "preset_mode", "asleep") and
          is_state_attr( "climate.lisa_living_room", "preset_mode", "asleep") and
          is_state_attr( "climate.lisa_office",      "preset_mode", "asleep") 
        }}
            
      turn_on:
        service: script.scene_sleep
      turn_off:
        service: script.do_nothing

These template switches are exposed to homekit and are the only ones that will be in the homekit scene. It is actually even better than the homekit scenes themselves, because you can have more granular control over when a scene is ‘on’ (e.g. when climate has a certain preset that only Home Assistant knows about).

What is the improvement?

By stating the expected conditions for an ‘active scene’ in the value template, the template switch will always be on when the scene conditions are met (e.g all lights off, alarm on in my example).

By turning any light on or turning off the alarm in the examples I gave above, the template switch will turn off - which in turn also turns the scene in Homekit off.

@countertokens, this might be the solution you’re looking for.

Are you using the Template Switch to control a scene entity? In other words, does script.scene_away turn on a scene entity?