andrew_NH
(Andrew)
December 10, 2024, 11:56pm
1
I want to build a graphic tide clock using LVGL. I easily build a gauges that spins 360 degrees with high tide at the top and low at the bottom.
I just need the time of the previous high tide and the next high tide and then divide that time by 360 degrees
This API call can get the high an low tides from a 72 hour range.
https://api.tidesandcurrents.noaa.gov/api/prod/datagetter?station=8454578&product=predictions&datum=MLLW&time_zone=lst_ldt&units=english&interval=hilo&format=json&begin_date=20241209&range=72
I just need some code to parse through the JSON and get the last and next high tide based on the current time.
Looks like there is already way to do this but the lambda is beyond my skill level.
Can anybody help me with this?
nickrout
(Nick Rout)
December 11, 2024, 7:23am
2
Use one of the tide integrations in home assistant and import the sensors into esphome.
andrew_NH
(Andrew)
December 11, 2024, 4:45pm
3
Yes it’s easy to get the hi/lo tide times from both this API or home assistant but it’s calculating the angle of the analog tide clock that I can’t figure out how to do.
nickrout
(Nick Rout)
December 11, 2024, 7:06pm
4
Take a look here Tides in Lovelace - #11 by nickrout . This is in Lovelace, but might give you some ideas.
andrew_NH
(Andrew)
January 14, 2025, 5:34am
5
I ended up needing to build a component that can calculate the tide a a percentage. So for example if the tide is half way between high and low the percentage is 25%. That way I can just have a meter that measures from 1 to 100. I did this by customizing the NOAA tide Home Assistant component.
I just need to add a bit of color and “fancy it up” a bit. But it’s working well.
1 Like
andrew_NH
(Andrew)
January 14, 2025, 5:34am
6
substitutions:
name: "tideclock"
friendly_name: "tide clock"
device_description: "Simple tide clock"
text_font: roboto24
esphome:
name: tideclock
friendly_name: "Tide Clock"
external_components:
- source: github://pr#8005
components: [lvgl]
host:
mac_address: "62:23:45:AF:B3:01"
touchscreen:
- platform: sdl
id: my_touchscreen
display: my_display
display:
- platform: sdl
id: my_display
update_interval: never
auto_clear_enabled: false
dimensions:
width: 480
height: 480
api:
logger:
time:
- platform: homeassistant
id: system_time
text_sensor:
- platform: homeassistant
entity_id: sensor.tides
attribute: tide_percentage
id: tide_percentage
on_value:
then:
- lvgl.indicator.update:
id: tide_level
value: !lambda |-
return std::stof(id(tide_percentage).state);
- platform: homeassistant
entity_id: sensor.tides
attribute: next_tide_type
id: next_tide_type
- platform: homeassistant
entity_id: sensor.tides
attribute: next_tide_time
id: next_tide_time
on_value:
- if:
condition:
text_sensor.state:
id: next_tide_type
state: 'Low'
then:
- lvgl.label.update:
id: low_tide_label
text:
format: "%s"
args: [ 'id(next_tide_time).state.c_str()' ]
else:
- lvgl.label.update:
id: high_tide_label
text:
format: "%s"
args: [ 'id(next_tide_time).state.c_str()' ]
- platform: homeassistant
entity_id: sensor.tides
attribute: last_tide_type
id: last_tide_type
- platform: homeassistant
entity_id: sensor.tides
attribute: last_tide_time
id: last_tide_time
on_value:
- if:
condition:
text_sensor.state:
id: last_tide_type
state: 'Low'
then:
- lvgl.label.update:
id: low_tide_label
text:
format: "%s"
args: [ 'id(last_tide_time).state.c_str()' ]
else:
- lvgl.label.update:
id: high_tide_label
text:
format: "%s"
args: [ 'id(last_tide_time).state.c_str()' ]
# -------------------------------------------
# LVGL Buttons
# -------------------------------------------
lvgl:
displays:
- my_display
touchscreens:
- my_touchscreen
theme:
obj:
radius: 0
border_width: 0
pad_all: 0
scrollable: false
# outline_width: 1
# outline_color: red
label:
radius: 0
border_width: 0
scrollable: false
# outline_width: 1
# outline_color: red
image:
radius: 0
border_width: 0
scrollable: false
# outline_width: 1
# outline_color: red
meter:
border_width: 0
pad_all: 0
scrollable: false
# outline_width: 1
# outline_color: red
page_wrap: true
pages:
- id: main_page
width: 100%
bg_color: Black
align: center
widgets:
- obj:
height: 480
width: 480
# layout:
# type: flex
# pad_row: 0
bg_color: White
align: center
pad_all: 4
widgets:
- meter:
height: 100%
width: 100%
text_font: roboto24
outline_width: 1
scales:
- range_from: 1
range_to: 100
angle_range: 360
rotation: 270
indicators:
- image:
id: tide_level
src: tide_pointer
pivot_x: 44
pivot_y: 44
value: 0
ticks:
count: 0
- range_from: 5
range_to: 1
angle_range: 120
rotation: 300
ticks:
width: 1
count: 5
major:
label_gap: 25
stride: 1
width: 2
length: 20
- range_from: 5
range_to: 1
angle_range: 120
rotation: 120
ticks:
width: 1
count: 5
major:
label_gap: 25
stride: 1
width: 2
length: 20
- label:
align: center
width: 100%
text_align: center
text_font: roboto24
text: "High Tide"
y: -215
- label:
id: high_tide_label
align: center
width: 100%
text_align: center
text_font: roboto24
text: "00:00 am"
y: -185
- label:
align: center
width: 100%
text_align: center
text_font: roboto24
text: "Low Tide"
y: 215
- label:
id: low_tide_label
align: center
width: 100%
text_align: center
text_font: roboto24
text: "00:00 am"
y: 185
# -------------------------------------------
# Graphics and Fonts
# -------------------------------------------
image:
- file: assets/tide_pointer.svg
id: tide_pointer
resize: 200x88 # 2.272 - 22x22
type: RGB565
use_transparency: true
font:
- file: "gfonts://Roboto"
id: roboto24
size: 24
bpp: 8
1 Like