TLDR
I ported ESPHome to run on top of ZephyrRTOS. Using this I was able to build against the Adafruit Feather 52840 Express, and create an OpenThread mesh network (not WiFi) which is used to communicate with my Home assistant instance.
Slightly Longer
I have long enjoyed how easy it was to make smart home devices using ESPHome, but was always interested in moving away from Wifi (range issues, congested IPs, power consumption, etc). Because of the fantastic job @OttoWinter did in creating abstraction layers in ESPHome (as well as an overall well structured project) I was able to create appropriate shims and project structure builders to make the code produced by ESPHome run on top of ZephyrRTOS, an embedded operating system with its own highly optimized runtime, and low power consumption.
One of the major selling points of Zephyr is that it had native support for using Openthread mesh networking as an L2 transport layer, meaning code sitting “above” could work with a normal network socket system. This means it was possible to make the ESPHome api component “just work” (after many hours of head banging) to communicate with HomeAssistant. The API component can talk using standard sockets which get translated to the L2 thread network, sent across the mesh to a border router (part of the openthread project) which then is visible to the network containing HomeAssistant. The border router also advertises registered services for each microcontroller such that they are discoverable on link local.
Even though I did all this to enable thread networking, it is by no means required. By supporting zephyr as a target platform there are hundreds of boards that can be supported by ESPHome (though of course I have only built and tested against one at the moment).
What Does This look Like
esphome:
name: zephyrboard
logger:
openthread:
network_name: NETWORK_NAME
panID: 0x111
xpanID: 1111111111111111
network_channel: 11
network_key: <NETWORK_KEY>
api:
password: "example_password"
reboot_timeout: 0s
zephyr:
zephyr_base: "<BASE_ZEPHYR_INSTALLATION>"
board: adafruit_feather_nrf52840
flash_args: "--runner blackmagicprobe --gdb-serial=/dev/ttyACM0 --elf-file=BUILD_DIR/zephyr/zephyr.signed.hex"
zephyr_ota:
binary_sensor:
- platform: gpio
pin:
number: D9
mode:
input: true
pullup: true
inverted: true
name: "zephyr sensor"
on_press:
then:
- switch.turn_on: switch_light
on_release:
then:
- switch.turn_off: switch_light
switch:
- platform: gpio
pin: D4
id: switch_light
internal: true
restore_mode: ALWAYS_OFF
How To Use
I’m writing this whole post to see how much interest there is in what I have been working on. I don’t want to spend a long time writing a guide no one will ever look at. Not that there is a lot to it, but I would rather put my time into the code I am going to use if no one else is interested. If there is interest I can do a write up and put it in follow up comments on setting up zephyr, the border router, etc.
The code can be found here.
Who Am I?
Just a person interested in using this for my own projects, I am not associated with ESPHome or Home Assistant, I just enjoy their wonderful work.
Will This Be Upstreamed?
I hope so eventually. I hope to not be sole maintainer for this forever, and I don’t have the energy to keep up tracking upstream development all the time. That said, until more features of ESPHome are supported (devices, interfaces, etc) I dont expect that they will want to pull in partially working project, but I might be wrong.
What Works
Right now I have focused on the basics.
- Compiling
- Thread networking
- GPIO
- Logging
- Flashing (locally and OTA)
- Most standard features not dependent on hardware, such as automations
- Communication with home assistant
What Doesn’t Work
I am not sure enough to make a list, basically the above list is what I have tried so far. I suspect SPI and I2C probably work in software mode (bit banging), and if they don’t it should be pretty quick to make them. I suspect anything specific to ESP projects (like camera) will take much more time, or not be possible. There is WiFi and Ethernet support support in Zephyr so in principal it should be possible to get the ESPHome components working, but that is not a near term goal for me. Library support is not working, as this is based directly from Zephyr and not platform IO. I can go into reasons if anyone asks.
What Are My Next Plans
I started all this to have some devices around my house, so what I get working next will largely be driven by those projects. I suspect A2D will be high priority so that I can monitor battery levels. Past that I plan on tacking SPI and I2C, as I will need them before long.
What are some drawbacks
The Rom sizes are not as optimized as I would like. Because OTA updates require two slots in memory (one running, and one to update to) sometimes there is a little juggling of space required. This is not so much of a problem with simple ESPHome scripts, but it is difficult to enable some of the features Zephyr provides. Currently Network logging is not working, but should not be hard to get it to.
Long Term Hopes
I would really like to take advantage of Zephyrs real time scheduler and callbacks to eliminate the need to run loop
. Events could simply be acted upon as they happen. This could be a big win in terms of power efficiency and responsiveness. Currently all of this happens exactly like it does on an ESP board which helps maintain compatibility, and makes it easier to focus on making other things work.
Is This Code Stable
No it is not. I tried to keep things designed in such a way that it could grow well, but I would classify this code possibly just past “make it work” stage. I suspect there will be refactoring in how all the Zephyr components interact with the configuration and build systems before long. That said it is usable (within what works) right now.
How Can You Help
Well first if you want to play with it, that would be great, bug reports, patches, etc are welcome (just note I have a day job so I might not always be supper prompt).
If you are interested you can donate microcontrollers (or cash to buy them), or run them on your own microcontrollers. I would be happy to support many boards, but I think my partner would give me “a look” If I spent money on many many boards, and I might not be around to keep working on it.
Thumbs up and or likes, knowing people find the work interesting helps with motivation.
Thank You
If you have made it this far in reading THANK YOU. Thank you for your attention and your time reading all of this. I have worked on this for a while and other people showing interest is very heart warming.