Giter Club home page Giter Club logo

esphome-state-machine's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

esphome-state-machine's Issues

Ability to directly set state (from HA) WITH `on_enter` automation run

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 can't get initial_state to work

Declaration with initial state STOPPAD:

state_machine:

  • name: On/Off Toggle State Machine
    diagram: dot
    initial_state: STOPPAD
    states:
    • name: STARTAR

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

How to get current state in lambda?

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

text_sensor not updated when using state_machine.set

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.

Light operation on the intial state on_set have no effect

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%

Feature Suggestion: Transition Trigger Based on a Timer

a suggestion for a feature.. If I could write C++ I would give you a push request :)

Timer Triggered Transitions

  1. An optional parameter (max_state_duration) to define how long the state machine can stay in any particular state
  2. If no transition received within X seconds of entering a state then, based on the current state, automatically send one of th defined transitions
  3. timers get reset on any state change event
  4. If there is no transition defined for the current state then the automatic trigger is ignored, timer is reset and the cycle continues

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

Ability to set initial_state dynamically

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.

Show example with states with on_enter

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.

Crashes on ESP8266 with ESPHome 2022.2+ when a lot of state/inputs/transitions

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

One state machine model for many instances

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.

PR on esphome

Sorry for abusing issues.
The component looks very good and I was wondering if you considered to add it to the official esphome repo

Change the order of state.on_enter and transition.action

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:

  1. Button pressed
  2. Input BTN2_SHORT_CLICK processed
  3. BTN2_SHORT_CLICK transition-specific action done
  4. BTN2_SHORT_CLICK action done
  5. State machine state changed
  6. State machine state.on_enter called
  7. ...
  8. State machine state.on_leave called

The actual sequence of events:

  1. Button pressed
  2. Input BTN2_SHORT_CLICK processed
  3. State machine state changed
  4. State machine state.on_enter called
  5. BTN2_SHORT_CLICK transition-specific action done
  6. BTN2_SHORT_CLICK action done
  7. ...
  8. State machine state.on_leave called

The impact and the result are mixed up. I think the sequence will be significantly more logical if the impact precedes the result.

Add posibility of creating the conditional transitions

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: ...

state_machine.transition action/condition parameters are not validated

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 :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.