Muse Luxe with ESPHome voice assistant

It’s both. I am monitoring the uptime in Home Assistant and there are times when uptime counter just resets, i.e., device reboots (once a day maybe sometimes more frequent).

But more critical is when I play something specific. In this case I can reproduce this behavior fairly reliably. For example when I play something, after the 4th or 5th time it would crash (and I get a huge static as before).

This is the message on the console:

[...]
[11:13:52][D][main:197]: ====> hardware mute
[11:13:52][D][micro_wake_word:375]: State changed from STOPPED to STARTING
[11:13:52][D][micro_wake_word:258]: Inference task has started, attempting to allocate memory for buffers
[11:13:52][D][micro_wake_word:263]: Inference task is running
[11:13:52][D][micro_wake_word:375]: State changed from STARTING to DETECTING_WAKE_WORD
[11:13:52][D][ring_buffer:034][mww]: Created ring buffer with size 3840
[11:13:56][D][button:023]: 'SimpliChime' Pressed.
[11:13:56][D][micro_wake_word:367]: Stopping wake word detection
[11:13:56][D][speaker_media_player:406]: State changed to ANNOUNCING
[11:13:56][D][micro_wake_word:375]: State changed from DETECTING_WAKE_WORD to STOPPING
[11:13:56][D][speaker_media_player.pipeline:114]: Reading WAV file type
[11:13:56][D][ring_buffer:034][ann_read]: Created ring buffer with size 1000000
[11:13:56][D][micro_wake_word:270]: Inference task is stopping, deallocating buffers
[11:13:56][D][micro_wake_word:275]: Inference task is finished, freeing task resources
[11:13:56][D][micro_wake_word:375]: State changed from STOPPING to STOPPED
[11:13:56][D][main:690]: ==>>>update_led
[11:13:56][D][light:089]: 'Muse Luxe Diningrm' Setting:
[11:13:56][D][light:113]:   Red: 100%, Green: 50%, Blue: 0%
[11:13:56][D][light:163]:   Effect: 'None'
[11:13:56][D][speaker_media_player.pipeline:124]: Decoded audio has 1 channels, 16000 Hz sample rate, and 16 bits per sample
[11:13:56][D][i2s_audio.speaker:102]: Starting
[11:13:56][D][i2s_audio.speaker:106]: Started
[11:13:56][D][ring_buffer:034][speaker_task]: Created ring buffer with size 3200
[11:13:56][D][main:209]: ====> hardware unmute
[11:13:57][D][button:023]: 'SimpliChime' Pressed.
[11:13:57][D][speaker_media_player.pipeline:114]: Reading WAV file type
[11:13:57][D][ring_buffer:034][ann_read]: Created ring buffer with size 1000000
[11:13:57][D][speaker_media_player.pipeline:124]: Decoded audio has 1 channels, 16000 Hz sample rate, and 16 bits per sample
[11:13:57][D][button:023]: 'SimpliChime' Pressed.
[11:13:57][D][speaker_media_player.pipeline:114]: Reading WAV file type
[11:13:57][D][ring_buffer:034][ann_read]: Created ring buffer with size 1000000
[11:13:57][D][speaker_media_player.pipeline:124]: Decoded audio has 1 channels, 16000 Hz sample rate, and 16 bits per sample
[11:13:58][D][button:023]: 'SimpliChime' Pressed.
[11:13:58][D][speaker_media_player.pipeline:114]: Reading WAV file type
[11:13:58][D][ring_buffer:034][ann_read]: Created ring buffer with size 1000000
[11:13:58][D][speaker_media_player.pipeline:124]: Decoded audio has 1 channels, 16000 Hz sample rate, and 16 bits per sample
[11:13:58]Guru Meditation Error: Core  0 panic'ed (StoreProhibited). Exception was unhandled.
[11:13:58]
[11:13:58]Core  0 register dump:
[11:13:58]PC      : 0x400996d9  PS      : 0x00060633  A0      : 0x80099190  A1      : 0x3ffd8990  
[11:13:58]A2      : 0x3f804a20  A3      : 0x000000f6  A4      : 0xb33fffff  A5      : 0x00060023  
[11:13:58]A6      : 0x0000001c  A7      : 0x3ffb6620  A8      : 0x000000f8  A9      : 0x00000003  
[11:13:58]A10     : 0x0000001b  A11     : 0x3f800014  A12     : 0x00010655  A13     : 0x3f800038  
[11:13:58]A14     : 0x3f800078  A15     : 0x00010655  SAR     : 0x0000001e  EXCCAUSE: 0x0000001d  
[11:13:58]EXCVADDR: 0x00010661  LBEG    : 0x40090f78  LEND    : 0x40090f94  LCOUNT  : 0xffffffff  
[11:13:58]
[11:13:58]
[11:13:58]Backtrace: 0x400996d6:0x3ffd8990 0x4009918d:0x3ffd89b0 0x400855db:0x3ffd89d0 0x400855fd:0x3ffd8a00 0x40085828:0x3ffd8a20 0x40085271:0x3ffd8a70 0x40212d3d:0x3ffd8a90 0x402163ad:0x3ffd8ac0 0x4021473e:0x3ffd8af0 0x40216b99:0x3ffd8b30 0x40216c7e:0x3ffd8b70 0x40210b4d:0x3ffd8bb0
[11:13:58]
[11:13:58]
[11:13:58]
[11:13:58]
[11:13:58]ELF file SHA256: 09a4e555a
[11:13:58]
[11:13:58]Rebooting...

