Hello everyone,
Could someone give me some assistance with the below code?
The “simulated button” I have created when clicked in home assistant cycles through the 4 states properly. The reset button works properly and the button press counter seems to be working properly when both using the simulated button and when setting the light state directly from a service call.
However, my issue is that the service calls never get the light to actually come on in any state. When looking at the logs and esphome, the esp is changing the counters so it is receiving information to make the state change. However, the light is never changing to the proper mode when using the service calls. (i.e., mode 1 Device OFF, mode 2 Device On, etc.)
Could I get someone to help me fix this based on the above info. Essentially I want to be able to used the “simulated button” to cycle through the states one at a time (which is working currently) but I would also like to be able to use direct state change method through the service call. (I am using the “perform action” are in developer tools for testing)
I think I need to somehow press the simulated button the proper number of times based on the change of the number from 1 to 4. (as I have assigned 1,2,3,4 to the various states.-- I thought that was what is programmed in the code provided but its not working for some reason.
Thank you all for helping me with this. I think it’s simple, I just don’t know what I’m doing.
Full transparency: ChatGPT got me to here or I wouldn’t have even been able to get this far.
esphome:
name: "supermariolight"
friendly_name: supermariolight
min_version: 2024.11.0
name_add_mac_suffix: false
esp32:
board: esp32dev
framework:
type: esp-idf
# Enable logging
logger:
# Enable Home Assistant API
api:
services:
- service: set_light_state
variables:
state: string
then:
- lambda: |-
// Map the desired state string to a target number
int target_state;
if (state == "Device OFF") {
target_state = 1;
} else if (state == "Device ON") {
target_state = 2;
} else if (state == "Device PULSING") {
target_state = 3;
} else if (state == "Device REACTS TO SOUND") {
target_state = 4;
} else {
ESP_LOGE("main", "Invalid state received: %s", state.c_str());
return;
}
// Calculate how many presses are needed to reach the target state
int current_state = id(button_counter);
int presses_needed = target_state - current_state;
if (presses_needed < 0) {
presses_needed += 4; // Wrap around to handle state cycling
}
// Simulate the required number of presses
for (int i = 0; i < presses_needed; i++) {
id(simulated_button).turn_on();
delay(1000); // Simulate the physical button press duration
id(simulated_button).turn_off();
delay(1000); // Wait before the next press
}
// Update the counter to match the target state
id(button_counter) = target_state;
// Publish the new counter value to Home Assistant
id(button_counter_sensor).publish_state(id(button_counter));
ESP_LOGD("main", "Set light state to %s, counter updated to %d", state.c_str(), id(button_counter));
# Allow Over-The-Air updates
ota:
- platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Supermariolight Fallback Hotspot"
password: "pPrZpEH1vZK0"
captive_portal:
# Global variable to track the state
globals:
- id: button_counter
type: int
restore_value: yes
initial_value: '1'
# Define the GPIO output to simulate button presses
output:
- platform: gpio
pin: GPIO5 # Use GPIO5 to simulate the button press
id: simulated_button
inverted: True # Inverts the signal, making it low by default
# Template switch to simulate button presses
switch:
- platform: template
name: "Simulated Button"
turn_on_action:
- lambda: |-
// Increment the counter
id(button_counter) += 1;
// Reset the counter after state 4
if (id(button_counter) > 4) {
id(button_counter) = 1;
}
// Log the current state
ESP_LOGD("main", "Simulated button pressed, current state: %d", id(button_counter));
// Simulate the button press
id(simulated_button).turn_on();
delay(1000); // Simulate the physical button press duration
id(simulated_button).turn_off();
// Update the sensor value
id(button_counter_sensor).publish_state(id(button_counter));
# Virtual reset button
- platform: template
name: "Reset Button"
turn_on_action:
- lambda: |-
// Reset the counter to 1
id(button_counter) = 1;
ESP_LOGD("main", "Counter reset to 1");
// Publish the updated state
id(button_counter_sensor).publish_state(id(button_counter));
# Expose the button counter as a sensor to Home Assistant
sensor:
- platform: template
name: "Button Press Counter"
id: button_counter_sensor
lambda: |-
return id(button_counter);
on_value:
then:
- homeassistant.service:
service: input_select.select_option
data:
entity_id: input_select.super_mario_light_state
option: !lambda |-
if (x == 1) {
return "Device OFF";
} else if (x == 2) {
return "Device ON";
} else if (x == 3) {
return "Device PULSING";
} else if (x == 4) {
return "Device REACTS TO SOUND";
} else {
return "Device OFF";
}