About the same. I’m not getting as frequent of reboots, but they do happen sometimes, but I also see the unmodified ESPHome install with similar stability, so I don’t know what to think
Same here. Occasional reboots every other day. It would be best to find out where it is coming from for every crash but that requires logging everything from serial and possibly removing and adding every single sensor to reduce the possibilities. At this moment it isnt really convenient for me to do that and I don’t have a second board to test it. I don’t really want to stop logging data for too long.
Another way to look into these issues is to look here GitHub - nkitanov/iaq_board: IAQ Board is a DIY (Do-It-Yourself) device for measuring internal air quality
It looks like most of the hardware is the same and they encountered the sgp31 issues also.
Or just put all the sensors on a breadboard and see if the same issues arise after a while.
If someone has a good test strategy we can try to collectively find the main issue(s)
It’s either an individual, hardware specific issue (not likely, since there are multiple of you), or there is an issue with ESPHome. I say that because I’ve been running mostly-stock AirGradient code with OLED, SHT, TVOC, S8, PM5003 on a modified v3.3 PCB with OLED on 5V and SHT on 3.3V, I2C at 100kHz, Arduino Core 3.1.0, Software Serial v6.12.7 and it has been running non-stop for 17 days, 21 hours, and 9 minutes with zero reboots, zero sensor dropouts/timeout. Rock solid.
I’d concur that there is a problem with ESPHome. Having reduced the pair of devices I have to just literally the ESPHome WiFi stack and an uptime sensor, they still reboot every few hours.
It’s worth noting that ESPHome has several built-in reboots e.g. WiFi drops for a period, though detecting these is tricky when the presence of debug logging seems to sometimes be enough to cause more instability!
What I notice about @argafal’s approach is that the Home Assistant native API is not in use. I might have to try the MQTT approach. Despite the native one being ‘recommended’, I generally have more faith in MQTT.
Thanks all by the way for chipping in thoughts, this is both frustrating and interesting!
Having trialed some changes for a while, I am fairly confident in saying that this set of ESP lines are causing the problem for me. No sensors needed, just enabling UART seems to start reboot cycles. Remove this and the device is rock solid (albeit doing very little!)
esp8266:
board: d1_mini
framework:
version: recommended
platform_version: 3.2.0
esphome:
name: "${devicename}"
libraries:
- uart=https://github.com/plerup/espsoftwareserial.git#6.17.1
# Remove this, reboots solved
uart:
- rx_pin: D5
tx_pin: D6
baud_rate: 9600
id: uart1
- rx_pin: D4
tx_pin: D3
baud_rate: 9600
id: uart2
So this does seem to point back to some instability around the UART code again, but I was under the impression 6.17.1 did not have the major errors the new versions did. Very odd; I’ll see if I can carve out some time to see what the actual reboot failures are.
The graph downloaded confirms that, unless the build is really broken in dependency management somehow, that it has the right libraries
Dependency Graph
|-- ESPAsyncTCP-esphome @ 1.2.3
|-- EspSoftwareSerial @ 6.17.1+sha.12f8480
|-- ESPAsyncWebServer-esphome @ 2.1.0
| |-- ESPAsyncTCP-esphome @ 1.2.3
| |-- Hash @ 1.0
| |-- ESP8266WiFi @ 1.0
|-- DNSServer @ 1.1.1
|-- ESP8266WiFi @ 1.0
|-- ESP8266mDNS @ 1.2
|-- AsyncMqttClient-esphome @ 0.8.6
| |-- ESPAsyncTCP-esphome @ 1.2.3
|-- ArduinoJson @ 6.18.5
Just following up, I got the following software WDT errors in two stack dumps
Stack 1
WARNING Found stack trace! Trying to decode it
WARNING Decoded 0x402338f0: tcp_tmr at /home/earle/src/esp-quick-toolchain/arduino/tools/sdk/lwip2/builder/lwip2-src/src/core/tcp.c:239
WARNING Decoded 0x402418b6: sta_input
WARNING Decoded 0x402321f3: tcpip_tcp_timer at /home/earle/src/esp-quick-toolchain/arduino/tools/sdk/lwip2/builder/lwip2-src/src/core/timeouts.c:153
WARNING Decoded 0x40253688: pm_keep_active_enable
WARNING Decoded 0x401007a4: ets_post
WARNING Decoded 0x40259669: ets_timer_handler_isr
WARNING Decoded 0x402596ae: ets_timer_handler_isr
WARNING Decoded 0x40222772: loop_task(ETSEventTag*) at core_esp8266_main.cpp
WARNING Decoded 0x40105a8d: call_user_start_local
WARNING Decoded 0x40105a93: call_user_start_local
WARNING Decoded 0x4010000d: call_user_start
WARNING Decoded 0x401000ab: app_entry_redefinable
WARNING Decoded 0x402498dc: cont_ret at cont.S.o
WARNING Decoded 0x4024988d: cont_continue at cont.S.o
WARNING Decoded 0x401007a4: ets_post
WARNING Decoded 0x40106225: ets_timer_disarm
WARNING Decoded 0x40100aa5: interrupt_handler
WARNING Decoded 0x40100a98: interrupt_handler
WARNING Decoded 0x4010028c: esphome::ISRInternalGPIOPin::digital_read()
WARNING Decoded 0x401058d9: lmacTxFrame
WARNING Decoded 0x401007a4: ets_post
WARNING Decoded 0x40102b25: rcUpdateTxDone
WARNING Decoded 0x401026f4: pp_post
WARNING Decoded 0x40105973: lmacTxFrame
WARNING Decoded 0x401007a4: ets_post
WARNING Decoded 0x401007a4: ets_post
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x401003aa: esphome::uart::ESP8266SoftwareSerial::gpio_intr(esphome::uart::ESP8266SoftwareSerial*)
WARNING Decoded 0x4010345c: rcReachRetryLimit
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x401003aa: esphome::uart::ESP8266SoftwareSerial::gpio_intr(esphome::uart::ESP8266SoftwareSerial*)
WARNING Decoded 0x401026f4: pp_post
WARNING Decoded 0x40100a98: interrupt_handler
WARNING Decoded 0x40104b4e: lmacRecycleMPDU
WARNING Decoded 0x40104fbf: lmacRecycleMPDU
WARNING Decoded 0x401009d4: interrupt_handler
WARNING Decoded 0x402090f8: esphome::socket::LWIPRawImpl::accept(sockaddr*, unsigned int*)
WARNING Decoded 0x40207a2b: esphome::ota::OTAComponent::handle_()
WARNING Decoded 0x402090f8: esphome::socket::LWIPRawImpl::accept(sockaddr*, unsigned int*)
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x401003aa: esphome::uart::ESP8266SoftwareSerial::gpio_intr(esphome::uart::ESP8266SoftwareSerial*)
WARNING Decoded 0x40100a98: interrupt_handler
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x401009d4: interrupt_handler
WARNING Decoded 0x4022c66a: _dtoa_r at /workdir/repo/newlib/newlib/libc/stdlib/dtoa.c:520
WARNING Decoded 0x4022c65b: _dtoa_r at /workdir/repo/newlib/newlib/libc/stdlib/dtoa.c:519
WARNING Decoded 0x4022c65b: _dtoa_r at /workdir/repo/newlib/newlib/libc/stdlib/dtoa.c:519 [120/230]
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x40207a2b: esphome::ota::OTAComponent::handle_()
WARNING Decoded 0x40100a98: interrupt_handler
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x401003aa: esphome::uart::ESP8266SoftwareSerial::gpio_intr(esphome::uart::ESP8266SoftwareSerial*)
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x4022df7e: __d2b at /workdir/repo/newlib/newlib/libc/stdlib/mprec.c:779
WARNING Decoded 0x40100a98: interrupt_handler
WARNING Decoded 0x4022ccd9: _dtoa_r at /workdir/repo/newlib/newlib/libc/stdlib/dtoa.c:854
WARNING Decoded 0x4022df7e: __d2b at /workdir/repo/newlib/newlib/libc/stdlib/mprec.c:779
WARNING Decoded 0x4022ccd9: _dtoa_r at /workdir/repo/newlib/newlib/libc/stdlib/dtoa.c:854
WARNING Decoded 0x4022e254: __ssputs_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:232
WARNING Decoded 0x402290e1: __cvt at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf_float.c:102
WARNING Decoded 0x4022e254: __ssputs_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:232
WARNING Decoded 0x4022e190: __ssputs_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:179
WARNING Decoded 0x40230f47: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create(unsigned int&, unsigned int) at /workdir/arena.x86_64/gcc-gnu/xtensa-lx106-elf/libstdc++-v3/include/bits/basi
c_string.tcc:156
WARNING Decoded 0x40229599: _printf_float at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf_float.c:326 (discriminator 4)
WARNING Decoded 0x40101202: free
WARNING Decoded 0x40231800: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::substr(unsigned int, unsigned int) const at /workdir/arena.x86_64/gcc-gnu/xtensa-lx106-elf/libstdc++-v3/include/bits/ba
sic_string.h:2837
WARNING Decoded 0x4022e190: __ssputs_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:179
WARNING Decoded 0x402313a4: std::char_traits<char>::assign(char&, char const&) at /workdir/arena.x86_64/gcc-gnu/xtensa-lx106-elf/libstdc++-v3/include/bits/char_traits.h:329
(inlined by) std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_set_length(unsigned int) at /workdir/arena.x86_64/gcc-gnu/xtensa-lx106-elf/libstdc++-v3/include/bits/basic_string.h:219
(inlined by) std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace_aux(unsigned int, unsigned int, unsigned int, char) at /workdir/arena.x86_64/gcc-gnu/xtensa-lx106-elf/libstdc++-v3/include
/bits/basic_string.tcc:419
WARNING Decoded 0x4022e690: _svfprintf_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:658
WARNING Decoded 0x40231834: operator delete(void*) at /workdir/repo/gcc-gnu/libstdc++-v3/libsupc++/del_op.cc:50
WARNING Decoded 0x40230f64: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose() at /workdir/arena.x86_64/gcc-gnu/xtensa-lx106-elf/libstdc++-v3/include/bits/basic_string.h:235
WARNING Decoded 0x4021d1c4: AsyncMqttClient::publish(char const*, unsigned char, bool, char const*, unsigned int, bool, unsigned short)
WARNING Decoded 0x40230f64: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose() at /workdir/arena.x86_64/gcc-gnu/xtensa-lx106-elf/libstdc++-v3/include/bits/basic_string.h:235
WARNING Decoded 0x4022a469: snprintf at /workdir/repo/newlib/newlib/libc/stdio/snprintf.c:87 (discriminator 4)
WARNING Decoded 0x402227f1: esp_yield
WARNING Decoded 0x40222f15: __delay
WARNING Decoded 0x40101010: umm_free_core at umm_malloc.cpp
WARNING Decoded 0x40101202: free
WARNING Decoded 0x40231834: operator delete(void*) at /workdir/repo/gcc-gnu/libstdc++-v3/libsupc++/del_op.cc:50
WARNING Decoded 0x40230f64: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose() at /workdir/arena.x86_64/gcc-gnu/xtensa-lx106-elf/libstdc++-v3/include/bits/basic_string.h:235
WARNING Decoded 0x4020555d: esphome::mqtt::MQTTClientComponent::publish(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*, unsigned int, unsigned char, bool)
WARNING Decoded 0x4021052b: void std::__push_heap<__gnu_cxx::__normal_iterator<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >*, std::vector<std::unique_ptr<esphome::Sc
heduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, std::allocator<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > > > >, int, std::unique
_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, __gnu_cxx::__ops::_Iter_comp_val<bool (*)(std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Schedule
r::SchedulerItem> > const&, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&)> >(__gnu_cxx::__normal_iterator<std::unique_ptr<esphome::Scheduler::SchedulerItem, s
td::default_delete<esphome::Scheduler::SchedulerItem> >*, std::vector<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, std::allocator<std::unique_ptr<esphome::Scheduler
::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > > > >, int, int, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, __gnu_cxx::__ops::_Iter_comp
_val<bool (*)(std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::Schedul
erItem> > const&)>&)
WARNING Decoded 0x40101202: free
WARNING Decoded 0x402108fc: void std::__adjust_heap<__gnu_cxx::__normal_iterator<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >*, std::vector<std::unique_ptr<esphome::
Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, std::allocator<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > > > >, int, std::uniq
ue_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Sched
uler::SchedulerItem> > const&, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&)> >(__gnu_cxx::__normal_iterator<std::unique_ptr<esphome::Scheduler::SchedulerItem
, std::default_delete<esphome::Scheduler::SchedulerItem> >*, std::vector<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, std::allocator<std::unique_ptr<esphome::Schedu
ler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > > > >, int, int, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, __gnu_cxx::__ops::_Iter_c
omp_iter<bool (*)(std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::Sch
edulerItem> > const&)>)
WARNING Decoded 0x40210320: esphome::Scheduler::SchedulerItem::cmp(std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&, std::unique_ptr<esphome::Scheduler::Scheduler
Item, std::default_delete<esphome::Scheduler::SchedulerItem> > const&)
WARNING Decoded 0x40206c89: esphome::mqtt::MQTTSensorComponent::publish_state(float) [60/230]
WARNING Decoded 0x40210320: esphome::Scheduler::SchedulerItem::cmp(std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&, std::unique_ptr<esphome::Scheduler::Scheduler
Item, std::default_delete<esphome::Scheduler::SchedulerItem> > const&)
WARNING Decoded 0x40218ef8: esp8266::polledTimeout::timeoutTemplate<false, esp8266::polledTimeout::YieldPolicy::DoNothing, esp8266::polledTimeout::TimePolicy::TimeUnit<esp8266::polledTimeout::TimePolicy::TimeSourceMillis, 1000ul
l> >::expiredOneShot() const
WARNING Decoded 0x40106369: ets_timer_arm_new
WARNING Decoded 0x402227f1: esp_yield
WARNING Decoded 0x40222f15: __delay
WARNING Decoded 0x4020e3fb: esphome::Application::loop()
(Stack 2
in next post due to post length)
which both look reliably inside ESP8266SoftwareSerial::read_bit
I’m not sure I’m much closer to understanding the problem, though I shall try again with SoftwareSerial 8.0.1 and see if anything changes. I did read on espsoftwareserial
github that there can be issues with WiFi interrupts being higher priority than UART interrupts and thus WiFi can be a potential cause of timeouts, so I think that’s probably my next mole to try whacking…
It’s slightly frustrating to keep running into advice that could be summarised as ‘Don’t use ESP8266’ when the existing Pro hardware is already purchased & using it
Stack 2
WARNING Found stack trace! Trying to decode it
WARNING Decoded 0x40232123: lwip_cyclic_timer at /home/earle/src/esp-quick-toolchain/arduino/tools/sdk/lwip2/builder/lwip2-src/src/core/timeouts.c:261
WARNING Decoded 0x402601bc: etharp_output
WARNING Decoded 0x4023207d: memp_free at /home/earle/src/esp-quick-toolchain/arduino/tools/sdk/lwip2/builder/lwip2-src/src/core/memp.c:447
WARNING Decoded 0x40253688: pm_keep_active_enable
WARNING Decoded 0x401007a4: ets_post
WARNING Decoded 0x40259669: ets_timer_handler_isr
WARNING Decoded 0x402596ae: ets_timer_handler_isr
WARNING Decoded 0x40222772: loop_task(ETSEventTag*) at core_esp8266_main.cpp
WARNING Decoded 0x40105a8d: call_user_start_local
WARNING Decoded 0x40105a93: call_user_start_local
WARNING Decoded 0x4010000d: call_user_start
WARNING Decoded 0x401000ab: app_entry_redefinable
WARNING Decoded 0x402498dc: cont_ret at cont.S.o
WARNING Decoded 0x4024988d: cont_continue at cont.S.o
WARNING Decoded 0x401058d9: lmacTxFrame
WARNING Decoded 0x401007a4: ets_post
WARNING Decoded 0x40102b25: rcUpdateTxDone
WARNING Decoded 0x401026f4: pp_post
WARNING Decoded 0x4010598b: lmacRxDone
WARNING Decoded 0x4010327f: rcReachRetryLimit
WARNING Decoded 0x401007a4: ets_post
WARNING Decoded 0x4010345c: rcReachRetryLimit
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x401003aa: esphome::uart::ESP8266SoftwareSerial::gpio_intr(esphome::uart::ESP8266SoftwareSerial*)
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x401003aa: esphome::uart::ESP8266SoftwareSerial::gpio_intr(esphome::uart::ESP8266SoftwareSerial*)
WARNING Decoded 0x40100a98: interrupt_handler
WARNING Decoded 0x40207a2b: esphome::ota::OTAComponent::handle_()
WARNING Decoded 0x401009d4: interrupt_handler
WARNING Decoded 0x40207a32: esphome::ota::OTAComponent::handle_()
WARNING Decoded 0x40207a2b: esphome::ota::OTAComponent::handle_()
WARNING Decoded 0x402090f8: esphome::socket::LWIPRawImpl::accept(sockaddr*, unsigned int*)
WARNING Decoded 0x40104880: lmacProcessTXStartData
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x401037e7: wDev_ProcessFiq
WARNING Decoded 0x401054be: lmacMSDUAged
WARNING Decoded 0x40103638: wDev_ProcessFiq
WARNING Decoded 0x401007a4: ets_post
WARNING Decoded 0x4022c4b8: _dtoa_r at /workdir/repo/newlib/newlib/libc/stdlib/dtoa.c:476
WARNING Decoded 0x4022c4b8: _dtoa_r at /workdir/repo/newlib/newlib/libc/stdlib/dtoa.c:476
WARNING Decoded 0x40255e9f: pp_attach
WARNING Decoded 0x40255e9f: pp_attach
WARNING Decoded 0x40207a2b: esphome::ota::OTAComponent::handle_()
WARNING Decoded 0x40255eee: pp_attach
WARNING Decoded 0x401007a4: ets_post
WARNING Decoded 0x401026f4: pp_post
WARNING Decoded 0x40254faf: ppTxPkt
WARNING Decoded 0x4023e1d3: ieee80211_output_pbuf
WARNING Decoded 0x4022df7e: __d2b at /workdir/repo/newlib/newlib/libc/stdlib/mprec.c:779
WARNING Decoded 0x4022df7e: __d2b at /workdir/repo/newlib/newlib/libc/stdlib/mprec.c:779
WARNING Decoded 0x4022ccd9: _dtoa_r at /workdir/repo/newlib/newlib/libc/stdlib/dtoa.c:854
WARNING Decoded 0x4022df7e: __d2b at /workdir/repo/newlib/newlib/libc/stdlib/mprec.c:779
WARNING Decoded 0x4022ccd9: _dtoa_r at /workdir/repo/newlib/newlib/libc/stdlib/dtoa.c:854
WARNING Decoded 0x4022ccd9: _dtoa_r at /workdir/repo/newlib/newlib/libc/stdlib/dtoa.c:854
WARNING Decoded 0x4022df7e: __d2b at /workdir/repo/newlib/newlib/libc/stdlib/mprec.c:779
WARNING Decoded 0x4022ccd9: _dtoa_r at /workdir/repo/newlib/newlib/libc/stdlib/dtoa.c:854
WARNING Decoded 0x4022e254: __ssputs_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:232
WARNING Decoded 0x402290e1: __cvt at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf_float.c:102
WARNING Decoded 0x4022e254: __ssputs_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:232
WARNING Decoded 0x4022e190: __ssputs_r at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf.c:179
WARNING Decoded 0x40230f47: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create(unsigned int&, unsigned int) at /workdir/arena.x86_64/gcc-gnu/xtensa-lx106-elf/libstdc++-v3/include/bits/basic_string.tcc:156
WARNING Decoded 0x40229599: _printf_float at /workdir/repo/newlib/newlib/libc/stdio/nano-vfprintf_float.c:326 (discriminator 4)
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x401003aa: esphome::uart::ESP8266SoftwareSerial::gpio_intr(esphome::uart::ESP8266SoftwareSerial*)
WARNING Decoded 0x40231800: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::substr(unsigned int, unsigned int) const at /workdir/arena.x86_64/gcc-gnu/xtensa-lx106-elf/libstdc++-v3/include/bits/basic_string.h:2837
WARNING Decoded 0x40100a98: interrupt_handler
WARNING Decoded 0x401009d4: interrupt_handler
WARNING Decoded 0x401007a4: ets_post
WARNING Decoded 0x402216c9: String::copy(char const*, unsigned int)
WARNING Decoded 0x40106225: ets_timer_disarm
WARNING Decoded 0x40100aa5: interrupt_handler
WARNING Decoded 0x40100a98: interrupt_handler
WARNING Decoded 0x4010028c: esphome::ISRInternalGPIOPin::digital_read()
WARNING Decoded 0x401003aa: esphome::uart::ESP8266SoftwareSerial::gpio_intr(esphome::uart::ESP8266SoftwareSerial*)
WARNING Decoded 0x40100a98: interrupt_handler
WARNING Decoded 0x40100a98: interrupt_handler
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x401003aa: esphome::uart::ESP8266SoftwareSerial::gpio_intr(esphome::uart::ESP8266SoftwareSerial*)
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x4010032c: esphome::uart::ESP8266SoftwareSerial::read_bit_(unsigned int*, unsigned int const&)
WARNING Decoded 0x401003aa: esphome::uart::ESP8266SoftwareSerial::gpio_intr(esphome::uart::ESP8266SoftwareSerial*)
WARNING Decoded 0x40100a98: interrupt_handler
WARNING Decoded 0x40100a98: interrupt_handler
WARNING Decoded 0x4025f8b0: chip_v6_unset_chanfreq
WARNING Decoded 0x401009d4: interrupt_handler
WARNING Decoded 0x4021052b: void std::__push_heap<__gnu_cxx::__normal_iterator<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >*, std::vector<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, std::allocator<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > > > >, int, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, __gnu_cxx::__ops::_Iter_comp_val<bool (*)(std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&)> >(__gnu_cxx::__normal_iterator<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >*, std::vector<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, std::allocator<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > > > >, int, int, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, __gnu_cxx::__ops::_Iter_comp_val<bool (*)(std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&)>&)
WARNING Decoded 0x4020d300: esphome::wifi::WiFiComponent::wifi_sta_ip()
WARNING Decoded 0x402108fc: void std::__adjust_heap<__gnu_cxx::__normal_iterator<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >*, std::vector<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, std::allocator<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > > > >, int, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&)> >(__gnu_cxx::__normal_iterator<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >*, std::vector<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, std::allocator<std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > > > >, int, int, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> >, __gnu_cxx::__ops::_Iter_comp_iter<bool (*)(std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&)>)
WARNING Decoded 0x40210320: esphome::Scheduler::SchedulerItem::cmp(std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&)
WARNING Decoded 0x40210320: esphome::Scheduler::SchedulerItem::cmp(std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&, std::unique_ptr<esphome::Scheduler::SchedulerItem, std::default_delete<esphome::Scheduler::SchedulerItem> > const&)
WARNING Decoded 0x4020dc2c: esphome::wifi::WiFiComponent::wifi_ssid[abi:cxx11]()
WARNING Decoded 0x40218ef8: esp8266::polledTimeout::timeoutTemplate<false, esp8266::polledTimeout::YieldPolicy::DoNothing, esp8266::polledTimeout::TimePolicy::TimeUnit<esp8266::polledTimeout::TimePolicy::TimeSourceMillis, 1000ull> >::expiredOneShot() const
WARNING Decoded 0x40106369: ets_timer_arm_new
WARNING Decoded 0x402227f1: esp_yield
WARNING Decoded 0x40222f15: __delay
WARNING Decoded 0x4020e3fb: esphome::Application::loop()
I’ve been away for a bit but I’ve seen my device mostly restart on hardware wdt and a occasional wdt 4 so software. No stack dumps saved sadly. My uptime is now around 5/6 days. And I also run espsoftwareserial 8.0.1 and all other the recommended versions.
I have about 20 esp devices with esphome and all run the native api. Only the airgradient has reset issues so I don’t want to blame the api at this point. Many have uptimes of months.
I’ve seen that esphome 2023.4.2 released today has a fix for i2c reset issue which can cause a hardware wdt. I updated immediatly and I will test again for next days/weeks. If it only resets on software error it makes it a lot easier to debug.
Some progress. I was able to narrow down the UART problem more. The specific problem area seems to be 9600 baud. If I init the board with this, I’ll get regular reboots (with zero sensors listed in ESPHome). With 115200 (which of course renders the associated sensors useless), the board appears to be stable.
I just found a Github issue that sounds almost identical to this problem. Frustratingly it was closed as theoretically fixed in ESPSoftwareSerial 5.3.0. It’s still interesting to see that this sort of thing has cropped before.
I was curious if anyone on this thread has had any luck proving that ESPHome actually pays attention to version information. I notice some really odd behaviour, when I select framework version
& platform_version
.
Changing version
to e.g. 3.1.1
yields no change other than a warning about not using the recommended version.
Changing platform_version
yields no messaging whatsoever.
Changing both to e.g. 3.1.1 & 3.2.0 respectively yields weird messages like Installing platformio/framework-arduinoespressif8266 @ ~3.30101.0
, which bears no resemblance to 3.2.0, but does mention 3.1.1 in its documentation (3.1.1 of what, nobody bothered to document).
None of this behaviour seems to match what is written in ESPHome’s documentation.
Other than whichever bunch of devs responsible for this need training in versioning semantics and documentation, does anyone know whether we can prove we’re actually running a given version of these packages?
ESPHome’s build dependency graph looks to be semi-useless, because it doesn’t even mention any of these packages.
I should add, to the above, the reason I’m trying to narrow this down is that with version: latest
, platform_version: 4.2.0
and ESPSoftwareSerial:8.0.3
I’m suddenly getting hardware watchdog timeouts, whereas a board with just version: recommended
and ESPSoftwareSerial:8.0.1
is still stable (if no UART sensors), but it’s currently impossible to prove anything as to what I’m changing!
In my experience it uses the right version and installs a new version if it isnt cached. I don’t think it is ever possible to ask code which version it is because is dependent on the developer to put that into a debug message or so. The reason I know changing arduino versions works is because dependencies are changed and my device did respond different and some bugs have gone away.
To give a little update on my crashes. It only happens every few weeks now. The i2c fix has helped in my instance. Most of the time its hardware watchdog. I run the recommended arduino framework and espsoftwareserial 8.0.1.
Thanks @Hendrik - out of curiousity, is your full config posted anywhere? I’d be interested to compare, as I’m still at the point where if I do have reboots, it’s software watchdog every few hours.
This is my working version. I will update it soon because I will change the tvoc sensor.
substitutions:
devicename: "airgradient"
upper_devicename: "Airgradient"
ipaddress: ""
voltage_divider: "4.27238" # ADC value * divider. The voltage divider between battery and adc input has 119k combined resistor.
battery_warning_voltage: "3.6"
battery_low_voltage: "3.2"
esphome:
name: ${devicename}
libraries:
# - uart=https://github.com/plerup/espsoftwareserial.git#6.17.1 # fix for uart issues on 6.12.7 which crashes esp8266
- uart=https://github.com/plerup/espsoftwareserial.git#8.0.1
platformio_options:
board_build.f_cpu: 160000000L
on_boot:
priority: -100
then:
#- script.execute: oled_on
- script.execute: oled_off
- switch.turn_on: bbme280
- switch.turn_on: bsgp30
- switch.turn_on: bsht30
- switch.turn_on: bsenseair
- lambda: id(aqi_text).publish_state("Calculating");
on_shutdown:
- script.execute: oled_off
#external_components:
# - source: github://eavyon/esphome@dev #fix for running newer arduino framework
# components: [ wifi ]
# refresh: 0s
# - source: github://epiclabs-uc/esphome-nowatchdog-component@master
# refresh: 60s
# components:
# - no_watchdog
#no_watchdog:
esp8266:
board: d1_mini
framework:
#version: 3.1.2
version: recommended
#platform_version: 4.1.0
debug:
update_interval: 10s
# Enable logging
logger:
#baud_rate: 0 #disable uart serial output
#tx_buffer_size: 256
level: DEBUG #default
#level: VERBOSE
logs:
sensor: INFO
sgp30: ERROR
senseair: INFO
sht3xd: INFO
pmsx003: INFO
text_sensor: NONE
homeassistant.sensor: NONE
# Enable Home Assistant API
api:
# encryption:
# key: ""
ota:
password: ""
packages:
wifi: !include .wifi.yaml
wifi:
manual_ip:
static_ip: ${ipaddress}
time:
- platform: homeassistant
id: homeassistant_time
#web_server:
# port: 80
# include_internal: true
i2c:
sda: D2
scl: D1
frequency: 100khz
scan: false
uart:
- rx_pin: D5
tx_pin: D6
baud_rate: 9600
id: pms5003_uart
- rx_pin: D4
tx_pin: D3
baud_rate: 9600
id: senseair_uart
script:
- id: oled_off
mode: restart
then:
- switch.turn_off: switch_oled
- id: oled_on
mode: restart
then:
- switch.turn_on: switch_oled
- delay: !lambda "return id(interval_display_on)*1000*60;"
- script.execute: oled_off
- id: oled_toggle
then:
if:
condition:
lambda: return id(oled).is_on();
then:
script.execute: oled_off
else:
script.execute: oled_on
- id: display_nextpage
then:
- display.page.show_next: oled
- component.update: oled
- id: bat_low_shutdown
then:
- button.press: button_shutdown
- id: senseair_background_calibration
mode: single
then:
- senseair.background_calibration: senseairs8co2
- id: senseair_background_calibration_result
mode: single
then:
- senseair.background_calibration_result: senseairs8co2
- id: senseair_abc_get_period
mode: single
then:
- senseair.abc_get_period: senseairs8co2
- id: senseair_abc_enable
mode: single
then:
- senseair.abc_enable: senseairs8co2
- id: senseair_abc_disable
mode: single
then:
- senseair.abc_disable: senseairs8co2
interval:
- interval: 1s
then:
- if:
condition:
lambda: return id(switch_oled).state;
then:
- component.update: oled
- if:
condition:
switch.is_on: bsgp30
then:
- component.update: ssgp30
- interval: 10sec
then:
- if:
condition:
switch.is_on: bbme280
then:
- component.update: sbme280
- if:
condition:
switch.is_on: bsht30
then:
- component.update: ssht3xd
- if:
condition:
switch.is_on: bsenseair
then:
- component.update: senseairs8co2
- interval: 1min
then:
- if:
condition:
lambda: 'return (id(batv).state < ${battery_low_voltage}) && (id(batv).state > 2.0);'
then:
- delay: 2min
- script.execute: bat_low_shutdown
globals:
- id: interval_display_on
type: float
restore_value: no
initial_value: '5'
number:
- platform: template
name: "${upper_devicename} Display Contrast"
id: contrast
optimistic: true
min_value: 0
max_value: 1
initial_value: 0.7
restore_value: true
step: 0.01
mode: slider
on_value:
- lambda: id(oled).set_contrast(x);
disabled_by_default: true
- platform: template
name: "${upper_devicename} Display On Time"
id: display_on_time
optimistic: true
min_value: 1
max_value: 60
initial_value: 5
restore_value: true
step: 1
mode: slider
on_value:
- globals.set:
id: interval_display_on
value: !lambda 'return (x);'
disabled_by_default: true
#binary_sensor:
# - platform: gpio
# name: "${upper_devicename} Button"
# pin:
# number: D8
# inverted: true
# mode:
# input: true
# pullup: true
# filters:
# - delayed_on: 10ms
# on_press:
# - script.execute: oled_toggle
# on_click:
# - min_length: 5000ms
# then:
# - button.press: button_restart
# internal: true
button:
- platform: restart
name: "${upper_devicename} Restart"
disabled_by_default: true
id: button_restart
- platform: safe_mode
name: "${upper_devicename} Restart (Safe Mode)"
disabled_by_default: true
- platform: shutdown
name: "${upper_devicename} Shutdown"
disabled_by_default: true
id: button_shutdown
- platform: template
name: "${upper_devicename} Display Next Page"
on_press:
- script.execute: display_nextpage
- platform: template
name: "${upper_devicename} Senseair Set Calibration"
on_press:
- script.execute: senseair_background_calibration
entity_category: diagnostic
disabled_by_default: true
- platform: template
name: "${upper_devicename} Senseair Get Calibration Result"
on_press:
- script.execute: senseair_background_calibration_result
entity_category: diagnostic
disabled_by_default: true
- platform: template
name: "${upper_devicename} Senseair Get Calibration Period"
on_press:
- script.execute: senseair_abc_get_period
entity_category: diagnostic
disabled_by_default: true
switch:
- platform: template
name: "${upper_devicename} Display On/Off"
id: switch_oled
#optimistic: true
lambda: |-
if (id(oled).is_on()) {
return true;
} else {
return false;
}
turn_on_action:
- lambda: id(oled).turn_on();
turn_off_action:
- lambda: id(oled).turn_off();
- platform: template
name: "${upper_devicename} Senseair Automatic Calibration"
optimistic: true
restore_state: true
turn_on_action:
- script.execute: senseair_abc_enable
turn_off_action:
- script.execute: senseair_abc_disable
entity_category: diagnostic
disabled_by_default: true
- platform: template
name: "${upper_devicename} BME280 Active"
id: bbme280
restore_state: True
optimistic: True
entity_category: config
disabled_by_default: True
- platform: template
name: "${upper_devicename} SHT30 Active"
id: bsht30
restore_state: True
optimistic: True
entity_category: config
disabled_by_default: True
- platform: template
name: "${upper_devicename} Senseair Active"
id: bsenseair
restore_state: True
optimistic: True
entity_category: config
disabled_by_default: True
- platform: template
name: "${upper_devicename} SGP30 Active"
id: bsgp30
restore_state: True
optimistic: True
entity_category: config
disabled_by_default: True
font:
- file: "gfonts://Roboto"
id: roboto
size: 10
display:
- platform: ssd1306_i2c
id: oled
model: "SH1106 128x64"
invert: false
contrast: 70%
#offset_y: 2
pages:
- id: page1
lambda: |-
static int count = 0;
if(count == 2){count = 0;}
//Battery text
//std::string bt = "99%";
//if(id(batv).state < 2.0){ bt = "NoBat"; }
//else if(id(batv).state < ${battery_warning_voltage}) { if(count == 1){ bt = "LOW"; } else { bt = printf("%.0f%%", id(battery_percentage).state); } }
//else { bt = printf("%.0f%%", id(battery_percentage).state); }
//it.strftime((it.get_width()-34)/2, 0, id(roboto), TextAlign::CENTER_HORIZONTAL, "%d-%m-%y %H:%M:%S", id(homeassistant_time).now());
it.strftime(0, 0, id(roboto), TextAlign::TOP_LEFT, "%H:%M:%S %d %b %y", id(homeassistant_time).now());
it.printf(104,0, id(roboto),TextAlign::TOP_RIGHT, "%.0f", id(wifirssi).state);
it.printf(128,0, id(roboto),TextAlign::TOP_RIGHT, "%.0f%%", id(battery_percentage).state);
it.line(0, 11, 128, 11); //Horizontal line
it.printf(0, 10, id(roboto), "T: %.1fC H: %.1f%%", id(temperature2).state, id(humidity2).state);
it.printf(0, 18, id(roboto), "Lucht: %.1f hPa", id(pressure).state);
it.line(0, 29, 96, 29); //Horizontal line
it.printf(0, 28, id(roboto), "CO2: %.0f ppm", id(co2).state);
it.printf(0, 36, id(roboto), "TVOC: %.0f ppb", id(tvoc).state);
it.printf(0, 44, id(roboto), "eCO2: %.0f ppm", id(eco2).state);
it.printf(0, 52, id(roboto), "PM25: %.0f ug/m3", id(pm25).state);
//it.rectangle(96, 0, 32, 21);
//if(id(batv).state < 2.0){ it.printf(98,0, id(roboto), "NoBat"); }
//else if (id(batv).state < ${battery_warning_voltage}) { if(count == 1){ it.print(98,0, id(roboto), "B LOW"); } else { it.printf(98,0, id(roboto), "B %.0f%%", id(battery_percentage).state); } }
//else { it.printf(98,0, id(roboto), "B %.0f%%", id(battery_percentage).state); }
//it.printf(98,9, id(roboto), "W %.0f", id(wifirssi).state);
//Column right
it.rectangle(96, 11, 32, 21);
it.printf(98, 11, id(roboto), "%.1fC", id(temperature).state);
it.printf(98, 19, id(roboto), "%.1f%%", id(humidity).state);
it.rectangle(96, 31, 32, 21);
it.printf(98, 31, id(roboto), " AQI");
it.printf(98, 39, id(roboto), " %.0f", id(pm_2_5_aqi).state);
it.rectangle(96, 51, 32, 12);
it.printf(98, 51, id(roboto), "%.1fC", id(temperature_outside).state);
count += 1;
- id: page2
lambda: |-
it.print(it.get_width()/2, 0, id(roboto), TextAlign::CENTER_HORIZONTAL, "Particle Density");
it.printf(it.get_width()/2, 15, id(roboto), TextAlign::CENTER_HORIZONTAL, "PM1.0: %.0f ug/m3", id(pm10).state);
it.printf(it.get_width()/2, 30, id(roboto), TextAlign::CENTER_HORIZONTAL, "PM2.5: %.0f ug/m3", id(pm25).state);
it.printf(it.get_width()/2, 45, id(roboto), TextAlign::CENTER_HORIZONTAL, "PM10: %.0f ug/m3", id(pm100).state);
update_interval: never
sensor:
- platform: homeassistant
#name: "${upper_devicename} Outside Temperature"
id: temperature_outside
entity_id: sensor.weerstation_temperatuur
- platform: bme280
id: sbme280
temperature:
name: "${upper_devicename} BME280 Temperature"
id: temperature2
oversampling: 1x
filters:
- offset: -0.8
pressure:
name: "${upper_devicename} BME280 Pressure"
id: pressure
oversampling: 1x
humidity:
name: "${upper_devicename} BME280 Humidity"
id: humidity2
oversampling: 1x
filters:
- offset: 6
address: 0x76
update_interval: never
- platform: sht3xd
id: ssht3xd
temperature:
id: temperature
name: "${upper_devicename} SHT30 Temperature"
humidity:
id: humidity
name: "${upper_devicename} SHT30 Humidity"
address: 0x44
update_interval: never
- platform: sgp30
id: ssgp30
eco2:
name: "${upper_devicename} eCO2"
id: eco2
filters:
- lambda: if(x > 10000) {return {};} else {return x;}
- filter_out: nan
- filter_out: 0
- throttle_average: 10s
- quantile:
send_every: 1
tvoc:
name: "${upper_devicename} TVOC"
id: tvoc
filters:
- lambda: if(x > 10000) {return {};} else {return x;}
- filter_out: 65535
- filter_out: nan
- filter_out: 0
- throttle_average: 10s
- quantile:
send_every: 1
baseline:
eco2_baseline: 0x9469
tvoc_baseline: 0x95EA
eco2_baseline:
name: "${upper_devicename} eCO2 Baseline"
id: eco2_baseline
state_class: "measurement"
disabled_by_default: true
tvoc_baseline:
name: "${upper_devicename} TVOC Baseline"
id: tvoc_baseline
state_class: "measurement"
disabled_by_default: true
store_baseline: yes
compensation:
temperature_source: temperature
humidity_source: humidity
address: 0x58
update_interval: never
- platform: pmsx003
type: PMSX003
uart_id: pms5003_uart
pm_1_0:
id: pm10
name: "${upper_devicename} PM <1.0µm Concentration"
pm_2_5:
id: pm25
name: "${upper_devicename} PM <2.5µm Concentration"
pm_10_0:
id: pm100
name: "${upper_devicename} PM <10.0µm Concentration"
update_interval: 3min # Sensor will go into sleep mode for extended operation lifetime
- platform: copy
source_id: pm25
id: pm_2_5
name: "${upper_devicename} PM <2.5µm Average 24h"
accuracy_decimals: 0
filters:
- sliding_window_moving_average:
window_size: 480 #every 3 minutes for 24 hours
send_every: 20 #hourly
send_first_at: 20
on_value:
lambda: |-
static int i = 0;
i++;
if(i>=18){ // Only publish after 18 hours
// https://en.wikipedia.org/wiki/Air_quality_index#Computing_the_AQI
if (id(pm_2_5).state < 12.0) {
// good
id(aqi_text).publish_state("Good");
id(pm_2_5_aqi).publish_state((50.0 - 0.0) / (12.0 - 0.0) * (id(pm_2_5).state - 0.0) + 0.0);
} else if (id(pm_2_5).state < 35.4) {
// moderate
id(aqi_text).publish_state("Moderate");
id(pm_2_5_aqi).publish_state((100.0 - 51.0) / (35.4 - 12.1) * (id(pm_2_5).state - 12.1) + 51.0);
} else if (id(pm_2_5).state < 55.4) {
// Unhealthy for Sensitive Groups
id(aqi_text).publish_state("Unhealthy for Sensitive Groups");
id(pm_2_5_aqi).publish_state((150.0 - 101.0) / (55.4 - 35.5) * (id(pm_2_5).state - 35.5) + 101.0);
} else if (id(pm_2_5).state < 150.4) {
// unhealthy
id(aqi_text).publish_state("Unhealthy");
id(pm_2_5_aqi).publish_state((200.0 - 151.0) / (150.4 - 55.5) * (id(pm_2_5).state - 55.5) + 151.0);
} else if (id(pm_2_5).state < 250.4) {
// very unhealthy
id(aqi_text).publish_state("Very Unhealthy");
id(pm_2_5_aqi).publish_state((300.0 - 201.0) / (250.4 - 150.5) * (id(pm_2_5).state - 150.5) + 201.0);
} else if (id(pm_2_5).state < 350.4) {
// hazardous
id(aqi_text).publish_state("Hazardous");
id(pm_2_5_aqi).publish_state((400.0 - 301.0) / (350.4 - 250.5) * (id(pm_2_5).state - 250.5) + 301.0);
} else if (id(pm_2_5).state < 500.4) {
// hazardous 2
id(aqi_text).publish_state("Hazardous");
id(pm_2_5_aqi).publish_state((500.0 - 401.0) / (500.4 - 350.5) * (id(pm_2_5).state - 350.5) + 401.0);
}
}
- platform: template
name: "${upper_devicename} PM <2.5 AQI"
unit_of_measurement: "aqi"
icon: "mdi:air-filter"
accuracy_decimals: 0
id: pm_2_5_aqi
- platform: senseair
id: senseairs8co2
uart_id: senseair_uart
co2:
name: "${upper_devicename} CO2"
id: co2
filters:
- filter_out: 0
- quantile:
send_every: 1
update_interval: never
- platform: adc
pin: A0
name: "${upper_devicename} Battery Voltage"
id: batv
filters:
- multiply: ${voltage_divider}
- sliding_window_moving_average:
window_size: 10
send_every: 10
- delta: 0.09 # Reduces publishing fluctuating values because of adc errors
- lambda: if(x < 2) {return {};} else {return x;}
on_value:
- sensor.template.publish:
id: battery_percentage
state: !lambda |-
int batper = (x - ${battery_low_voltage}) / (4.2 - ${battery_low_voltage}) * 100;
if(batper > 100) { batper = 100; }
if(batper < 0) { batper = 0; }
return batper;
disabled_by_default: true
update_interval: 1s
entity_category: diagnostic
- platform: template
name: "${upper_devicename} Battery Percentage"
id: battery_percentage
device_class: battery
accuracy_decimals: 0
unit_of_measurement: "%"
entity_category: diagnostic
- platform: wifi_signal
name: "${upper_devicename} Wifi Strength"
id: wifirssi
disabled_by_default: true
update_interval: 10s
- platform: uptime
name: "${upper_devicename} Uptime Sensor"
id: uptime_sensor
update_interval: 60s
- platform: debug
free:
name: "${upper_devicename} Heap Free"
#disabled_by_default: true
fragmentation:
name: "${upper_devicename} Heap Fragmentation"
#disabled_by_default: true
block:
name: "${upper_devicename} Heap Max Block"
#disabled_by_default: true
loop_time:
name: "${upper_devicename} Loop Time"
#disabled_by_default: true
text_sensor:
- platform: version
name: "${upper_devicename} ESPHome version"
- platform: debug
device:
name: "${upper_devicename} Device Info"
#disabled_by_default: true
reset_reason:
name: "${upper_devicename} Reset Reason"
- platform: template
name: ${upper_devicename} AQI
id: aqi_text