muxa / esphome-state-machine Goto Github PK
View Code? Open in Web Editor NEWESPHome State Machine component
License: MIT License
ESPHome State Machine component
License: MIT License
I would like to suggest an enhancement, which I fill may be extremely useful.
Adding possibility to specify the condition
parameter for transitions, like:
transitions:
- from: IDLE
to: SCANNING
condition:
lambda: ...
Thank you so much for this esphome component.
As a new user, I've been struggling to get a basic example working. I continued to get this error:
Must be string, got <class 'esphome.helpers.OrderedDict'>. did you forget putting quotes around the value?.
The reasoning wasn't clear to me until I found this gist for a garage door opener.
Basically the states
can be either
state_machine:
- name: Fan Mode
states:
- NORMAL
- SILENCED
or
state_machine:
- name: Fan Mode
states:
- name: NORMAL
on_enter:
- logger.log: "Fan is turned off"
- name: SILENCED
on_enter:
- logger.log: "Fan is turned on"
However, you can not do the following (which is what I was mistakenly doing)
state_machine:
- name: Fan Mode
states:
- id: NORMAL
on_enter:
- logger.log: "Fan is turned off"
- id: SILENCED
on_enter:
- logger.log: "Fan is turned on"
It may be obvious to others, but It wasn't clear to me that states
needs either a list of strings, or a list of dictionaries with key 'name'. An additional example in the readme may be helpful for others.
I'm trying to set light status in on_set
of the initial state, but it does not have effect.
- light.turn_on:
id: status
transition_length: 0s
brightness: 25%
red: 100%
green: 100%
blue: 100%
light:
- id: status
platform: neopixelbus
restore_mode: ALWAYS_ON
variant: SK6812
num_leds: 1
default_transition_length: 0s
pin: GPIO27
Probably initial state transition happens to early. In my logs I see it way before setup
finishes and config is dumped.
Light transition is visible in logs but ignored:
[21:23:06][D][light:035]: 'status' Setting:
[21:23:06][D][light:040]: Color mode: RGB
[21:23:06][D][light:046]: State: ON
[21:23:06][D][state_machine:085]: State set to STARTING
[21:23:06][D][light:035]: 'status' Setting:
[21:23:06][D][light:050]: Brightness: 25%
[21:23:06][D][light:058]: Red: 100%, Green: 100%, Blue: 100%
a suggestion for a feature.. If I could write C++ I would give you a push request :)
Timer Triggered Transitions
An Example Configuration with the suggestion integrated
state_machine:
- name: Sauna Controller
id: sauna_state_machine
states:
- "OFF"
- "ON"
- "HEATING"
initial_state: "OFF"
max_state_duration: 5400 # timer in seconds
expiry: # in this case, the sauna state will automatically switch to OFF after 5400 seconds (mimics the control board on the device)
state: "HEATING" # if in this state then send the trigger transition
trigger: power # the transition to trigger after timer expires
inputs:
- name: power
transitions:
- OFF -> ON
- ON -> OFF
- HEATING -> OFF
- name: heat
transitions:
- ON-> HEATING
- HEATING -> ON
When controlling, for instance, light wit a state machine, the light state will be restored from HA, but the state machine won't be.
We need a way to restore state machine initial state somehow.
On state_machine.set
Action docs:
Note that only the target state on_set automation will be triggered, and all other state machine automations (on_enter, on_leave and action of the inputs and transitions) will be skipped.
It would be great if we could have an option to directly set the state but still activate (at least) the on_enter
, of the inputs and transitions.
The use case here is a state machine with many complex states and transitions for a light switch with PIR motion sensor and led indicator light per switch. I want to push a HA dashboard button to set a mode/state directly. ie turn off motion mode, etc ect.
Without the above I would have to write complex logic in the device (using state_machine.state
etc) to first check what the current state of the machine is, and determine what sequence of transitions I need to action to arrive at the desired new state. It is like I have to write all possible state transitions again, not being DRY, and breaking when state machine logic is changed.
I need the on_enter
automation to run as it sets the light, sets the indicator led to show the mode etc etc.
I cannot easily just use the state_machine.transition
Action in my case as the transition action would be dependent on the current state.
Currently I guess an easier way would be to have more simple logic determining the state_machine.transition
Action required to reach the desired new state based on the current state, however this may sill break if the state machine logic is updated, and would still be complex on complex state machines.
For reference this is my project: https://community.home-assistant.io/t/australian-light-switch-with-motion-sensor-local-control-show-and-tell/444612
I've back in April 2022 I've upgrade ESPHome to 2022.2 and started experiencing crashes of ESP8266 nodes. I pin pointed this to ESP8266 framework upgrade from 2.7.4
to 3.0.2
(https://esphome.io/changelog/2022.2.0.html).
I have not found the root cause for it. So the workaround that I used was to downgrade the framework to 2.7.4
, i.e. by putting the following section into the node yaml:
esp8266:
board: d1_mini
framework:
version: 2.7.4
Thank you for providing this code.
I'm trying to set
and get
the current state_machine state from a lambda.
I can set the transition from a lambda, but I can't read the state from a lambda.
Setting the transition works:
id(state_machine_mode).transition("ERROR");
However attempting to get the state returns this error
if (id(state_machine_mode).state != "ERROR") {
}
error: 'class esphome::state_machine::StateMachineComponent' has no member named 'state'; did you mean 'states_'?
Is it possible to get the state from a lambda? If so what is the syntax
Declaration with initial state STOPPAD:
state_machine:
When starting up state is set to STARTAR:
[16:03:54][C][state_machine:032]: State Machine 'On/Off Toggle State Machine'
[16:03:54][C][state_machine:034]: Current State: STARTAR
[16:03:54][C][state_machine:036]: States: 4
[16:03:54][C][state_machine:039]: STARTAR
[16:03:54][C][state_machine:039]: STARTAD
[16:03:54][C][state_machine:039]: STOPPAR
[16:03:54][C][state_machine:039]: STOPPAD
[16:03:54][C][state_machine:042]: Inputs: 2
[16:03:54][C][state_machine:045]: STARTA
[16:03:54][C][state_machine:045]: STOPPA
[16:03:54][C][state_machine:048]: Transitions: 2
[16:03:54][C][state_machine:051]: STARTA: STOPPAD -> STARTAR
[16:03:54][C][state_machine:051]: STOPPA: STARTAD -> STOPPAR
and later:
[16:14:12][W][state_machine:101]: STARTA: no transition from STARTAR
[16:14:14][W][state_machine:101]: STOPPA: no transition from STARTAR
text_sensor is not updated when state is set using state_machine.set without a transition.
This is used for example when changing state after reboot and the state is set based on a binary sensor. See for exampe your garage.yaml example and init code in API status.
Hi,
I have designed a state machine that works well for a light switch with a single gang (1 button, 1 relay with 1 PIR motion sensor etc).
However I now want to use this same state machine model for a 3 gang switch (3 buttons, 3 relays etc) each with the same model of state machine, but separate instances (IDs: sm1
, sm2
, sm3
).
In the state machine file I have hardcoded the IDs of lights to turn on/off etc
I can’t figure out how to dynamically import this state machine model 3 times, each instance with different variables. I was wondering if anyone has come across and solved this issue before.
I have posted this question with much more detail and examples on the HA ESPHome community forum, but wanted to post here for visibility as it concerns esphome-state-machine.
Currently there's no validation for the from
, input
and to
parameters on the state_machine.transition
action and on state_machine.transition
confition. This is something that would be nice to add.
I don't know ESPHome validation framework well enough to implement this. If you know how to do that please help :)
It seems like an order of state.on_enter handler and transition specific action is incorrect.
Test code:
binary_sensor:
- platform: gpio
pin:
number: GPIO16
mode: INPUT_PULLDOWN_16
name: "Button #2"
on_click:
- min_length: 50ms
max_length: 350ms
then:
- state_machine.transition: BTN2_SHORT_CLICK
script:
- id: filling
mode: single
then:
- delay: 2s
- state_machine.transition: FILLING_OK
state_machine:
- name: State Machine
id: fsm
initial_state: FSM_STATUS_OK
states:
- name: FSM_STATUS_OK
- name: FSM_IN_PROGRESS
on_set:
- lambda: 'ESP_LOGW("FSM_IN_PROGRESS", "on_set handler");'
on_enter:
- lambda: 'ESP_LOGW("FSM_IN_PROGRESS", "on_enter handler");'
on_leave:
- lambda: 'ESP_LOGW("FSM_IN_PROGRESS", "on_leave handler");'
inputs:
- name: BTN2_SHORT_CLICK
transitions:
- from: FSM_STATUS_OK
to: FSM_IN_PROGRESS
action:
- lambda: 'ESP_LOGW("BTN2_SHORT_CLICK: FSM_STATUS_OK -> FSM_IN_PROGRESS", "action handler");'
- script.execute: filling
action:
- lambda: 'ESP_LOGW("BTN2_SHORT_CLICK", "action handler");'
- name: FILLING_OK
transitions:
- FSM_IN_PROGRESS -> FSM_STATUS_OK
Log output:
[18:25:19][D][binary_sensor:036]: 'Button #2': Sending state ON
[18:25:19][D][binary_sensor:036]: 'Button #2': Sending state OFF
[18:25:19][D][state_machine:099]: BTN2_SHORT_CLICK: transitioned from FSM_STATUS_OK to FSM_IN_PROGRESS
[18:25:19][W][FSM_IN_PROGRESS:072]: on_enter handler
[18:25:19][W][BTN2_SHORT_CLICK: FSM_STATUS_OK -> FSM_IN_PROGRESS:082]: action handler
[18:25:19][W][BTN2_SHORT_CLICK:085]: action handler
[18:25:21][D][state_machine:099]: FILLING_OK: transitioned from FSM_IN_PROGRESS to FSM_STATUS_OK
[18:25:21][W][FSM_IN_PROGRESS:074]: on_leave handler
Expected sequence of events:
The actual sequence of events:
The impact and the result are mixed up. I think the sequence will be significantly more logical if the impact precedes the result.
Sorry for abusing issues.
The component looks very good and I was wondering if you considered to add it to the official esphome repo
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.