I am working on a project for my garage. The function is for the following:
- Have an 8x32 ws2812 matrix display, and display messages from MQTT.
- Depending on the message received, the display will change and display the message. The MQTT messages will be triggered by external sensors which I do not have linked.
I am doing all testing with the MQTT integration:
The sensors I will be using is a photoelectric switch like this one. This will be placed at a distance to clear the gate opening. If a car pulls up, and breaks the sensor and tried to open the gate, the gate will not open and the display will print a message.
I also want to have a green arrow, a red X, etc., depending on the case.
Example:
- When a car pulls up, the matrix is full solid red. button pressed, when gate is open, display shows green arrow.
- When car pulls up, break the sensor line, display turns red, prints back up for 1 second, then red display again, etc.
The code below prints a message on the display which is received from MQTT. This works well. So any message I send from MQTT under that topic will be displayed on the matrix. So far so good.
#Name the Project here to dentify the specific node
substitutions:
project: Garage-LED-Sign-01
id: garage-led-sign-01
xscrollpadding: "4" # in pix
mqtt:
broker: !secret mqtt_broker
username: !secret mqtt_user
password: !secret mqtt_pwd
id: mqtt_client
#Include the board used
<<: !include common/esphome/esp32.yaml
#include common Wifi-OTA-API, etc
<<: !include common/common.yaml
#Include the platform used for the hardware
<<: !include common/templates/standard_template.yaml
binary_sensor:
#Include the status
- !include common/binary_sensors/status.yaml
- platform: gpio
pin: GPIO34
name: "PIR Sensor"
device_class: motion
id: garage_pir_sensor
switch:
#Include restart button
- !include common/switches/restart.yaml
sensor:
#Include wifi signal sensor
- !include common/sensors/wifi_signal.yaml
- !include common/sensors/uptime.yaml
text_sensor:
- platform: mqtt_subscribe
name: "Garage Sign Text"
id: garage_led_sign_text
topic: garage/led_sign/text
font:
- file: "fonts/arial.ttf"
id: text_font_tiny
size: 10
- file: "fonts/materialdesignicons-webfont.ttf"
id: icon_font_40
size: 35
glyphs: [
ó°€, #mdi-molecule-co2
󰟏, #mdi-molecule
ó°, #mdi-factory
ó°ą, #mdi-broom
ó°”, #mdi-air-filter
ó°, #mdi-weather-sunny
ó°, #mdi-weather-rainy
ó°,#mdi-weather-partly-cloudy
ó°, #mdi-weather-snowy-heavy
ó°, #mdi-weather-cloudy
ó°Œ, #mdi-error
ó°Š #mdi-progress-clock
]
color:
- id: my_red
red: 100%
green: 0%
blue: 0%
- id: my_green
red: 0%
green: 100%
blue: 0%
- id: my_blue
red: 0%
green: 0%
blue: 100%
- id: my_yellow
red: 100%
green: 100%
blue: 0%
# Configure WS2815
light:
- platform: fastled_clockless
chipset: WS2812b
id: led_matrix_light
pin: GPIO5
num_leds: 256
rgb_order: GRB
name: "Garage Traffic Sign"
default_transition_length: 0s
color_correct: [50%, 50%, 50%]
restore_mode: ALWAYS_ON
effects:
- addressable_rainbow:
- addressable_color_wipe:
- flicker:
- strobe:
- random:
- addressable_scan:
- addressable_twinkle:
- addressable_random_twinkle:
- addressable_fireworks:
- addressable_flicker:
- addressable_rainbow:
name: Rainbow Effect With Custom Values
speed: 10
width: 50
display:
- platform: addressable_light
id: led_matrix_display
addressable_light_id: led_matrix_light
width: 32
height: 8
pixel_mapper: |-
if (x % 2 == 0) {
return (x * 8) + y;
}
return (x * 8) + (7 - y);
rotation: 180°
update_interval: 200ms
pages:
- id: page1
lambda: |-
if (id(mqtt_client)->is_connected()) {
// do something if MQTT is connected
static uint16_t xpos = 0;
int x_start, y_start;
int width, height;
it.get_text_bounds(0, 0, "MQTT Connected", id(text_font_tiny),
TextAlign::TOP_LEFT, &x_start, &y_start, &width, &height);
it.print(-(xpos % (width + $xscrollpadding)), -2,
id(text_font_tiny), Color(id(my_blue)),
TextAlign::TOP_LEFT, "MQTT Connected");
xpos++;
}
- id: page2
lambda: |-
static uint16_t xpos = 0;
const char * text = id(garage_led_sign_text).state.c_str();
int x_start, y_start;
int width, height;
it.get_text_bounds(0, 0, text, id(text_font_tiny),
TextAlign::TOP_LEFT, &x_start, &y_start, &width, &height);
it.print(-(xpos % (width + $xscrollpadding)), -2,
id(text_font_tiny), Color(id(my_red)),
TextAlign::TOP_LEFT, text);
xpos++;
Thanks to @fribse for the scrolling code. The message scrolls and all works great.
Now I am trying to get the other section, which is have different screen display depending on the message received.
I thought about making pages, so one page is solid red, one is solid green, one is arrow, one is text, etc.
Then depending on the MQTT message received, I will basically show the page, delay, show the text scrolling, show another page, etc. with an interval.
Is this the best way of doing it?
I have been trying to get it working for a while now, and I am not sure where to put this code from the help page:
So the thought is trigger on a message received from MQTT, then read the message, and depending on the message text, load the first page in the animation.
then have a few interval code snippets, so depending on which page gets loaded from the code above, it will keep looping until a new message is received.
Not sure if this all makes sense.
Any thoughts or pointer?
EDIT:
I got this to compile
text_sensor:
- platform: mqtt_subscribe
name: "Garage Sign Text"
id: garage_led_sign_text
topic: garage/led_sign/text
on_value:
then:
- if:
condition:
lambda: return x == "START";
then:
- display.page.show: page3
- component.update: led_matrix_display
else:
- display.page.show: page2
- component.update: led_matrix_display
I tested and it works. Changes the pages. So got this figured out. Now a question on the condition.
Is -if
limited to one condition and one else? Is there a way I can make a switch statement like in standard C? To have multiple conditions for each of the text strings received from MQTT.
if START â page 1
if STOP â page 2
if GO â page 3
or a nested if â else if â else if â else
Any way I can test more than one condition?