Hello, very nice! Could you share the code you used for this? It’s quite interesting. Also, the STL file for the case in this combination? Thanks in advance.
Sure, it’s definitely a work in progress, unrefined and not optimised since I’m just prototyping stuff with it - but here you go
esphome:
name: m5dial
friendly_name: M5Dial
globals:
- id: screenwidth
type: int
restore_value: no
- id: max_rotary_value
type: int
restore_value: no
initial_value: '1'
- id: min_rotary_value
type: int
restore_value: no
initial_value: '100'
external_components:
- source: github://the-smart-home-maker/esphome-4cello@gc9a01
components: [ gc9a01 ]
i2c:
sda: GPIO12
scl: GPIO14
id: bus_a
#interrupt: 16
esp32:
board: esp32-s3-devkitc-1
framework:
type: arduino
# Enable logging
logger:
level: DEBUG
color:
- id: my_red
red: 100%
green: 3%
blue: 5%
- id: my_green
hex: 59981A
- id: my_blue
red: 3%
green: 5%
blue: 100%
- id: my_yellow
hex: FFFF00
- id: my_light_blue
hex: 145DA0
- id: my_light_red
hex: fc6d6d
- id: my_light_orange
hex: FD7F20
- id: my_light_yellow
hex: B58B00
image:
- file: mdi:volume-variant-off
id: volume_mute
resize: 40x40
- file: mdi:volume-low
id: volume_notmute
resize: 40x40
- file: mdi:light-recessed
id: downlighticon
resize: 80x80
- file: mdi:air-conditioner
id: airconicon
resize: 80X80
- file: mdi:snowflake
id: ac_cool_40
resize: 40x40
- file: mdi:sun-snowflake-variant
id: ac_heatcool_40
resize: 40x40
- file: mdi:fan
id: ac_fan_40
resize: 40x40
- file: mdi:power-cycle
id: power_off_icon_40
resize: 40x40
- file: mdi:water-percent
id: ac_dry_40
resize: 40x40
- file: mdi:fire
id: ac_heat_40
resize: 40x40
- file: mdi:thermometer
id: temp_target_icon
resize: 20x20
- file: mdi:bullseye
id: temp_current_icon
resize: 20x20
- file: mdi:snowflake
id: ac_cool_80
resize: 80x80
- file: mdi:sun-snowflake-variant
id: ac_heatcool_80
resize: 80x80
- file: mdi:fan
id: ac_fan_80
resize: 80x80
- file: mdi:power-cycle
id: power_off_icon_80
resize: 80x80
- file: mdi:water-percent
id: ac_dry_80
resize: 80x80
- file: mdi:fire
id: ac_heat_80
resize: 80x80
- file: mdi:knob
id: volumeknob
resize: 80x80
font:
- file: "fonts/arial.ttf"
id: my_font
size: 40
- file: "gfonts://Roboto"
id: roboto16
size: 16
- file: "gfonts://Roboto"
id: roboto20
size: 20
- file: "gfonts://Roboto"
id: roboto24
size: 24
# Enable Home Assistant API
api:
encryption:
key: !secret m4dialencryption
ota:
password: !secret m4dialotapassword
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "M4Dial Fallback Hotspot"
password: !secret m4fallbackpassword
captive_portal:
uart:
tx_pin: GPIO2
rx_pin: GPIO1
baud_rate: 256000
parity: NONE
stop_bits: 1
ld2410:
spi:
mosi_pin: GPIO5
clk_pin: GPIO6
display:
- platform: gc9a01
reset_pin: GPIO8
id: my_lcd
cs_pin: GPIO7
dc_pin: GPIO4
rotation: 180
pages:
- id: page1
lambda: |-
if (id(dimmersensor).state == "ON")
{
it.start_clipping(0, (id(dimmersensor_brightness).state * -1) + 255, 250, 250);
it.filled_circle(it.get_width() / 2, it.get_height(), 255, my_light_yellow);
it.end_clipping();
}
it.image(it.get_width() / 2, it.get_height() / 2 - 55, downlighticon, ImageAlign::TOP_CENTER);
it.printf(it.get_width() / 2, it.get_height() / 2 + 35, id(roboto24), TextAlign::TOP_CENTER, "%s", id(dimmersensor).state.c_str());
it.filled_circle(it.get_width() / 2 -12, 225, 3);
it.circle(it.get_width() / 2, 225, 3);
it.circle(it.get_width() / 2 +12, 225, 3);
- id: page2
lambda: |-
if (id(climatedevice).state == "cool")
{
// cooling
it.filled_circle(it.get_width() / 2, it.get_height() / 2, 120, my_light_blue);
it.image(it.get_width() / 2, it.get_height() / 2 + -55, ac_cool_80, ImageAlign::TOP_CENTER);
}
else if (id(climatedevice).state == "heat")
{
// heating
it.filled_circle(it.get_width() / 2, it.get_height() / 2, 120, my_light_red);
it.image(it.get_width() / 2, it.get_height() / 2 + -55, ac_heat_80, ImageAlign::TOP_CENTER);
}
else if (id(climatedevice).state == "auto")
{
// auto heat or cool
it.filled_circle(it.get_width() / 2, it.get_height() / 2, 120, my_light_orange);
it.image(it.get_width() / 2, it.get_height() / 2 + -55, ac_heatcool_80, ImageAlign::TOP_CENTER);
}
else if (id(climatedevice).state == "fan_only")
{
// fan only
it.filled_circle(it.get_width() / 2, it.get_height() / 2, 120, my_light_orange);
it.image(it.get_width() / 2, it.get_height() / 2 + -55, ac_fan_80, ImageAlign::TOP_CENTER);
}
else if (id(climatedevice).state == "dry")
{
// dry
it.filled_circle(it.get_width() / 2, it.get_height() / 2, 120, my_green);
// it.image(it.get_width() / 2 - 80, it.get_height() / 2 - 20, ac_dry_40, ImageAlign::TOP_CENTER);
it.image(it.get_width() / 2, it.get_height() / 2 + -55, ac_dry_80, ImageAlign::TOP_CENTER);
}
else if (id(climatedevice).state == "off")
{
// off
it.image(it.get_width() / 2, it.get_height() / 2 + -55, power_off_icon_80, ImageAlign::TOP_CENTER);
}
it.printf(it.get_width() / 2, it.get_height() / 2 - 95, id(roboto24), TextAlign::TOP_CENTER, "Air-Con");
it.printf(it.get_width() / 2 + 10, it.get_height() / 2 + 35, id(roboto24), TextAlign::TOP_CENTER, "%.0f", id(climatedevice_setpoint).state);
it.printf(it.get_width() / 2 + 10, it.get_height() / 2 + 65, id(roboto24), TextAlign::TOP_CENTER, "%.0f", id(climatedevice_currenttemp).state);
it.line(it.get_width() / 2 - 40, it.get_height() / 2 + 65, it.get_width() / 2 + 40, it.get_height() / 2 + 65);
it.image(it.get_width() / 2 - 30, it.get_height() / 2 + 40, temp_current_icon, ImageAlign::TOP_CENTER);
it.image(it.get_width() / 2 - 30, it.get_height() / 2 + 70, temp_target_icon, ImageAlign::TOP_CENTER);
it.circle(it.get_width() / 2 -12, 225, 3);
it.filled_circle(it.get_width() / 2, 225, 3);
it.circle(it.get_width() / 2 +12, 225, 3);
- id: page3
lambda: |-
if (id(mediaplayermute).state == "on")
{
it.image(it.get_width() / 2 + 80, it.get_height() / 2 -25, volume_mute, ImageAlign::TOP_CENTER);
}
else
{
it.image(it.get_width() / 2 + 80, it.get_height() / 2 -25, volume_notmute, ImageAlign::TOP_CENTER);
}
it.image(it.get_width() / 2, it.get_height() / 2 - 55, volumeknob, ImageAlign::TOP_CENTER);
it.printf(it.get_width() / 2, it.get_height() / 2 + 35, id(roboto24), TextAlign::TOP_CENTER, "%.0f%%", id(beam_volume).state * 100);
it.circle(it.get_width() / 2 -12, 225, 3);
it.circle(it.get_width() / 2, 225, 3);
it.filled_circle(it.get_width() / 2 +12, 225, 3);
on_page_change:
- to: page1
then:
- sensor.rotary_encoder.set_value:
id: rotaryencoder
value: !lambda return (id(dimmersensor_brightness).state / 255) * 100;
- component.update: my_lcd
- to: page2
then:
- sensor.rotary_encoder.set_value:
id: rotaryencoder
value: !lambda return id(climatedevice_setpoint).state;
- component.update: my_lcd
- to: page3
then:
- sensor.rotary_encoder.set_value:
id: rotaryencoder
value: !lambda 'return id(beam_volume).state * 100;'
- component.update: my_lcd
binary_sensor:
- platform: gpio
pin: GPIO42
name: "BacklightButton"
on_press:
- if:
condition:
- display.is_displaying_page: page1
then:
- homeassistant.service:
service: light.toggle
data:
entity_id: light.great_room_dimmer_4
- component.update: my_lcd
- if:
condition:
- display.is_displaying_page: page2
then:
if:
condition:
lambda: return id(climatedevice).state == "off";
then:
- homeassistant.service:
service: climate.turn_on
data:
entity_id: climate.doris
else:
- homeassistant.service:
service: climate.turn_off
data:
entity_id: climate.doris
- if:
condition:
- display.is_displaying_page: page3
then:
if:
condition:
lambda: return id(mediaplayermute).state == "off";
then:
- logger.log:
format: "The mediaplayer sensor reports value %s"
args: [ 'id(mediaplayermute).state' ]
- homeassistant.service:
service: media_player.volume_mute
data:
entity_id: media_player.living_room
is_volume_muted: 'true'
else:
- logger.log:
format: "The mediaplayer sensor reports value %s"
args: [ 'id(mediaplayermute).state' ]
- homeassistant.service:
service: media_player.volume_mute
data:
entity_id: media_player.living_room
is_volume_muted: 'false'
- platform: ld2410
has_target:
name: Presence
has_moving_target:
name: Moving Target
has_still_target:
name: Still Target
sensor:
- platform: rotary_encoder
name: "Rotary Encoder"
id: rotaryencoder
max_value: 31
min_value: 17
pin_a:
number: GPIO40
mode:
input: true
pullup: true
pin_b:
number: GPIO41
mode:
input: true
pullup: true
accuracy_decimals: 1
#on_value:
# - component.update: my_lcd
on_clockwise:
- display.page.show_next: my_lcd
- component.update: my_lcd
on_anticlockwise:
- display.page.show_previous: my_lcd
- component.update: my_lcd
- platform: homeassistant
name: "Media Volume"
id: "beam_volume"
entity_id: media_player.living_room
attribute: volume_level
on_value:
- if:
condition:
- display.is_displaying_page: page3
then:
- sensor.rotary_encoder.set_value:
id: rotaryencoder
value: !lambda 'return id(beam_volume).state;'
- component.update: my_lcd
- platform: ld2410
detection_distance:
name: Detection Distance
id: ddistance
on_value:
then:
if:
condition:
- lambda: 'return id(ddistance).state < 150;'
then:
if:
condition:
- light.is_off: backlight
then:
- light.turn_on: backlight
else:
- light.turn_off:
id: backlight
transition_length: 1s
light:
name: light
moving_distance:
name : Moving Distance
still_distance:
name: Still Distance
moving_energy:
name: Move Energy
still_energy:
name: Still Energy
- platform: homeassistant
name: "Dimmer Light Brightness"
id: "dimmersensor_brightness"
entity_id: light.great_room_dimmer_4
attribute: brightness
on_value:
- if:
condition:
- display.is_displaying_page: page1
then:
- sensor.rotary_encoder.set_value:
id: rotaryencoder
value: !lambda return (id(dimmersensor_brightness).state / 255) * 100;
- component.update: my_lcd
- platform: homeassistant
name: "Climate Device Current Temperature"
id: "climatedevice_currenttemp"
entity_id: climate.doris
attribute: current_temperature
on_value:
- if:
condition:
- display.is_displaying_page: page2
then:
- sensor.rotary_encoder.set_value:
id: rotaryencoder
value: !lambda return id(climatedevice_currenttemp).state;
- component.update: my_lcd
- platform: homeassistant
name: "Climate Device Setpoint"
id: "climatedevice_setpoint"
entity_id: climate.doris
attribute: temperature
on_value:
- component.update: my_lcd
light:
- platform: monochromatic
id: backlight
name: "Backlight"
output: oledbacklight
default_transition_length: 250ms
output:
- id: oledbacklight
platform: ledc
# pin: GPIO9
pin: GPIO21
max_power: 1
min_power: 0
switch:
- platform: ld2410
engineering_mode:
name: "engineering mode"
bluetooth:
name: "control bluetooth"
text_sensor:
- platform: ld2410
version:
name: "firmware version"
mac_address:
name: "mac address"
- platform: homeassistant
name: "Dimmer Light Sensor"
id: "dimmersensor"
entity_id: light.great_room_dimmer_4
filters:
- to_upper:
on_value:
- component.update: my_lcd
- platform: homeassistant
name: "Climate Device"
id: "climatedevice"
entity_id: climate.doris
filters:
- map:
- heat_cool -> auto
on_value:
- component.update: my_lcd
- platform: homeassistant
name: "Media Player Mute"
id: "mediaplayermute"
entity_id: media_player.living_room
attribute: is_volume_muted
on_value:
then:
- component.update: my_lcd
To answer your question directly, yes. I needed to change the pin from GPIO9 (LCD_BL) to GPIO21 (RGB LED)
I could then use output.set_level to change the brightness of the screen.
output:
- id: oledbacklight
platform: ledc
# pin: GPIO9
pin: GPIO21
max_power: 1
min_power: 0
I could then link this to a luminosity sensor to change the brightness value depending on the surrounding light levels- (similar to the below).
- platform: homeassistant
name: "Room Lux Sensor"
id: luxsensor
entity_id: sensor.sauron_illuminance
on_value:
- logger.log:
format: "The illumincance sensor reports value %.0f"
args: [ 'id(luxsensor).state' ]
- lambda: |-
float lux = id(luxsensor).state;
if (lux < 15)
{
id(oledbacklight).set_level(0.1);
}
else if (lux < 50)
{
id(oledbacklight).set_level(0.3);
}
else if (lux < 125)
{
id(oledbacklight).set_level(0.5);
}
else if (lux < 200)
{
id(oledbacklight).set_level(0.6);
}
else
{
id(oledbacklight).set_level(1);
}
1% brightness
30% brightness
Any chance you can put this info in a repo? It would be great to be able to keep up and test out your progress on this.
Sure
Much appreciated. I had never used ESPHome until I saw this post, and I was not looking forward to having to do any C++, so seeing that getting this thing working in this manner was a pretty huge deal, lol.
Edit, I am going to have to try and strip all that down to the bare minimum and work my way up from there. I tried to remove/change the obvious things that were non-existent in my setup, but have yet to get the backlight working. I can tell something is displayed, as I can barely see a small icon, but that’s about all I can tell that is going on.
Is there an example somewhere of a minimal template of just the necessary things that one could build up from, that anyone is aware of? Perhaps from a different but similar device?
Hey, that’s very nice! How did you connect it? Can you share a photo or a diagram so that I can connect it too?
can you share this file pleas ?
i have this erro code ?
Could not find file '/config/esphome/fonts/arial.ttf'. Please make sure it exists (full path: /config/esphome/fonts/arial.ttf).
I don’t use it in the actual code, it’s legacy, so you can either remove the reference or find it online from any of the numerous free font sites.
Couldn't find ID 'roboto24'. Please check you have defined an ID with that name in your configuration.
lambda: !lambda |-
float screenheight = it.get_height();
float screenwidth = it.get_width();
float halfscreenheight = screenheight / 2;
float halfscreenwidth = screenwidth /2;
if (id(climatedevice).state == "cool")
{
// cooling
it.filled_circle(halfscreenwidth, halfscreenheight, 120, my_light_blue);
it.image(halfscreenwidth, halfscreenheight + -55, ac_cool_80, ImageAlign::TOP_CENTER);
}
else if (id(climatedevice).state == "heat")
{
// heating
it.filled_circle(halfscreenwidth, halfscreenheight, 120, my_light_red);
it.image(halfscreenwidth, halfscreenheight + -55, ac_heat_80, ImageAlign::TOP_CENTER);
}
else if (id(climatedevice).state == "auto")
{
// auto heat or cool
it.filled_circle(halfscreenwidth, halfscreenheight, 120, my_light_orange);
it.image(halfscreenwidth, halfscreenheight + -55, ac_heatcool_80, ImageAlign::TOP_CENTER);
}
else if (id(climatedevice).state == "fan_only")
{
// fan only
it.filled_circle(halfscreenwidth, halfscreenheight, 120, my_light_orange);
it.image(halfscreenwidth, halfscreenheight + -55, ac_fan_80, ImageAlign::TOP_CENTER);
}
else if (id(climatedevice).state == "dry")
{
// dry
it.filled_circle(halfscreenwidth, halfscreenheight, 120, my_green);
// it.image(halfscreenwidth - 80, halfscreenheight - 20, ac_dry_40, ImageAlign::TOP_CENTER);
it.image(halfscreenwidth, halfscreenheight + -55, ac_dry_80, ImageAlign::TOP_CENTER);
}
else if (id(climatedevice).state == "off")
{
// off
it.image(halfscreenwidth, halfscreenheight - 55, power_off_icon_80, ImageAlign::TOP_CENTER);
}
it.printf(halfscreenwidth, halfscreenheight - 95, id(roboto24), TextAlign::TOP_CENTER, "Air-Con");
it.printf(halfscreenwidth + 10, halfscreenheight + 35, id(roboto24), TextAlign::TOP_CENTER, "%.0f", id(climatedevice_setpoint).state);
it.printf(halfscreenwidth + 10, halfscreenheight + 65, id(roboto24), TextAlign::TOP_CENTER, "%.0f", id(climatedevice_currenttemp).state);
it.line(halfscreenwidth - 40, halfscreenheight + 65, it.get_width() / 2 + 40, it.get_height() / 2 + 65);
it.image(halfscreenwidth - 30, halfscreenheight + 40, temp_current_icon, ImageAlign::TOP_CENTER);
it.image(halfscreenwidth - 30, halfscreenheight + 70, temp_target_icon, ImageAlign::TOP_CENTER);
it.circle(halfscreenwidth -12, 225, 3);
it.filled_circle(halfscreenwidth, 225, 3);
it.circle(halfscreenwidth +12, 225, 3); [source /config/esphome/m5dial.yaml:192]
this erro next ?
It’s defined in the fonts section of my file (line 149). So you will need to check what you’ve done.
Big thanks to @dgaust for sharing your code.
I stripped it back for others to play with.
Main changes in my code
- backlight to come on upon boot
- backlight pin changed back to 9
- added NFC reader
- removed arial font
I am no coder, but this should be able to help those just wanting to build from a starting block.
name: workshop-rotary
friendly_name: workshop-rotary
on_boot:
priority: 100
then:
- logger.log: "Startup - Backlight on"
- lambda: |-
id(oledbacklight).set_level(0.7);
# Enable Home Assistant API
api:
encryption:
key: !secret rotary_key
ota:
password: !secret ota_pass
globals:
- id: screenwidth
type: int
restore_value: no
- id: max_rotary_value
type: int
restore_value: no
initial_value: '1'
- id: min_rotary_value
type: int
restore_value: no
initial_value: '100'
external_components:
- source: github://the-smart-home-maker/esphome-4cello@gc9a01
components: ["gc9a01"]
i2c:
- id: bus_internal
sda: GPIO11
scl: GPIO12
- id: bus_porta
sda: 13
scl: 15
# interrupt: 14
esp32:
board: esp32-s3-devkitc-1
framework:
type: arduino
# Enable logging
logger:
level: DEBUG
image:
- file: mdi:volume-low
id: volume_notmute_80
resize: 80x80
font:
- file: "gfonts://Roboto"
id: roboto16
size: 16
- file: "gfonts://Roboto"
id: roboto20
size: 20
- file: "gfonts://Roboto"
id: roboto24
size: 24
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Rotary Fallback Hotspot"
password: !secret fallback_pass
captive_portal:
rc522_i2c:
i2c_id: bus_internal
address: 0x28
on_tag:
then:
- homeassistant.tag_scanned: !lambda 'return x;'
touchscreen:
- platform: lilygo_t5_47
interrupt_pin: GPIO14
i2c_id: bus_internal
id: my_touchscreen
on_touch:
- logger.log: "touched"
spi:
mosi_pin: GPIO5
clk_pin: GPIO6
display:
- platform: gc9a01
reset_pin: GPIO8
id: my_lcd
cs_pin: GPIO7
dc_pin: GPIO4
rotation: 90
pages:
- id: page1
lambda: |-
float screenheight = it.get_height();
float screenwidth = it.get_width();
float halfscreenheight = screenheight / 2;
float halfscreenwidth = screenwidth /2;
it.image(halfscreenwidth, halfscreenheight -55, volume_notmute_80, ImageAlign::TOP_CENTER);
it.filled_circle(halfscreenwidth -12, 225, 3);
it.circle(halfscreenwidth, 225, 3);
it.circle(halfscreenwidth +12, 225, 3);
on_page_change:
- to: page1
then:
- sensor.rotary_encoder.set_value:
id: rotaryencoder
value: !lambda 'return id(workshop_volume).state * 100;'
- component.update: my_lcd
binary_sensor:
- platform: gpio
pin: GPIO42
name: "BacklightButton"
sensor:
- platform: rotary_encoder
name: "Rotary Encoder"
id: rotaryencoder
max_value: 100
min_value: 0
pin_a:
number: GPIO40
mode:
input: true
pullup: true
pin_b:
number: GPIO41
mode:
input: true
pullup: true
accuracy_decimals: 1
on_value:
- lambda: |-
id(oledbacklight).set_level(0.7);
# - component.update: my_lcd
on_clockwise:
- display.page.show_next: my_lcd
- component.update: my_lcd
on_anticlockwise:
- display.page.show_previous: my_lcd
- component.update: my_lcd
light:
- platform: monochromatic
id: backlight
name: "Backlight"
output: oledbacklight
default_transition_length: 250ms
output:
- id: oledbacklight
platform: ledc
pin: GPIO9
#pin: GPIO21
max_power: 1
min_power: 0
thanks for this code
i get this errro code when i want to install you code
INFO ESPHome 2023.11.6
INFO Reading configuration /config/esphome/m5stack-dial.yaml...
Failed config
display.gc9a01: [source /config/esphome/m5stack-dial.yaml:105]
platform: gc9a01
reset_pin:
number: 8
mode:
output: True
input: False
open_drain: False
pullup: False
pulldown: False
drive_strength: 20.0
inverted: False
ignore_strapping_warning: False
id: my_lcd
cs_pin:
number: 7
mode:
output: True
input: False
open_drain: False
pullup: False
pulldown: False
drive_strength: 20.0
inverted: False
ignore_strapping_warning: False
dc_pin:
number: 4
mode:
output: True
input: False
open_drain: False
pullup: False
pulldown: False
drive_strength: 20.0
inverted: False
ignore_strapping_warning: False
rotation: 90
pages:
- id: page1
lambda: !lambda |-
float screenheight = it.get_height();
float screenwidth = it.get_width();
float halfscreenheight = screenheight / 2;
float halfscreenwidth = screenwidth /2;
it.image(halfscreenwidth, halfscreenheight -55, volume_notmute_80, ImageAlign::TOP_CENTER);
it.filled_circle(halfscreenwidth -12, 225, 3);
it.circle(halfscreenwidth, 225, 3);
it.circle(halfscreenwidth +12, 225, 3);
on_page_change:
- to: page1
then:
- sensor.rotary_encoder.set_value:
id: rotaryencoder
Couldn't find ID 'workshop_volume'. Please check you have defined an ID with that name in your configuration.
value: !lambda |-
return id(workshop_volume).state * 100;
- component.update:
id: my_lcd
auto_clear_enabled: True
update_interval: 5s
width: 240
height: 240
offset_y: 0
offset_x: 0
eight_bit_color: True
You can remove the section -
- to: page1
then:
- sensor.rotary_encoder.set_value:
id: rotaryencoder
value: !lambda 'return id(workshop_volume).state * 100;'
- component.update: my_lcd
workshop_volume is an entity in my HA setup.
Only left it in there to show how dgaust updated the values when the page shown was changed.
Has anyone been able to get the RTC to work. I have found a few randomize almost documentation-less examples but not been able to get them to work.
I think the issue is esphome assumes a type that these components have not implemented and even their examples will not compile for me.
I have the paper too. Anyone know w bit more about the guts here to understand what is happening? I want to use the RTC because the yaml I am working on runs this thing off of battery as a portable remote. I want to shut things down and keep the wifi off as long as possible.
I had not, but I am playing around with it since it looks like it uses the PCF8563 RTC chip PCF8563 Time Source — ESPHome
The below appears to work and will display (a currently incorrect) time
esphome:
name: m4dial
friendly_name: M4Dial
on_boot:
then:
# read the RTC time once when the system boots
- pcf8563.read_time: my_time
- text_sensor.template.publish:
id: template_text
state: !lambda |-
char str[17];
time_t currTime = id(my_time).now().timestamp;
strftime(str, sizeof(str), "%Y-%m-%d %H:%M", localtime(&currTime));
return { str };
time:
- platform: pcf8563
id: my_time
address: 0x38
# repeated synchronization is not necessary unless the external RTC
# is much more accurate than the internal clock
update_interval: never
- platform: homeassistant
# instead try to synchronize via network repeatedly ...
on_time_sync:
then:
# ... and update the RTC when the synchronization was successful
- pcf8563.write_time: my_time
- logger.log: "time synced"
text_sensor:
- platform: template
name: "RTC Sensor"
id: template_text
There are three i2c components on the internal bus at
0x28 is the RFID scanner
0x38 appears to be the RTC chip
0x51 is something I haven’t looked at yet
It’s starting to look more and more that I will have to learn some c++, and the esphome codebase, to turn these ft3267 drivers into a custom esphome component to get the touchscreen working since the pull request isn’t getting much traction
Same in regards to the screen, it is doing something curious where it needs the entire (seemingly) esphome codebase and compile time takes forever. I started to pull it apart, but it is working so…kind of meh.
I know C but never made a component. Looking at the shell of them now, but it is less about knowing C than knowing the libraries and structures expected here.
Hey, have you managed to get the RFID sensor working to add the new card and make the current card work?