-
Notifications
You must be signed in to change notification settings - Fork 4
/
P5-wood-pellet-stove.yaml
619 lines (618 loc) · 23.3 KB
/
P5-wood-pellet-stove.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
#----------------------------------------------------------
# Uses D1 mini ESP8266 chip
# version; 1.1.3
# date: 01-01-23
# 1.0.0 added a Power Level P5 (ultra low power) that is fully configurable while in ECO2 mode.
# 1.1.0 added echo of actual display messages and status via Display's MCU UART monitoring
#
# All of these mods will turn down the heat slightly during idle mode so the stove goes thru fewer
# on/off/igniter cycles and just maintains a lower heat output (for smaller rooms)
# so the room just cools slightly. when the room cools enuf, ECO2 mode will kick back to "Heating" which
# turns off this new power level, then once the room temp is +2F above set temp, stove
# goes into "Idle" mode again and new P5 is active again. The cycle repeats and the stove stays lit.
# and room doesnt drastically heat up driving your wife nuts.
# These mods ***require*** some very simple wifi module, MCU control board and Display board mods.
# See Github Discussions for complete details
#
#NOTE: I am NOT a career/pro programmer. There is tons of opportunity to consolidate many of the
# if/then statements that check things into convoluted programmer-porn style Lambda evaluations,
# but I hate writing and debugging Lambdas,
# so my code makes way more sense for the average person and is very easy to debug. Your mileage may vary.
# And, more inportant, it gets the job done!
#------------------------------------------
# *** TO DO ***
# Version 2.0 will have
#
# 1) when switching from ECO2 to STABILIZATION, stoke for 2 min (adjustable) then switch. this will
# reduce smoke and ash buildup on glass. or just use P3 instead of P1?
#
# 2) stop at 35 auger turns on lighting. this will prevent too many pellets in hopper, ESC1
# errors on lighting and reduce smoke and ash on glass.
# hopper still lights, it just takes a bit longer
#
#Version 3.0 will have
#1) an independent Pipe temp sensor. This will allow precise control over the burn pot.
#it works ok now, but pipe temp sensor only updates once every 60s from TuyaMCU
#so pellet adjustments like stoking can overshoot burn params.
#----------------------------------------
#
substitutions:
device_name: "house-wood-pellet-stove"
device_description: House Wood Pellet Stove running ESPHome
friendly_name: House Wood Pellet Stove
location: House
#----------------------------------------------------------
#Pin Mappins of unused but repurposed tywe1s gpio pins
#DONT USE GPIO0 or 2
# XX GPIO0 D3 DONT USE
# XX GPIO2 D4 DONT USE
# GPIO3 = RX label - UART rx from MCU control board
# GPIO4 D2 Hopper Pellet level echo pin
# GPIO5 D1 Hopper Pellet level trigger pin
# GPIO12 D6 Auger signal sensor from MCU - yellow
# GPIO13 TUYAMCU RX
# GPIO14 D5 LED & to Auger Motor opto isolator - red
# GPIO15 TUYAMCU TX
# GPIO16 D0 LED indicator that P5 is active - green
external_components:
- source: github://pr#4032
components: tuya
refresh: 0s
ota:
captive_portal:
wifi:
# use_address: dev-wood-pellet-stove.local # use when renaming this node
ssid: "Van Slyke"
password: !secret wifi_password
power_save_mode: none
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "${location}-Wood-Pellet-Stove"
password: !secret wifi_password
#
logger:
level: debug
baud_rate: 0 #required for UART sniffer to work
#
# define 2 UARTS, 1 for TYWE1S, other for MCU Display monitoring
#
uart:
#from Display control board TX pin to control board RX pin
- id: mcu_uart_bus
rx_pin: GPIO3 #D7 to rx pin on mcu board
baud_rate: 2400
rx_buffer_size: 80
debug:
direction: RX
dummy_receiver: true
after:
delimiter: [0xCC, 0x33]
sequence:
- lambda: |-
UARTDebug::log_hex(direction, bytes, ' ');
//Still log the data
//Some packets have 5 bytes
//might have to make this 3 if delimitar bytes get removed....
if (bytes.size()==5) {
if(bytes[0]==0xAA && bytes[1]==0x00) {
//id(MCUrawString).publish_state("Heartbeat");
//4B heartbeat, ignore
if(bytes[2]==0x20)
id(MCUrawString).publish_state("Welcome to use");
if(bytes[2]==0x6A)
id(MCUrawString).publish_state("Goodbye!");
if(bytes[2]==0x69)
id(MCUrawString).publish_state("Cleaning");
if(bytes[2]==0x63)
id(MCUrawString).publish_state("Cleaning");
if(bytes[2]==0x65)
id(MCUrawString).publish_state("Lighting");
if(bytes[2]==0x66)
id(MCUrawString).publish_state("Stabilization");
if(bytes[2]==0x62)
id(MCUrawString).publish_state("Switching OFF");
if(bytes[2]==0x69)
id(MCUrawString).publish_state("Cooling");
}
}
//Some packets have 6 bytes
if (bytes.size()==6) {
if(bytes[1]==0x01 && bytes[2]==0x46 && bytes[3]==0x02)
id(MCUrawString).publish_state("Welcome to use");
if(bytes[1]==0x01 && bytes[2]==0x49 && bytes[3]==0x80)
id(MCUrawString).publish_state("Stabilization");
if(bytes[1]==0x01 && bytes[2]==0x49 && bytes[3]==0x00)
id(MCUrawString).publish_state("Stabilization");
if(bytes[1]==0x01 && bytes[2]==0x49 && bytes[3]==0x81)
id(MCUrawString).publish_state("ECO2");
if(bytes[1]==0x01 && bytes[2]==0x48 && bytes[3]==0x80)
id(MCUrawString).publish_state("ECO1");
if(bytes[1]==0x01 && bytes[2]==0x48 && bytes[3]==0xC0)
id(MCUrawString).publish_state("Idling - ECO2");
if(bytes[1]==0x01 && bytes[2]==0x49 && bytes[3]==0x01)
id(MCUrawString).publish_state("Idling - ECO2");
if(bytes[1]==0x01 && bytes[2]==0x48 && bytes[3]==0x83)
id(MCUrawString).publish_state("ECO1");
if(bytes[1]==0x01 && bytes[2]==0x48 && bytes[3]==0xC3)
id(MCUrawString).publish_state("ECO2");
if(bytes[1]==0x01 && bytes[2]==0x49 && bytes[3]==0x81)
id(MCUrawString).publish_state("Idling - ECO2");
}
#communication from MCU to tywe1s chip
- id: tywe1s_uart
rx_pin: GPIO13
tx_pin: GPIO15
baud_rate: 9600
#
globals:
- id: auger_count_global
type: int
restore_value: no
initial_value: '0'
- id: stoking_flag_global
type: bool
initial_value: "false"
#
esphome:
name: ${device_name}
comment: ${device_description}
platform: ESP8266
board: esp01_1m
on_shutdown:
priority: 1000
then:
- switch.turn_off: auger_output_to_optoisolator
on_boot:
priority: -100
then:
- switch.turn_off: auger_output_to_optoisolator
- delay: 5s
- switch.turn_off: auger_output_to_optoisolator
- delay: 30s
- logger.log: "on_boot.30s delay over, STARTING UP"
- switch.turn_off: auger_output_to_optoisolator
- globals.set:
id: stoking_flag_global
value: 'false'
- if:
condition:
- binary_sensor.is_on: p5z
then:
- switch.turn_on: p5_indicator
- script.execute: new_auger_motor_power_level
else:
- switch.turn_off: p5_indicator
api:
reboot_timeout: 0s # disabled.
#
script:
- id: stoke_fire
#started by on_value,
#if burnpot is starting to go out, then rekindle it
mode: single
then:
#Check that fire pot is not going out
# - logger.log: #"script.stoke_fire. ENTERING"
# format: "dp108.on_value.ABOUT TO TEST LAMBDA |stoking_temp= %f"
# args: ['id(stoking_temp).state']
- delay: 1s
# - script.stop: stoke_fire
- while:
condition:
and:
- lambda: return id(stoking_flag);
- text_sensor.state: #Stove is IDLING, not HEATING
id: hvac_action
state: 'idle'
then: # STOKE the fire to avoid E1 Error "fire went out"
#might need to kick up P level so fan blows faster
# - logger.log:
# format: "SCRIPT.STOKING.Stoking FIRE | stoking_temp= %f"
# args: ['id(stoking_temp).state']
- switch.turn_on: auger_output_to_optoisolator
- logger.log: "SCRIPT.STOKER.AUGER TURNING"
- delay: 5s # SECONDS ON
- switch.turn_off: auger_output_to_optoisolator
- script.execute: new_auger_motor_power_level
- delay: 20s # SECONDS OFF
#
#SCRIPT New P5 Power level Auger motor control
#Started by the following events: p5z, on_boot, MCUrawString
#
- id: new_auger_motor_power_level
mode: single
then:
# - logger.log: "1script.new_auger_motor_power_level.STARTING"
#Main loop
- while:
condition:
and:
- text_sensor.state: #Stove is idling in ECO2 mode
id: hvac_action
state: 'idle'
- binary_sensor.is_on: p5z #We ARE In power level 5
- binary_sensor.is_off: stoking_flag # #we arent stoking the fire
then:
# - logger.log: "1script.new_auger_motor_power_level.ENTERING WHILE"
#new P5 Auger routine
- if:
condition:
- sensor.in_range: #**** Stove is lighting, exhaust is cold
id: stove_pipe_temp
below: 125.0
then:
# - logger.log: "2script.new_auger_motor_power_level.STOPPING SCRIPT, pipe temp < 200"
- script.stop: new_auger_motor_power_level
#else
- switch.turn_on: auger_output_to_optoisolator
#! this triggered while cooling
# - logger.log: "new_auger_motor_power_level.AUGER TURNING"
# - logger.log:
# format: "new P5 Auger routine | hvac_action= %s"
# args: ['id(hvac_action).state.c_str()']
- delay: !lambda "return id(auger_on_timez).state * 1000;"
# - logger.log: "3script.newP5 active. Auger ON delay completed"
- switch.turn_off: auger_output_to_optoisolator
- delay: !lambda "return id(auger_off_timez).state * 1000;"
# - logger.log: "4script.newP5 active. Auger OFF delay completed"
# - logger.log: "1script.new_auger_motor_power_level.EXITING WHILE"
#ENDWHILE
#
binary_sensor:
- platform: template # template sensors expose sensors to HA
name: ${location} Stoke Fire Flag
id: stoking_flag
# set it to the value of the global
lambda: |-
if (id(stoking_flag_global) == 1) {
return true;
} else {
return false;
}
# - platform: template
# name: "${location}_Heartbeat"
# id: heartbeat
# lambda: |-
# if (id(heartbeat_flag) == 1) {
# return true;
# } else {
# return false;
# }
#read new P5 power mode from home assistant, toggle repurposed Timer LED on display module
- platform: homeassistant
id: p5z
entity_id: input_boolean.p5
on_state:
then:
# - logger.log: "logger: P5 button changed"
- if:
condition:
- binary_sensor.is_on: p5z #p5 is active
then:
# - logger.log: "script.P5 sw = TRUE turning ON P5 indicator"
- switch.turn_on: p5_indicator
- script.execute: new_auger_motor_power_level
else:
# - logger.log: "script.p5z = FALSE, turning OFF P5 indicator"
- switch.turn_off: p5_indicator
#
#MCU CONTROL BOARD AUGER SENSOR
- platform: gpio
pin: GPIO12 #
internal: false # this is just a flag you expose and watch in Lovelace
id: esph_${location}_auger_sensor_from_mcu
name: "esph ${location} Auger Sensor from MCU" #Auger signal from MCU, goes low when Auger motor is running
filters:
- invert #flip it
on_state:
then:
# - logger.log: "GPIOI12.Auger.from.MCU.on_state just changed"
- if:
condition:
- binary_sensor.is_off: esph_${location}_auger_sensor_from_mcu
then:
#ECHO Auger
- if:
condition:
and:
- binary_sensor.is_off: esph_${location}_auger_sensor_from_mcu
- text_sensor.state: #Stove is HEATING not IDLING
id: hvac_action
state: 'heating'
then:
- switch.turn_off: auger_output_to_optoisolator
- if: #LIGHTING, echo Auger
condition:
and:
- binary_sensor.is_off: esph_${location}_auger_sensor_from_mcu
- text_sensor.state:
id: MCUrawString
state: 'Lighting'
then:
# - logger.log: "GPIOI12.Auger.from.MCU.Lighting"
- switch.turn_off: auger_output_to_optoisolator
- if: #HEATING (Stabilization), ECHO Auger
condition:
and:
- binary_sensor.is_on: esph_${location}_auger_sensor_from_mcu
- text_sensor.state: #Stove is HEATING, not IDLING
id: hvac_action
state: 'heating'
then:
#ECHO Auger
- switch.turn_on: auger_output_to_optoisolator
# - logger.log: "1GPIO12.AUGER TURNING"
- if: #LIGHTING, ECHO Auger
condition:
and:
- binary_sensor.is_on: esph_${location}_auger_sensor_from_mcu
- text_sensor.state:
id: MCUrawString
state: 'Lighting'
then:
- switch.turn_on: auger_output_to_optoisolator
# - logger.log: "2GPIO12.AUGER TURNING"
- lambda: id(auger_count_global) += 1; #keep track of how many auger turns happen and reset if stove lights
- lambda: id(auger_counter).publish_state(id(auger_count_global)); #publish it to the sensor
- if:
condition:
and:
- binary_sensor.is_off: p5z #NOT In power level 5
- binary_sensor.is_on: esph_${location}_auger_sensor_from_mcu
then:
- switch.turn_on: auger_output_to_optoisolator
# - logger.log: "3GPIO12.AUGER TURNING"
- if:
condition:
and:
- binary_sensor.is_off: p5z #NOT In power level 5
- binary_sensor.is_off: esph_${location}_auger_sensor_from_mcu
then:
- switch.turn_off: auger_output_to_optoisolator
button:
- platform: restart #allows remote reset of tywe1s chip from home assistant or internally
id: restart_esp
name: "ESPH ${location} Stove Restart"
#
# DEFINE ALL SENSORS AND SWITCHES
#
text_sensor:
#from MCU in the display board, gives us what specific text is shown on the display
- platform: template
id: MCUrawString
name: ${location}_display_text_sensor
on_value: # When value simply changes
# - logger.log: "0MCUrawString.on_value.entered"
- delay: 5s
- switch.turn_off: auger_output_to_optoisolator # just to be safe
- if:
condition:
# and:
- binary_sensor.is_on: p5z
- lambda: return id(MCUrawString).state == "Idling - ECO2";
- text_sensor.state: #Stove is idling in ECO2 mode
id: hvac_action
state: 'idle'
then:
# - logger.log: "1MCUrawString.new_auger_motor_power_level.CALLING SCRIPT"
- script.execute: new_auger_motor_power_level
else: #failsafe action
# - logger.log: "2MCUrawString.new_auger_motor_power_level.STOPPING SCRIPT"
- script.stop: new_auger_motor_power_level
- if: #keep track of how many auger turns happen during Lighting
#reset as soon as stove starts to lights
#better yet, interrupt it at just the right level to avoid ESC1 errors from too much fuel in pot
condition: #OR
- lambda: return id(MCUrawString).state == "Stabilization";
- lambda: return id(MCUrawString).state == "Idling - ECO2";
then:
- logger.log: "3MCUrawString.new_auger_motor_power_level.RESETTING AUGER COUNT = 0"
- lambda: id(auger_count_global) = 0;
- lambda: id(auger_counter).publish_state(id(auger_count_global));
#
- platform: template
name: "${location} Uptime (formatted)"
lambda: |-
uint32_t dur = id(uptime_s).state;
int dys = dur / 86400;
dur %= 86400;
int hrs = dur / 3600;
dur %= 3600;
int mnts = dur / 60;
dur %= 60;
return str_sprintf("%ud %02uh %02um %02us", dys, hrs, mnts, dur);
icon: mdi:clock-start
update_interval: 10s
#get these object values from home assistant
- platform: homeassistant
id: hvac_action
entity_id: climate.${location}_wood_pellet_stove
#this sensor changes from HEATING to IDLE in ECO2 mode only or when we reach set temp in ECO1.
attribute: hvac_action
#
sensor:
- platform: template
name: ${location} Auger Counter (lighting)
id: auger_counter
# do this whereever you want it to go back to HA
# - lambda: id(auger_counter).publish_state(id(auger_count_global));
#get these object values from home assistant
- platform: homeassistant
id: auger_off_timez
entity_id: input_number.auger_off_time
#
- platform: homeassistant
id: auger_on_timez
entity_id: input_number.auger_on_time
#stoke_temp
- platform: homeassistant
id: stoking_temp
entity_id: input_number.stoking_temp
force_update: true
#
#Ultrasonic Pellet level Sensor
#. https://community.home-assistant.io/t/pellet-stove-hopper-level-ultrasonic-sensor-and-thermostat-relay-esphome/292042
- platform: ultrasonic
trigger_pin: GPIO5 #BLUE WIRE D3
echo_pin: GPIO4 #GREEN WIRE D2
name: "esph ${location} pellet level in percent"
update_interval: 60s
# Optional variables:
icon: "mdi:sack-percent"
accuracy_decimals: 0
filters:
# Calculates in %
# Replace 0.46 (.36 trying less ) by the height of hopper. From the sensor to the bottom.
# I used this website to know how I should multiply my values :https://www.skillsyouneed.com/num/percent-change.html
- lambda: return (0.34-x)*(100/0.34);
unit_of_measurement: "%"
#
- platform: "tuya"
name: "ESPH ${location} Stove-Power On"
sensor_datapoint: 1
id: stove_on
#
- platform: "tuya"
name: "ESPH ${location} Stove-Error Code"
id: error_code
sensor_datapoint: 104
- platform: "tuya"
name: "ESPH ${location} Stove-Power Mode"
sensor_datapoint: 4
- platform: "tuya"
name: "ESPH ${location} Stove-Set Temp"
sensor_datapoint: 106
- platform: "tuya"
id: current_temp
name: "ESPH ${location} Stove-Current Temp"
sensor_datapoint: 107
- platform: "tuya"
name: "ESPH ${location} Stove-Pipe Temp"
id: stove_pipe_temp
sensor_datapoint: 108
on_value:
then:
# - logger.log: "dp108.on_value CHANGED"
- delay: 1s
- if:
condition:
and:
- lambda: return id(MCUrawString).state != "Switching OFF";
- lambda: return id(MCUrawString).state != "Lighting";
- sensor.in_range:
id: stove_pipe_temp
above: 125.0
- binary_sensor.is_on: p5z
#Adjust this temp value to keep pot from burning out
- lambda: |-
if (id(stove_pipe_temp).state <= id(stoking_temp).state) {
return true;
} else {
return false;
}
then:
# - logger.log:
# format: "dp108.on_value.EXECUTING SCRIPT Stoking FIRE | stoking_temp= %f"
# args: ['id(stoking_temp).state']
- globals.set: #expose to ha
id: stoking_flag_global
value: 'true'
- script.stop: new_auger_motor_power_level
- script.execute: stoke_fire
else:
- delay: 1s
- globals.set: #expose to ha
id: stoking_flag_global
value: 'false'
- script.stop: stoke_fire
- script.execute: new_auger_motor_power_level
#
- platform: "tuya"
name: "ESPH ${location} Stove-Protect Temp"
sensor_datapoint: 109
#more utility sensors
- platform: uptime
internal: false
name: ${friendly_name} Uptime
id: uptime_s
update_interval: 10s
#
#DEFINE SELECTS
#
select:
- platform: "tuya"
tuya_id: "${location}"
name: "ESPH ${location} Power Select"
enum_datapoint: 4
options:
0: P1-High
1: P2-Med High
2: P3-Med Low
3: P4-Low
- platform: "tuya"
tuya_id: "${location}"
name: "ESPH ${location} ECO Select"
id: eco_mode
enum_datapoint: 101
options:
0: ECO1 - Heat then OFF
1: ECO2 - Px then P4
on_value:
then:
# - logger.log: "select.eco_mode ECO Mode changed"
# Data points observed in Tuya iOT platform during ${location} debug mode
# 1 - Power on (Heat)
#4 - Mode P1/P2/P3P4
#101 - ECO1/ECO2
#104 - Error Code
#105 - unused
#106 - Set Temp
#107 - Current Temp
#108 - Pipe Temp
#109 - Protect Temp
#-----------------
#Datapoint 1: switch (value: OFF)
#Datapoint 105: enum (value: 0)
#Datapoint 4: enum (value: 0)
#Datapoint 101: enum (value: 0)
#Datapoint 106: int value (value: 68)
#Datapoint 107: int value (value: 64)
#Datapoint 108: int value (value: 68)
#Datapoint 109: int value (value: 72)
#Datapoint 104: bitmask (value: 0)
#GPIO Configuration: status: pin 5, reset: pin 0
#Product: '{"p":"8Dj5zVjGqPSXaUgf","v":"1.0.0","m":0}'
#
# Register the Tuya MCU connection
tuya:
id: "${location}"
uart_id: tywe1s_uart
#
switch:
- platform: safe_mode # expose this in HA just in case...
name: "${location} Wood Pellet Stove Restart (Safe Mode)"
#This sends the Auger signal to the optoisolator to turn on the Auger motor
- platform: gpio
pin: GPIO14
name: "esph ${location} AugerOut to optoisolator +LED"
id: auger_output_to_optoisolator
inverted: yes
#FAILSAFE. IF AUGER GETS STUCK on for over 5s, TURN IT OFF
on_turn_on:
- delay: 5s
- switch.turn_off: auger_output_to_optoisolator
#wire the time LED on front panel to GPIO1 to indicate when new P5 level is on
- platform: gpio
pin: GPIO16
name: "esph ${location} P5 indicator LED"
inverted: yes
id: p5_indicator
# - platform: "tuya"
#```
climate:
- platform: tuya
reports_fahrenheit: true # bug in stove requires this new flag. added 11/1/22 by ${location}s
name: "${location} Wood Pellet Stove"
switch_datapoint: 1
target_temperature_datapoint: 106
current_temperature_datapoint: 107