(I was also discussing this in this older thread: Muse Luxe esphome loud buzzing sound - #32 by Raspiaudio)

For reference, this is my YAML.

Would you mind trying this one out and see if you can reproduce it?

api:
  encryption:
    key: "xxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: none
  output_power: 15



substitutions:
  name: "muse-luxe-01"
  friendly_name: "Muse Luxe Diningrm"
#States  
  P_starting: "0"
  P_waiting: "1"
  P_playing: "2"
  P_listening: "3"
  P_answering: "4"
  
esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  min_version: 2025.2.0
  name_add_mac_suffix: false
  platformio_options:
    board_build.flash_mode: dio
    board_build.arduino.memory_type: qio_opi
  project:
    name: raspiaudio.voice-assistant
    version: "2025.3.0"    
  on_boot:
    priority: -100.0
    then:
      - output.turn_on: dac_mute
      - lambda: id(muteH) = true;
      - lambda: id(phase) = 0;
      - script.execute: update_led  
            
external_components:
    - source: github://RASPIAUDIO/esphomeLuxe@main
      components: [es8388]
      refresh: 0s
        
esp32:
  board: esp-wrover-kit  
  flash_size: 4MB
  partitions: luxe_partitions2.csv
  framework:
    type: esp-idf
    version: recommended
    sdkconfig_options:
      CONFIG_ESP_CONSOLE_USB_CDC: "n"
      CONFIG_ESP_CONSOLE_UART_DEFAULT: "y"
      CONFIG_ESP_CONSOLE_UART_NUM: "0"
      CONFIG_ESP_CONSOLE_UART_BAUDRATE: "115200"
       
micro_wake_word:
  id: mww
  microphone: luxe_mic
  stop_after_detection: false
  models:
    - model: https://github.com/kahrendt/microWakeWord/releases/download/okay_nabu_20241226.3/okay_nabu.json
      id: okay_nabu
    - model: hey_jarvis
      id: hey_jarvis
    - model: hey_mycroft
      id: hey_mycroft
  on_wake_word_detected:
    - voice_assistant.start:
        wake_word: !lambda return wake_word;

logger:
  level: DEBUG
  baud_rate: 115200
  hardware_uart: UART0
  logs:
    media_player: WARN

##########
# Hardware Configuration
es8388:
   id: my_es8388
   
psram:
  mode: quad
  speed: 80MHz

#######
# Buses Configuration
i2c:
  sda: GPIO18
  scl: GPIO23


#####################
# Internal Components
output:
  - platform: gpio
    id: dac_mute
    pin:
      number: GPIO21
      inverted: true
      mode:
        output: true
  
              
globals:
  - id: Vol
    type: float
    initial_value: '0.6'    
  - id: phase
    type: int
    initial_value: '0'    
  - id: mute  
    type: bool
    initial_value: 'false'        
  - id: muteH 
    type: bool
    initial_value: 'false'     
  - id: last_led_phase
    type: int
    initial_value: '-1'
  - id: audio_active
    type: bool
    initial_value: 'false'
  - id: audio_started
    type: bool
    initial_value: 'false'
  - id: last_volume_cmd
    type: float
    initial_value: '-1.0'
        
interval:
  - interval: 0.1sec   
    then:          
      - if:
          condition:  
             - speaker.is_stopped:             
          then:
             - if:
                condition:
                  - not:
                     - lambda: 'return(id(muteH));'            
                then:
                  - output.turn_on: dac_mute   
                  - lambda: id(muteH) = true;
                  - logger.log: "====> hardware mute"     
          
      - if:
          condition:  
             - speaker.is_playing:             
          then:
             - if:
                condition:
                  - lambda: 'return(id(muteH));'            
                then:
                  - output.turn_off: dac_mute   
                  - lambda: id(muteH) = false;          
                  - logger.log: "====> hardware unmute"               
     
      - if:
          condition:
            and:
              - lambda: 'return id(audio_active) && !id(audio_started);'
              - speaker.is_playing:
          then:
            - lambda: id(audio_started) = true;
          

sensor:
  - platform: uptime
    name: Uptime
  - platform: adc
    pin: GPIO33
    name: Battery voltage
    device_class: voltage
    unit_of_measurement: "V"
    accuracy_decimals: 2
    state_class: measurement
    entity_category: diagnostic
    update_interval: 15s
    attenuation: auto
    filters:
      - multiply: 2 # https://forum.raspiaudio.com/t/esp-muse-luxe-bluetooth-speaker/294/12
      - exponential_moving_average:
          alpha: 0.2
          send_every: 2
      - delta: 0.002
    on_value:
      then:
        - sensor.template.publish:
            id: battery_percent
            state: !lambda "return x;"

  - platform: template
    name: Battery
    id: battery_percent
    device_class: battery
    unit_of_measurement: "%"
    accuracy_decimals: 0
    state_class: measurement
    entity_category: diagnostic
    update_interval: 15s
    filters:
      - calibrate_polynomial:
          degree: 3
          datapoints:
            - 4.58 -> 100.0
            - 4.5 -> 97.1
            - 4.47 -> 94.2
            - 4.44 -> 88.4
            - 4.42 -> 82.7
            - 4.41 -> 76.9
            - 4.41 -> 71.1
            - 4.37 -> 65.3
            - 4.35 -> 59.5
            - 4.31 -> 53.8
            - 4.28 -> 48.0
            - 4.26 -> 42.2
            - 4.23 -> 36.4
            - 4.21 -> 30.6
            - 4.19 -> 24.9
            - 4.16 -> 19.1
            - 4.1 -> 13.3
            - 4.07 -> 10.4
            - 4.03 -> 7.5
            - 3.97 -> 4.6
            - 3.82 -> 1.7
            - 3.27 -> 0.0
      - lambda: return clamp(x, 0.0f, 100.0f);   
                  
                   
binary_sensor:
  - platform: gpio
    pin:
      number: GPIO27
      mode:
        input: true
        pullup: true
    id: jack_detect
    name: Jack Detect
    internal: true
    on_press:
      - script.execute: jack_detect_high
    on_release:
      - script.execute: jack_detect_low
  - platform: gpio
    pin:
      number: GPIO19
      inverted: true
      mode:
        input: true
        pullup: true
    name: Volume Up
    on_click:
        - lambda: |-       
                id(Vol) += 0.05;
                if(id(Vol) > 1) id(Vol) = 1;            
        - if:
            condition:
              lambda: 'return fabsf(id(last_volume_cmd) - id(Vol)) > 0.005f;'
            then:
              - media_player.volume_set: 
                  id: luxe_media_player        
                  volume: !lambda return id(Vol);         
              - lambda: id(last_volume_cmd) = id(Vol);
         
  - platform: gpio
    pin:
      number: GPIO32
      inverted: true
      mode:
        input: true
        pullup: true
    name: Volume Down
    on_click:
        - lambda: |-       
                id(Vol) -= 0.05;
                if(id(Vol) < 0) id(Vol) = 0;            
        - if:
            condition:
              lambda: 'return fabsf(id(last_volume_cmd) - id(Vol)) > 0.005f;'
            then:
              - media_player.volume_set: 
                  id: luxe_media_player        
                  volume: !lambda return id(Vol);              
              - lambda: id(last_volume_cmd) = id(Vol);
      
  - platform: gpio
    pin:
      number: GPIO12
      inverted: true
      mode:
        input: true
        pullup: true 
    name: Mute
    on_click:       
      - script.execute: manual_listen
    on_double_click:
       - if:
           condition: 
              - lambda: 'return(id(phase) == 2);'
           then:
              - media_player.stop:                     


light:
  - platform: esp32_rmt_led_strip
    name: None
    id: top_led
    pin: GPIO22
    chipset: WS2812
    num_leds: 1
    rgb_order: grb
#    rmt_channel: 0
    default_transition_length: 0s
    gamma_correct: 2.8
    effects:
      - pulse:
          name: pulse
          transition_length: 250ms
          update_interval: 250ms
      - pulse:
          name: slow_pulse
          transition_length: 1s
          update_interval: 2s

    
i2s_audio:
    id: i2s0
    i2s_lrclk_pin: GPIO25
    i2s_bclk_pin: GPIO5
    i2s_mclk_pin: GPIO0

microphone:
  - platform: i2s_audio
    id: luxe_mic
    i2s_audio_id: i2s0
    sample_rate: 16000
    i2s_din_pin: GPIO35
    bits_per_sample: 16bit
    channel: stereo
    adc_type: external  
    
speaker:
  - platform: i2s_audio
    id: luxe_speaker
    i2s_audio_id: i2s0
    i2s_dout_pin: GPIO26
    dac_type: external
    sample_rate: 48000
    bits_per_sample: 16bit
    num_channels: 2
    buffer_duration: 100ms     
    
media_player:
  - platform: speaker
    name: None
    id: luxe_media_player
    internal: false   
#    task_stack_in_psram: true
#    volume_min: 0.5
#    volume_max: 0.8
    announcement_pipeline:
      speaker: luxe_speaker
      format: WAV
      sample_rate: 48000
      num_channels: 1       
    files:
      - id: little_sound
        file: https://github.com/RASPIAUDIO/esphomeLuxe/raw/refs/heads/main/wav/sounds_timer_finished.wav
      - id: beep
        file: http://10.227.4.10:8123/local/beep.wav
      - id: SimpliChime
        file: http://10.227.4.10:8123/local/SimpliChime.wav
      - id: BurglarAlarm
        file: http://10.227.4.10:8123/local/Burglar-alarm-sound.mp3
    on_announcement: 
      - micro_wake_word.stop:
      - wait_until:
          not:
            micro_wake_word.is_running:
      - microphone.mute: luxe_mic
      - lambda: |-
          id(audio_active) = true;
          id(audio_started) = false;
      - if:
           condition:
                lambda: 'return(id(phase) != 2);'
           then:           
              - lambda: |-
                   if(id(phase) == 1)  id(phase) = 2;    
              - script.execute: mute_off         
              - script.execute: update_led    
                     
    on_idle:
      - if:
          condition:
            lambda: 'return id(audio_active) && id(audio_started);'
          then:
            - wait_until:
               and:
                - not:
                    media_player.is_announcing:
                - not:
                    voice_assistant.is_running:    
            - if:
                condition:              
                    lambda: 'return((id(phase) == 4) || (id(phase) == 2));'
                then:
                  - lambda: |-
                       id(phase) = 1; 
            - microphone.unmute: luxe_mic
            - micro_wake_word.start:                                              
            - script.execute: update_led
            - lambda: |-
                id(audio_active) = false;
                id(audio_started) = false;
    on_play:
      - if:
          condition:
            lambda: 'return !id(mute);'
          then:
            - output.turn_off: dac_mute
            - lambda: id(muteH) = false;
      
select:
  - platform: template
    name: "Wake word sensitivity"
    optimistic: true
    initial_option: Slightly sensitive
    restore_value: true
    entity_category: config
    options:
      - Slightly sensitive
      - Moderately sensitive
      - Very sensitive
    on_value:
      # Adjust model probability thresholds to tune wake word sensitivity
      lambda: |-
        if (x == "Slightly sensitive") {
          id(okay_nabu).set_probability_cutoff(217);    // 0.85 -> 0.000 FAPH on DipCo
          id(hey_jarvis).set_probability_cutoff(247);   // 0.97 -> 0.563 FAPH on DipCo
          id(hey_mycroft).set_probability_cutoff(253);  // 0.99 -> 0.567 FAPH on DipCo
        } else if (x == "Moderately sensitive") {
          id(okay_nabu).set_probability_cutoff(176);    // 0.69 -> 0.376 FAPH on DipCo
          id(hey_jarvis).set_probability_cutoff(235);   // 0.92 -> 0.939 FAPH on DipCo
          id(hey_mycroft).set_probability_cutoff(242);  // 0.95 -> 1.502 FAPH on DipCo
        } else if (x == "Very sensitive") {
          id(okay_nabu).set_probability_cutoff(143);    // 0.56 -> 0.751 FAPH on DipCo
          id(hey_jarvis).set_probability_cutoff(212);   // 0.83 -> 1.502 FAPH on DipCo
          id(hey_mycroft).set_probability_cutoff(237);  // 0.93 -> 1.878 FAPH on DipCo
        }


voice_assistant:
  id: va
  microphone: luxe_mic
  media_player: luxe_media_player
  micro_wake_word: mww
  use_wake_word: false
  noise_suppression_level: 2
  auto_gain: 31dBFS
  volume_multiplier: 2.0
  
  on_listening: 
     - logger.log: "listening 3 => phase"                    
     - micro_wake_word.stop:
     - lambda: |-
        id(phase) = 3;                            
     - script.execute: update_led

  on_stt_end:
     - light.turn_on:
        id: top_led
        blue: 60%
        red: 20%
        green: 20%
        effect: pulse
      

  on_tts_start:
    - logger.log: "answering  4 => phase"                   
    - micro_wake_word.stop:
    - wait_until:
        not:
          micro_wake_word.is_running:
    - microphone.mute: luxe_mic
    - lambda: |-
        id(audio_active) = true;
        id(audio_started) = false;
    - lambda: |-
        id(phase) = 4;
    - script.execute: update_led
                     
  on_error:
    - logger.log: "ERROR!!!!!!!!!!!!!!!!"  
    - light.turn_on:
        id: top_led
        blue: 0%
        red: 100%
        green: 0%
        effect: pulse          
    - delay: 3s
    - lambda: id(phase) = 1;    
    - script.execute: update_led 
  
button:
  - platform: restart
    id: restart_button
    name: "Restart"
    entity_category: config
    disabled_by_default: true
    icon: "mdi:restart"
  - platform: template
    name: "Beep"
    on_press:
      - media_player.speaker.play_on_device_media_file:
          media_file: beep
          announcement: true
  - platform: template
    name: "SimpliChime"
    on_press:
      - media_player.speaker.play_on_device_media_file:
          media_file: SimpliChime
          announcement: true
  - platform: template
    name: "Burglar Alarm"
    on_press:
      - media_player.speaker.play_on_device_media_file:
          media_file: BurglarAlarm
          announcement: true

#########
# Scripts

script:   


  - id: jack_detect_high
    then:
       - logger.log: "Jack detect high -> route to speaker"
       - output.turn_off: dac_mute
       - lambda: |-
           id(my_es8388).write_byte(0x1D, 0x20);
           id(my_es8388).write_byte(0x1C, 0x10);
           id(my_es8388).write_byte(0x04, 0x30);

  - id: jack_detect_low
    then:
       - logger.log: "Jack detect low -> route to line out"
       - output.turn_on: dac_mute
       - lambda: |-  
           id(my_es8388).write_byte(0x1D, 0x00);
           id(my_es8388).write_byte(0x1C, 0x00);
           id(my_es8388).write_byte(0x04, 0x0C);

  - id: manual_listen
    then:
      - logger.log: "Manual listen button pressed"
      - if:
          condition:
            lambda: 'return id(mute);'
          then:
            - logger.log: "Manual listen -> unmute and go to waiting"
            - script.execute: mute_off
            - voice_assistant.stop:
            - wait_until:
                not:
                  voice_assistant.is_running:
            - micro_wake_word.start:
            - lambda: |-
                 id(audio_active) = false;
                 id(audio_started) = false;
                 id(phase) = 1;
            - script.execute: update_led
          else:
            - if:
                condition:
                  lambda: 'return id(phase) == 2;'
                then:
                  - logger.log: "Manual listen -> mute current playback"
                  - script.execute: mute_on
                else:
                  - if:
                      condition:
                        lambda: 'return id(phase) == 1;'
                      then:
                        - logger.log: "Manual listen -> switch waiting to listening"
                        - voice_assistant.stop:
                        - wait_until:
                            not:
                              voice_assistant.is_running:
                        - script.execute: mute_off
                        - microphone.unmute: luxe_mic
                        - micro_wake_word.stop:
                        - lambda: |-
                             id(audio_active) = false;
                             id(audio_started) = false;
                             id(phase) = 3;
                        - script.execute: update_led
                        - voice_assistant.start:
                      else:
                        - if:
                            condition:
                              lambda: 'return id(phase) == 3;'
                            then:
                              - logger.log: "Manual listen -> switch listening to waiting"
                              - voice_assistant.stop:
                              - wait_until:
                                  not:
                                    voice_assistant.is_running:
                              - micro_wake_word.start:
                              - lambda: |-
                                   id(audio_active) = false;
                                   id(audio_started) = false;
                                   id(phase) = 1;
                              - script.execute: update_led
                            else:
                              - logger.log: "Manual listen -> fallback to waiting"
                              - voice_assistant.stop:
                              - wait_until:
                                  not:
                                    voice_assistant.is_running:
                              - micro_wake_word.start:
                              - lambda: |-
                                   id(audio_active) = false;
                                   id(audio_started) = false;
                                   id(phase) = 1;
                              - script.execute: update_led


  - id: update_led
    then:  
       - if:
           condition:
             lambda: 'return id(phase) != id(last_led_phase);'
           then:
             - lambda: id(last_led_phase) = id(phase);
             - logger.log: "==>>>update_led" 
             - lambda: |-
                   if(id(phase) == 0)id(start).execute();
                   if(id(phase) == 1)id(waiting).execute();  
                   if(id(phase) == 2)id(external_player).execute();                      
                   if(id(phase) == 3)id(listening).execute();
                   if(id(phase) == 4)id(answering).execute();
                         
  - id: start           
    then:
     - light.turn_on:
          id: top_led
          effect: slow_pulse
          red: 80%
          green: 0%
          blue: 80%             
     - delay: 5sec
     - lambda: id(my_es8388).setup();
     - output.turn_off: dac_mute
     - lambda: id(phase) = 1;
     - micro_wake_word.stop:
     - wait_until:
         not:
           micro_wake_word.is_running:
     - microphone.mute: luxe_mic
     - delay: 200ms
#     - media_player.speaker.play_on_device_media_file:
#          media_file: little_sound
#          announcement: false      
     - script.execute: update_led
     
  - id: waiting
    then:
     - light.turn_on:
          id: top_led
          effect: pulse
          red: 0%
          green: 0%
          blue: 100% 
          brightness: 100% 
     - voice_assistant.stop:              
     - micro_wake_word.start:                       
       

  - id: listening
    then:
     - light.turn_on:
          id: top_led
          effect: pulse
          red: 0%
          green: 100%
          blue: 0%                      
          brightness: 100%       
          
  - id: answering
    then:
     - light.turn_on:
          id: top_led
          effect: none
          red: 100%
          green: 100%
          blue: 0%                     
          brightness: 100%       
          
  - id: external_player
    then:
     - light.turn_on:
          id: top_led
          effect: none
          red: 80%
          green: 40%
          blue: 0%                      
                      
                        
  - id: mute_on
    then:
       - if:
           condition:
             lambda: 'return fabsf(id(last_volume_cmd)) > 0.005f;'
           then:
             - media_player.volume_set:
                 id: luxe_media_player
                 volume: '0'
             - lambda: id(last_volume_cmd) = 0.0f;
       - lambda: id(mute) = true;
     
  - id: mute_off
    then:

       - if:
           condition:
             lambda: 'return fabsf(id(last_volume_cmd) - id(Vol)) > 0.005f;'
           then:
             - media_player.volume_set:
                  id: luxe_media_player
                  volume: !lambda return(id(Vol));
             - lambda: id(last_volume_cmd) = id(Vol);
       - lambda: id(mute) = false;               


EDIT: It may actually be related to the “SimpliChime” button and pressing it too fast. For these small sounds I would like to have them on the device directly and use a button. Do you know if there’s a better way to integrate this into the state machine?
Regarding the other crashes, I will continue to let it run and provide the uptime plot (see if it changed compared to the one I posted here)