Flashing the SMS4IOT Firmware To flash firmware onto new device: . ~/esp32/esp-idf/export.sh (Assuming thats where you put your ESP32 idf) esptool.py --chip esp32c5 -p /dev/ttyACM0 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 80m --flash_size 8MB 0x2000 bootloader.bin 0x20000 dcisms4iot.bin 0x8000 partition-table.bin 0xf000 ota_data_initial.bin You may have to change the UART port (eg -p /dev/ttyACM0) above. I used ESP32-C5-DevKitC-1 dev board* (found on Amazon) but raw ESP32-C5-WROOM-1-N8R4/8 Espressif modules work too. Once flashed connect to the device console via "screen /dev/ttyACM0" or something similar. Do a "stat" to see whats going on. You shall see log messages** every second or so showing the device trying to: 1. connect to some wifi hotspot 2. autoconfiguring itself with a. demo device id (e.g. "10001003") b. a key to access the sms4iot gateway, and c. a on device only private key for secure end-to-end communication If the device is successful in finding a hotspot, you should start to see the correct date and time (UTC) in some of the messages. 3. Enter "qr" on the console and snap a picture of the QR code, then enter "qr" again to re-enable log messages. Make sure your console screen is large enough to accomodate the full QR code. This will later be used to add the device to Home Assistant. If the device was not able to find a suitable hotspot, the device will continue rescanning for hotspots and trying. I found this works in most urban environments (cafes, fast food, hotels, airports, resturants, stores, public buildings, parks, etc...) Home Assistant Integration (HA) - Linux 1. Copy directory sms4iot to your HA config/custom_components/ directory and restart HA. 2. Start the sms4iot daemon "s4igw" running, e.g., "cd config/custom_components/sms4iot" then "./s4igw". This program will periodically exchange payloads encrypted by/for your devices with global sms4iot gateways. If need be, "cc s4igw.c -o s4igw" to rebuild the daemon for your Linux version. 3. Go to HA Settings and Devices and add the SMS4IoT integration. This will prompt you to scan the QR generated above. 4. Your new device, identified by device id number (e.g. "10001003"), should show up. After a minute or two, data from you device should show up in HA. 5. Thats it. You device can be in a cafe on the other side of the world or in your house. Notes: *Configured GPIOs (s/w will scan I2C for AHT2X sensor and SSD1306 display) SDA 10 SCL 9 RELAY 23 LED 27 // WS2818 RGB BOOT 28 ADC 3 USB- 13 USB+ 14 ** idf:v6.0-dev-760-g4e8ad76602-dirty 8MB ext flash, 8MB ext psram RTC clk:Internal 136kHz Running part: addr=0x00020000 type=0 subtype=16 heap:8571568/8571568(min) mymalloc:0/0(max) my_adc_doread: gpio3=adc2,unit1 cal Uptime:0hr 6min rbootcnt:0 relay:0 inPin:0 ADC1:1002mV ADC2:0mV ID: mac:10:BD:A3:FE:FF:D7 Last Reset by USB peripheral. wifi: 00:00:00:00:00:00 () ch:0 ip:0.0.0.0 dns:0.0.0.0 name ustack pri num cpu main 7568 1 2 0 IDLE 5264 0 3 0 consoletask 9248 2 5 0 Tmr Svc 7184 1 4 0 esp_timer 15312 22 1 0 myi2cinit: initialized read_aht2x: No AHT2X found mymaintaskproc: Initialized interface... sms4iotproc: flg=1 Thu Jan 1 00:06:41 1970 sms4iot_paramload: open namespace "sms4iot" failed sms4iot_initparams: A Brand new device. Setting up autoprovisioning. sms4iot_paramflash: namespace "sms4iot".. creating.. sms4iot_paramflash: writing 422 bytes sms4iotproc: done - init,reset counters ssd1306_init: No SSD1306 display found mymaintaskproc: Start scanning.... Start passive wifi scan. 150ms/chan ip_event_handler: WIFI_EVENT(43) Wi-Fi home channel change doesn't occur when scanning ip_event_handler: Station start - no connect ip_event_handler: WIFI_EVENT(1) Finished scanning AP mymaintaskproc: Max AP number ap_info can hold = 49 ip_event_handler: WIFI_EVENT(3) Station stop mymaintaskproc: Total APs scanned = 33, actual AP number ap_info holds = 33 *xxpass2 (-37) 11 Verizon_KR7HTS (-66) 11 Verizon_KR7HTS (-76) 36 Eero (-76) 6 DIRECT-BE-HP OfficeJet 6950 (-78) 6 forever24 (-78) 6 Sonic-2b5c (-79) 11 homesweethome (-80) 1 APIS5 (-82) 6 NETGEAR66 (-83) 11 Eero (-83) 153 homesweethome (-85) 44 forever24 (-85) 1 *xfinitywifi (-85) 44 foever24guest (-86) 1 forever24 (-89) 1 East44 (-89) 6 forever24 (-89) 6 foever24guest (-89) 6 Hill10 (-89) 6 HELM XF!nity (-90) 11 foever24guest (-91) 1 Sonic-c588 (-91) 1 Terrified Petrified Stupefied (-91) 9 East44 (-92) 44 Xfinity Mobile (-92) 44 Why-Fry? (-93) 1 HairyGreens (-93) 1 APIS5 (-94) 44 curssid:xxpass2 ch:11 top3:xxpass2 Verizon_KR7HTS Verizon_KR7HTS mymaintaskproc: wifi start |xxpass2||ch:0 bssid not set mymaintaskproc: before esp_wifi_start ip_event_handler: try to connect to ap mymaintaskproc: waiting for connection... mymaintaskproc: waiting for connection... ip_event_handler: WIFI_EVENT(43) Wi-Fi home channel change doesn't occur when scanning ip_event_handler: connected to ap mymaintaskproc: waiting for connection... ip_event_handler: IP:192.168.15.118 ip_event_handler: ip:192.168.15.118 dns:192.168.15.254 mymac:10:bd:a3:d7:ed:88 mymaintaskproc: Connected to ap SSID:xxpass2 fwupdate: Running partition type 0 subtype 16 (offset 0x00020000) fwupdate: curimg=1 size=2097152 bytes fwupdate: Looking for updated fw from http://www.sms4iot.com/files/devkesp32c5.binx fwupdate: Connected! fwupdate: html error sms4iotproc: flg=1 Thu Jan 1 00:06:54 1970 sms4iot_paramload: Read params 422 bytes sms4iotproc: done - init,reset counters sms4iotproc: flg=0 Thu Jan 1 00:06:54 1970 getipinfo: 10:bd:a3:d7:ed:88 getipinfo: ip:192.168.15.118 dns:192.168.15.254 sms4iotproc: openned socket sms4iotproc: done - no rx ret=0 Thu Jan 1 00:06:54 1970 sms4iotproc: flg=0 Thu Jan 1 00:06:55 1970 sms4iotproc: done - no rx ret=0 Thu Jan 1 00:06:55 1970 sms4iotproc: flg=0 Thu Jan 1 00:06:56 1970 sms4iotproc: done - no rx ret=0 Thu Jan 1 00:06:56 1970 sms4iotproc: flg=0 Thu Jan 1 00:06:57 1970 sms4iotproc: done - no rx ret=0 Thu Jan 1 00:06:57 1970 sms4iotproc: flg=0 Thu Jan 1 00:06:58 1970 sms4iotproc: done - no rx ret=0 Thu Jan 1 00:06:58 1970 sms4iotproc: flg=0 Thu Jan 1 00:06:59 1970 sms4iotproc: done - no rx ret=0 Thu Jan 1 00:06:59 1970 sms4iotproc: flg=0 Thu Jan 1 00:07:00 1970 sms4iotproc: AUTOPROVISION-> sms4iotproc: Generating new ed25519 keypair sms4iotproc: Send-autoprovision(pre-enc) 60 bytes sms4iotproc: Send-autoprovision 68 bytes sms4iotproc: Sent 156 bytes seq=0 ack=0 192.168.15.118:0 -> 192.168.15.254:53 sms4iotproc: missed:1 badhash:0 noans:0 txrxtries:1 2waycnt:0 sms4iotproc: done - no rx ret=0 Thu Jan 1 00:07:00 1970 sms4iotproc: flg=0 Thu Jan 1 00:07:01 1970 sms4iotproc: Recv 317 bytes = 192.168.15.254:53 -> 192.168.15.118:0 sms4iotproc: Time corrected to 6A595F79 from 000001A5 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:21 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:22 2026 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:22 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:23 2026 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:23 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:24 2026 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:24 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:25 2026 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:25 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:26 2026 sms4iotproc: AUTOPROVISION-> sms4iotproc: Send-autoprovision(pre-enc) 60 bytes sms4iotproc: Send-autoprovision 68 bytes sms4iotproc: Sent 156 bytes seq=0 ack=0 192.168.15.118:0 -> 192.168.15.254:53 sms4iotproc: missed:1 badhash:0 noans:0 txrxtries:2 2waycnt:0 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:26 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:27 2026 sms4iotproc: Recv 317 bytes = 192.168.15.254:53 -> 192.168.15.118:0 sms4iotproc: AUTOPROVISIONING sms4iotproc: 1000100b 5.x031.nl sms4iot_paramflash: writing 422 bytes sms4iotproc: flg=0 Thu Jul 16 22:47:28 2026 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:28 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:29 2026 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:29 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:30 2026 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:30 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:31 2026 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:31 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:32 2026 sms4iotproc: Sent 86 bytes seq=0 ack=0 192.168.15.118:0 -> 192.168.15.254:53 sms4iotproc: missed:1 badhash:0 noans:0 txrxtries:1 2waycnt:0 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:32 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:33 2026 sms4iotproc: Recv 125 bytes = 192.168.15.254:53 -> 192.168.15.118:0 sms4iotproc: Set start time sms4iotproc: RX Empty request sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:33 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:34 2026 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:34 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:35 2026 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:35 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:36 2026 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:36 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:37 2026 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:37 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:38 2026 sms4iotproc: Sent 86 bytes seq=0 ack=0 192.168.15.118:0 -> 192.168.15.254:53 sms4iotproc: missed:1 badhash:0 noans:0 txrxtries:2 2waycnt:0 sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:38 2026 sms4iotproc: flg=0 Thu Jul 16 22:47:39 2026 sms4iotproc: Recv 125 bytes = 192.168.15.254:53 -> 192.168.15.118:0 sms4iotproc: RX Empty request sms4iotproc: done - no rx ret=0 Thu Jul 16 22:47:39 2026