|
substitutions: |
|
name: esphome-web-adcbb8 |
|
internal_name: ESPHOME_adcbb8 |
|
friendly_name: wax-thermometer |
|
board_name: supermini esp32c3 |
|
comment: Max31855 and K type thermocouple probe |
|
font_family: 'Ubuntu Mono' |
|
font_size: '18' |
|
line_height: '16' |
|
col: '70' |
|
|
|
esphome: |
|
name: ${name} |
|
friendly_name: ${friendly_name} |
|
comment: "${board_name} - ${comment}" |
|
min_version: 2024.6.0 |
|
name_add_mac_suffix: false |
|
project: |
|
name: esphome.web |
|
version: dev |
|
platformio_options: |
|
board_build.flash_mode: dio |
|
on_boot: |
|
- priority: 800 |
|
then: |
|
- output.turn_on: buzzer |
|
# some MH-FMD passive buzzers with a PNP transistor will |
|
# get warm and waste power unless you set the IO line to |
|
# high, when not in use. |
|
# https://www.avrfreaks.net/s/topic/a5C3l000000Ub6bEAC/t156425 |
|
|
|
esp32: |
|
board: esp32-c3-devkitm-1 |
|
framework: |
|
type: esp-idf |
|
|
|
packages: |
|
common: !include ../common/common.yaml |
|
# web_server: !include ../common/web_server.yaml |
|
|
|
wifi: |
|
output_power: 13 |
|
|
|
i2c: |
|
sda: |
|
number: 10 |
|
scl: |
|
number: 9 |
|
scan: true |
|
id: bus_a |
|
frequency: 400kHz |
|
|
|
spi: |
|
miso_pin: |
|
number: 5 |
|
clk_pin: |
|
number: 4 |
|
|
|
number: |
|
- platform: template |
|
id: "temp_high" |
|
name: "Temp High" |
|
mode: "box" |
|
optimistic: true |
|
min_value: 0 |
|
max_value: 300 |
|
initial_value: 85 |
|
restore_value: true |
|
step: 0.1 |
|
unit_of_measurement: "°C" |
|
device_class: "temperature" |
|
- platform: template |
|
id: "temp_low" |
|
name: "Temp Low" |
|
mode: "box" |
|
optimistic: true |
|
min_value: 0 |
|
max_value: 300 |
|
initial_value: 76.667 |
|
restore_value: true |
|
step: 0.1 |
|
unit_of_measurement: "°C" |
|
device_class: "temperature" |
|
|
|
select: |
|
- platform: template |
|
name: "Display Unit" |
|
id: display_unit |
|
options: |
|
- "°C" |
|
- "°F" |
|
initial_option: "°C" |
|
optimistic: true |
|
|
|
|
|
switch: |
|
- platform: template |
|
name: "Alarm Sound" |
|
id: alarm_switch |
|
restore_mode: RESTORE_DEFAULT_OFF |
|
optimistic: true |
|
|
|
sensor: |
|
- platform: max31855 |
|
id: probe_temp |
|
cs_pin: |
|
number: 7 |
|
name: "Temperature" |
|
reference_temperature: |
|
name: "Reference Temp" |
|
id: ref_temp |
|
disabled_by_default: true |
|
update_interval: 3s |
|
|
|
- platform: copy |
|
id: calibrated_temp |
|
name: "Calibrated" |
|
source_id: probe_temp |
|
filters: |
|
- calibrate_linear: |
|
method: least_squares |
|
datapoints: |
|
- 4.3 -> 0.1 |
|
- 98.625 -> 100 |
|
# Map sensor values -> true values |
|
# 100 °C is boiling point. |
|
# Portland, OR at elevation 105FT and 29.99 barometric pressure boiling point is 99.97 °C |
|
# calculated using: https://www.thermoworks.com/bpcalc/ |
|
on_value_range: |
|
- above: !lambda "return id(temp_high).state;" |
|
then: |
|
- if: |
|
condition: |
|
- switch.is_on: alarm_switch |
|
then: |
|
- rtttl.play: "scale_up:d=16,o=5,b=160:c,d,e,f,g,a,b,c6,c,d,e,f,g,a,b,c6,c,d,e,f,g,a,b,c6" |
|
- below: !lambda "return id(temp_low).state;" |
|
then: |
|
- if: |
|
condition: |
|
- switch.is_on: alarm_switch |
|
then: |
|
- rtttl.play: "scale_down:d=16,o=4,b=100:b,a#,g#,f#,e,d#,c#,c" |
|
- platform: copy |
|
id: sliding_average |
|
name: "Sliding Window Moving Average" |
|
source_id: calibrated_temp |
|
filters: |
|
- sliding_window_moving_average: |
|
window_size: 10 |
|
send_every: 5 |
|
|
|
|
|
binary_sensor: |
|
- platform: gpio |
|
pin: |
|
number: 3 |
|
mode: |
|
input: true |
|
pullup: true |
|
id: decrease_temp |
|
on_press: |
|
then: |
|
- script.execute: |
|
id: adjust_settings_script |
|
my_action: 'decrement' |
|
- platform: gpio |
|
pin: |
|
number: 20 |
|
mode: |
|
input: true |
|
pullup: true |
|
id: increase_temp |
|
on_press: |
|
then: |
|
- script.execute: |
|
id: adjust_settings_script |
|
my_action: 'increment' |
|
- platform: gpio |
|
pin: |
|
number: 21 |
|
inverted: true |
|
mode: |
|
input: true |
|
pullup: true |
|
id: cycle_button |
|
# on_press: |
|
# then: |
|
# - script.execute: page_toggle_script |
|
on_multi_click: |
|
- timing: |
|
- ON for at most 0.25s |
|
- OFF for at least 0.1s |
|
then: |
|
- script.execute: page_toggle_script |
|
- timing: |
|
- ON for at least 1s |
|
then: |
|
- script.execute: CorF_script |
|
button: |
|
- platform: factory_reset |
|
name: Restart with Factory Default Settings |
|
|
|
font: |
|
- file: |
|
type: gfonts |
|
family: ${font_family} |
|
weight: 400 |
|
id: font1 |
|
size: ${font_size} |
|
- file: |
|
type: gfonts |
|
family: ${font_family} |
|
weight: 700 |
|
id: font1b |
|
size: ${font_size} |
|
|
|
graph: |
|
# Show bare-minimum auto-ranged graph |
|
- id: single_temperature_graph |
|
duration: 5min |
|
x_grid: 1min |
|
# y_grid: 1.0 |
|
width: 128 |
|
height: 64 |
|
traces: |
|
sensor: probe_temp |
|
line_type: DOTTED |
|
line_thickness: 3 |
|
|
|
display: |
|
- platform: ssd1306_i2c |
|
model: "SSD1306 128x64" |
|
address: 0x3C |
|
id: my_display |
|
pages: |
|
- id: page_main |
|
<<: !include |
|
file: ../common/thermostat_page_lines.yaml |
|
vars: |
|
bold_line: 1 |
|
|
|
- id: page_set_high |
|
<<: !include |
|
file: ../common/thermostat_page_lines.yaml |
|
vars: |
|
bold_line: 2 |
|
|
|
- id: page_set_low |
|
<<: !include |
|
file: ../common/thermostat_page_lines.yaml |
|
vars: |
|
bold_line: 3 |
|
|
|
- id: page_set_alarm |
|
<<: !include |
|
file: ../common/thermostat_page_lines.yaml |
|
vars: |
|
bold_line: 4 |
|
- id: page_graph |
|
lambda: |- |
|
const int l = ${line_height}; |
|
const auto d_unit = id(display_unit).state == "°F" ? "°F" : "°C"; |
|
const bool my_test = id(display_unit).state == "°F"; |
|
// it.print(0, 0, id(font1), "temp"); |
|
it.printf(0, 0, id(font1), " %3.0f %2s", my_test ? id(calibrated_temp).state * (9.0/5.0) + 32.0 : id(calibrated_temp).state, d_unit); |
|
|
|
// Draw the graph at position [x=0,y=0] |
|
it.graph(0, 0, id(single_temperature_graph)); |
|
# - id: page_calibrate |
|
# lambda: |- |
|
# const int l = ${line_height}; |
|
# const auto d_unit = id(display_unit).state == "°F" ? "°F" : "°C"; |
|
# const bool my_test = id(display_unit).state == "°F"; |
|
|
|
# it.print(0, 0, id(font1), "temp"); |
|
# it.printf(${col}, 0, id(font1), "%3.2f %2s", my_test ? id(probe_temp).state * (9.0/5.0) + 32.0 : id(probe_temp).state, d_unit); |
|
|
|
# it.print(0, l, id(font1), "calib"); |
|
# it.printf(${col}, l, id(font1), "%3.2f %2s", my_test ? id(calibrated_temp).state * (9.0/5.0) + 32.0 : id(calibrated_temp).state, d_unit); |
|
|
|
# it.print(0, l*2, id(font1), "ref"); |
|
# it.printf(${col}, l*2, id(font1), "%3.2f %2s", my_test ? id(ref_temp).state * (9.0/5.0) + 32.0 : id(ref_temp).state, d_unit); |
|
|
|
output: |
|
- platform: ledc |
|
pin: |
|
number: 2 |
|
id: buzzer |
|
|
|
rtttl: |
|
output: buzzer |
|
gain: 0.5 |
|
on_finished_playback: |
|
then: |
|
- output.turn_on: buzzer |
|
|
|
script: |
|
- id: page_toggle_script |
|
then: |
|
- display.page.show_next: my_display |
|
- component.update: my_display |
|
- id: adjust_settings_script |
|
parameters: |
|
my_action: string |
|
then: |
|
- if: |
|
condition: |
|
display.is_displaying_page: page_main |
|
then: |
|
- if: |
|
condition: |
|
lambda: |- |
|
return my_action == "increment"; |
|
then: |
|
- rtttl.play: "startup:d=16,o=4,b=360:d6.,a.,f#.,d." |
|
|
|
- if: |
|
condition: |
|
lambda: |- |
|
return my_action == "decrement"; |
|
then: |
|
- rtttl.play: "startup:d=16,o=4,b=360:16d6,8a,8f#,16d" |
|
|
|
- logger.log: |
|
format: "button: %s" |
|
args: my_action |
|
- if: |
|
condition: |
|
display.is_displaying_page: page_set_high |
|
then: |
|
- if: |
|
condition: |
|
lambda: |- |
|
return my_action == "increment"; |
|
then: |
|
- number.set: |
|
id: temp_high |
|
value: !lambda |- |
|
if(id(display_unit).state == "°F") { |
|
float f = id(temp_high).state * (9.0/5.0) + 32.0; |
|
f = f + 1.0; |
|
return (f - 32.0) * (5.0/9.0); |
|
} else { |
|
return id(temp_high).state + 1.0; |
|
} |
|
- if: |
|
condition: |
|
lambda: |- |
|
return my_action == "decrement"; |
|
then: |
|
- number.set: |
|
id: temp_high |
|
value: !lambda |- |
|
if(id(display_unit).state == "°F") { |
|
float f = id(temp_high).state * (9.0/5.0) + 32.0; |
|
f = f - 1.0; |
|
return (f - 32.0) * (5.0/9.0); |
|
} else { |
|
return id(temp_high).state - 1.0; |
|
} |
|
- if: |
|
condition: |
|
display.is_displaying_page: page_set_low |
|
then: |
|
- if: |
|
condition: |
|
lambda: |- |
|
return my_action == "increment"; |
|
then: |
|
- number.set: |
|
id: temp_low |
|
value: !lambda |- |
|
float f = id(temp_low).state * (9.0/5.0) + 32.0; |
|
f = f + 1.0; |
|
return (f - 32.0) * (5.0/9.0); |
|
- if: |
|
condition: |
|
lambda: |- |
|
return my_action == "decrement"; |
|
then: |
|
- number.set: |
|
id: temp_low |
|
value: !lambda |- |
|
float f = id(temp_low).state * (9.0/5.0) + 32.0; |
|
f = f - 1.0; |
|
return (f - 32.0) * (5.0/9.0); |
|
- if: |
|
condition: |
|
display.is_displaying_page: page_set_alarm |
|
then: |
|
- switch.toggle: alarm_switch |
|
- id: CorF_script |
|
then: |
|
- select.next: |
|
id: display_unit |
|
cycle: true |