i’ve tried to look up this problem/topic in different topics and external forums, but couldn’t be helped yet. How can I prevent repeated code? It is way too expensive (time to set it up and maintain it) to code the same code block repeated over and over again.
My case:
I have multiple rooms (total of 8) with the same sensor equipment of multisensor and window sensor for which I’d copy and pasted a bunch of code to add history stats, mold indicator and a template sensor:
You see that only the part of the name “xxx_open_count_1d” and part of entity_id “binary_sensor.xxx” needs to be manually put into a template piece of code. I would think of something like this:
Everything stays the same, except of course the name of the sensor based on each room and possibly the calibration_factor. This would be a huge help, otherwise i have at least 1000 lines of code for this simple setup.
Sorry but why not create a package for each room.
The first room is hand written the next room just copied with a file name change then use search and replace on the entities, you did use a structure for your entity naming didn’t you ?
Yes, you are right - i just structured naming. Your idea is a first simple solution to my problem.
But still it would be quite expensive to change e.g. the if-elif-else thresholds. In your case, if I wanted to change my limits from 80% to 85% would need to do it on all *.yaml files.
Would be best to have it in one place, and then refer to it from each other area/group.
So put ALL those sensors in one file to create the values used in other packages.
I’m not sure what the purpose of this thread is meant to be.
Do you want a solution or just to nit pick small issues ?
This can be done (I do it) if the software could read your mind it would be a lot easier.
That ain’t gonna happen so make the best use of the alternatives you have
I dont want to nit pick small issues. With your first proposal i would make my life easier, but I was challenging for a better solution. Thought it would be possible. My main aim is to check, if it is currently possible to create complex templates, e.g. simply to clone same settings via an easy call of that template. That this is based on a mold_indicator is just an example, i want to reuse the same concept for other sensors as well:
I would drop this and replace it by a Gauge Card in the UI with thresholds and colors Because this „sensor“ is not about gathering data, but visualization
Finity,
I don’t use yaml anchors, my primary thoughts about their use would be to help with repetitive code used in lovelace ??? (please correct me)
The reason I think there would be an issue here is that the OP wants to have the same automations, sensors, helpers available across many rooms - all to the same pattern
So just for one example automation stolen at random from one of mine : -
- alias: au_light_kitchenled_mosen_on
mode: single
max_exceeded: silent
trigger:
- platform: state
entity_id: binary_sensor.bs_light_kitchen_motion
to: 'on'
- platform: state
entity_id: light.fibdim2_kitf_level
from: 'on'
to: 'off'
- platform: state
entity_id: light.fibdim2_kitr_level
from: 'on'
to: 'off'
condition:
- condition: state
entity_id: binary_sensor.bs_light_kitchen_motion
state: 'on'
- condition: state
entity_id: binary_sensor.bs_aalight_mosen_nightslot
state: 'on'
- condition: state
entity_id: light.fibrgbw441_kitn_level_wte
state: 'off'
- condition: state
entity_id: light.fibrgbw441_kitn_level_mstr
state: 'off'
- condition: state
entity_id: light.fibdim2_kitf_level
state: 'off'
- condition: state
entity_id: light.fibdim2_kitr_level
state: 'off'
action:
- service: input_boolean.turn_on
entity_id: input_boolean.ib_light_kitchenled_mosen_triggered
- service: light.turn_on
entity_id: light.fibrgbw441_kitn_level_wte
So lets break this down into bits that could be directed from a yaml anchor and the specific entities that NEED to be in place to make this automation unique to ‘a particular room’
- alias: au_light_kitchenled_mosen_on # text needed to make the automation unique
anchor01 - text common to all instances of this automation (but only the first part)
# mode: single
# max_exceeded: silent
# trigger:
# - platform: state ## so 4 lines replaced with one anchor
entity_id: binary_sensor.bs_light_kitchen_motion # specific to the entities in this room
anchor02 - text common to all instances of this automation (the second part)
# to: 'on'
# - platform: state ## so 2 lines replaced with one anchor
entity_id: light.fibdim2_kitf_level # specific to the entities in this room
anchor03 - text common to all instances of this automation (the third part)
# from: 'on'
# to: 'off'
# - platform: state ## so 3 lines replaced with one anchor
entity_id: light.fibdim2_kitr_level # specific to the entities in this room
anchor04 - text common to all instances of this automation (the forth part)
# from: 'on'
# to: 'off'
# condition:
# - condition: state ## so 4 lines replaced with one anchor
entity_id: binary_sensor.bs_light_kitchen_motion # specific to the entities in this room
anchor05 - text common to all instances of this automation (the fifth part)
# state: 'on'
# - condition: state ## so 2 lines replaced with one anchor
entity_id: binary_sensor.bs_aalight_mosen_nightslot # specific to the entities in this room
anchor06 - text common to all instances of this automation (the sixth part)
# state: 'on'
# - condition: state ## so 2 lines replaced with one anchor
entity_id: light.fibrgbw441_kitn_level_wte # specific to the entities in this room
anchor07 - text common to all instances of this automation (the seventh part)
# state: 'off'
# - condition: state ## so 2 lines replaced with one anchor
entity_id: light.fibrgbw441_kitn_level_mstr # specific to the entities in this room
anchor08 - text common to all instances of this automation (the eigth part)
# state: 'off'
# - condition: state ## so 2 lines replaced with one anchor
entity_id: light.fibdim2_kitf_level # specific to the entities in this room
anchor09 - text common to all instances of this automation (the ninth part)
# state: 'off'
# - condition: state ## so 2 lines replaced with one anchor
entity_id: light.fibdim2_kitr_level # specific to the entities in this room
anchor10 - text common to all instances of this automation (the tenth part)
# state: 'off'
# action:
# - service: input_boolean.turn_on ## so 3 lines replaced with one anchor
entity_id: input_boolean.ib_light_kitchenled_mosen_triggered # specific to the entities in this room
anchor11 - text common to all instances of this automation (the eleventh part)
# - service: light.turn_on ## so 1 line replaced with one anchor
entity_id: light.fibrgbw441_kitn_level_wte # specific to the entities in this room
This is based on a pnbruckner example where he placed the referenced yaml in a single file, I admit that I may have gotten the syntax wrong as I have never actually used it (again please correct me)
But the result of the 39 line automation would be these 23 lines AND the reference yaml in the file (but that would be reused across all the relevant instances)
However, I couldn’t read this. I couldn’t fault find it and ‘if’ a breaking change came through I’d have no idea where to start.
This is a slightly confusing statement
So what I think you mean by this is (correct me if I’m wrong as the best way to ensure understanding is to restate a concept back to the originator and look for agreement) : -
You want to store a template that takes various entity states (different for each room) processes a statement/mathematical operation, spits out an answer (into each room) so that it can be used as a sensor/in an autmation/set a value ???
In short, the answer is no !
A template only lives for the duration of that template being processed (it’s result does not persist unless you have stored it in (say) an input number. This input number would be defined in the template and therefore would have to be unique and thus it defeats your objective)
You are able to define a ‘macro’ within a template and use it recursively within that template (eg adding units to distinct units : - “2 days 4 hours and 13 minutes”) but this is only within that template so will not survive.
What in essence you are looking for is to define a ‘function’ available to the jinja2 templating engine, to process as you wish. Not just once but for any process you wish, bdraco recently did exactly this with his as_local() function that converted any timestamp (assuming it was UTC (all HA generated timestamps are)) into a local timestamp using the TZ offset stored in the local instance.
He is a developer, with the ear of Paulus and he did it quite quickly but …
Extending this wider would bloat the code base, slowing HA etc. and would be impossible to keep track of.
So definately No
Yep, that would also work but inherently that does not allow the reuse of the defining code. it merely moves it from yaml, into the configuration of the card (probably in JSON within the .storage folder losing the ability to share the code with others) and would require coding for each instance (you could probably copy and tweak but that is what I’m suggesting above anyway)
However your suggestion has the benefit of presenting it nicely in the front end too - so a double win if that is the OP’s secondary goal
I agree with @Mutt here. This would just shift the “problem” into another area. On top, I use that template sensor not as a gauge but as an custom:multiple-entity-row:
that’s true but I don’t think it is limited only to Lovelace. It should work for all yaml configurations.
I’m not sure where it ewas specifically stated that it was to be over several rooms (maybe wishful thinking on your part since that seems to be the go to example in your quest to spread the “package gospel” around here ) but I don’t thyink that would matter.
the “all to the same pattern” is the important bit. And I believe that’s what yaml anchors can do.
But again, I don’t use them either so I can’t say for absolute sure that it would solve the situation.
To my understanding you can use yaml anchors in any file you want. You can even use them in your beloved packages…
But. no. I don’t know that I would necessarily use them in any automations. But maybe I would if I knew more about their use.
But anyway, I’ve offered my suggestions and I’m not sure the OP has looked into it yet.