gdoor-org / gdoor

Wifi adapter and bus protocol documentation for the Gira TKS Door System
https://gdoor-org.github.io/
GNU General Public License v3.0
14 stars 4 forks source link

ESPHome external component #25

Open nholloh opened 2 weeks ago

nholloh commented 2 weeks ago

Currently, home assistant integration is done through MQTT with auto discovery. However, in my opinion, the integration in home assistant still offers potential for optimisation:

  1. Identifying bus messages to trigger various functions (door open, light, ...) is rather tedious, having to search through logbook, or by connecting the device via serial to a PC.
  2. Triggering the functions currently has to be done by performing a service call to either echo something through the serial connection or perform a service call to send an MQTT message to a predefined topic, which carries just the bus message that was previously recorded.
  3. The esp32 chip cannot be used for anything else, even though it might have resources to spare. That is, some people may find it useful to have it set up as bluetooth proxy for BLE devices, to extend home assistant's bluetooth coverage.

I believe there are multiple ways to address these issues.

I am currently exploring one of them, creating an external_component for esphome based on the gdoor code. In my opinion, esphome offers several advantages:

  1. it provides an easy way to configure the rx related settings in the device's yml
  2. it can provide an out-of-the-box feature to switch into a learning mode, where bus messages for certain actions (door open, light, ...) can be recorded
  3. we can distinct buttons and states for these actions
  4. the esp32 chip may additionally be used for something other than just being the gdoor adapter, by simply including that functionality in the device's yml.

For openHAB users I believe there is also a binding to include esphome devices, if desired.

Of course, most of this is also possible with the current firmware and MQTT based approach. However, I personally find the MQTT approach to be more verbose and it may require more knowledge on the user-side to get things up and running. Using esphome, we could reduce it to a couple of lines of yml code, which will be used by esphome to automatically compile the most recent firmware with default settings (of course you can override them) and flash that to the device.

I'd be keen to know any other Home Assistant user's take on this.

DaSchaef commented 2 weeks ago

I think OpenHAB will work with either solution, as a OpenHAB user, I'm used to set it up more complicated. My understanding of esphome is not good enough to judge, but GDoor currently needs multiple timers and interrupt, don't know how good these low level needs will integrate into a framework.

nholloh commented 2 weeks ago

I am just getting into this, however esphome can use esp-idf or the arduino framework to compile, and compilation happens using platformio under the hood.

In the esphome component, you can implement a setup and a loop function, from which you have quite granular control over whatever it is you need to do. So from an API level perspective, I do not see an issue, actually the API looks quite similar to the main.cpp from gdoor. I took an attempt at porting:

void GDoorSensor::setup() {
    ESP_LOGI(TAG, "Setting up GDoorSensor");

    // TODO: Make sensitivity configurable.
    GDOOR::setRxThreshold(PIN_RX_THRESH, RX_SENS_MED_NUM);

    // TODO: Make RX PIN configurable.
    GDOOR::setup(PIN_TX, PIN_TX_EN, RX_PIN_22_NUM);

    // Publish initial idle state.
    publish_state(gdoor_data_idle.action);
}

void GDoorSensor::dump_config() { 
    ESP_LOGCONFIG(TAG, "GDoor text sensor");
}

void GDoorSensor::loop() {
    GDOOR::loop();

    GDOOR_DATA* rx_data = GDOOR::read();
    if(rx_data != NULL) {
        ESP_LOGI(TAG, "Received data from bus");
        GDOOR_DATA_PROTOCOL busmessage = GDOOR_DATA_PROTOCOL(rx_data);

        ESP_LOGD(TAG, "Data: ", busmessage);

        // Set sensor state.
        publish_state(busmessage.action);

        ESP_LOGD(TAG, "Sensor state set. Back to idle.");

        // TODO: Set sensor state back to idle.
        publish_state(gdoor_data_idle.action);
    }
}

From what I understand, timers and interrupts are part of the Arduino framework. Since you can configure esphome to build off the Arduino framework, this should(TM) theoretically work pretty much out of the box.

jschroeter commented 2 weeks ago

As a HA user, I do like the idea with ESPHome. I haven't done much with it yet but I do like the general concept and I expect it to work nicely. Further, I have the impression that the WifiManager is a bit buggy (e.g. it's leaking the Wifi password in the UI, I tried fixing it but couldn't get it to work) and not so well maintained. Mostly from a gut-feeling a think ESPHome is the more future-proof solution.

nholloh commented 2 weeks ago

ESPHome is a first party add-on developed by the company that also develops home assistant and HAOS (nabucasa). That is, I expect this to be most future-proof.

image

nholloh commented 2 weeks ago

So quick status report: I do have the first version of the firmware compiling, but I did need to make some changes to the gdoor code. The most significant being reverting from the v3 arduino framework apis (timer, ledc) to the v2 ones, since, for some reason, platformio has only published v2 versions.

I'll do a test run on my esp tomorrow evening and see if it succeeds in reading messages from the bus.

INFO ESPHome 2024.5.5
INFO Reading configuration /config/esphome/gdoor-test.yaml...
INFO Updating https://github.com/nholloh/gdoor-esphome.git@main
INFO Generating C++ source...
INFO Compiling app...
Processing gdoor-test (board: wemos_d1_mini32; framework: arduino; platform: platformio/espressif32@5.4.0)
--------------------------------------------------------------------------------
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
 - toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5
Dependency Graph
|-- WiFi @ 2.0.0
|-- ESPmDNS @ 2.0.0
|-- Update @ 2.0.0
|-- noise-c @ 0.1.4
RAM:   [=         ]  12.8% (used 41792 bytes from 327680 bytes)
Flash: [=====     ]  48.1% (used 882081 bytes from 1835008 bytes)
========================= [SUCCESS] Took 15.15 seconds =========================
INFO Successfully compiled program.
sim-san commented 2 weeks ago

Reference to https://github.com/gdoor-org/gdoor/issues/27#issuecomment-2157721911

In the last Release of ESPHome, they also support Events on the ESPHome: ESPHome HA Events

nholloh commented 2 weeks ago

image

The integration with esphome itself for just reporting the current bus status seems to be working, however during reverting to the v2 arduino APIs I probably killed the timers involved in decoding the bus signal. I'm rather busy this week so I don't expect to make a whole lot of progress until the weekend. In the meantime, if anybody wants to take a look, feel free to check out my code here: https://github.com/nholloh/gdoor-esphome. If you want to make some changes for testing, let me know and I can set permissions accordingly.

Here's the yml I use for testing:

esphome:
  name: gdoor-test
  friendly_name: GDoor_Test

esp32:
  board: wemos_d1_mini32
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

external_components:
  - source: github://nholloh/gdoor-esphome@main
    refresh: 0s
    components: [ gdoor ]

text_sensor:
  - platform: gdoor
    name: 'BUS Status'
    id: gdoor_bus_status
mrtnkhl commented 2 weeks ago

Side note: ESPHome would also potentially allow for audio support using the ESP32's internal ADC, see https://esphome.io/components/microphone/i2s_audio.html and https://esphome.io/components/speaker/i2s_audio for reference (I2S and internal ADC described under the same links).

nholloh commented 2 weeks ago

Side note: ESPHome would also potentially allow for audio support using the ESP32's internal ADC, see https://esphome.io/components/microphone/i2s_audio.html and https://esphome.io/components/speaker/i2s_audio for reference (I2S and internal ADC described under the same links).

Might still require changes to the pcb, but it may make development of the component a lot easier.

There are three other things, which also come to mind with an i2s audio based speaker and mic configuration:

  1. you may play music to the person outside waiting, or use text to speech to give them a proper announcement (waiting, the door cannot be answered at the moment, …)
  2. You may add a voice mailbox sort of feature so that people can leave behind a message if you are unable to open the door.
  3. Speaker and mic are also the base for any assist pipeline in home assistant. Who wouldn‘t want their doorbell to be a voiced, interactive personal assistant? 😆
mrtnkhl commented 2 weeks ago

Best thing is you don't even need any I2S hardware, other then some bus coupling per @DaSchaef AFAIK. See also: https://github.com/gdoor-org/gdoor/issues/20 for sample circuits.

From the ESPHome documentation, applies to both ADC and DAC:

adc_type (Required, enum): internal: Use the internal ADC of the ESP32. Only supported on ESP32, no variant support.

Given that the door station audio is not hifi, we might get away with using the internal ESP32 ADC and DAC!

mrtnkhl commented 2 weeks ago

@nholloh

  1. Speaker and mic are also the base for any assist pipeline in home assistant. Who wouldn‘t want their doorbell to be a voiced, interactive personal assistant? 😆

gdoor, HA assist pipeline and ChatGPT powered GIRA door station upon someone unauthorized trying to get into the building: "I'm sorry, Dave. I'm afraid I can't do that."

I cannot wait, this will be grand!

nholloh commented 1 week ago

So the draft integration for ESPHome is working. I exposed the current bus state as text_sensor and was able to see events in the logbook as I pressed buttons on my doorbell.

The next step is to split the bus communication from the text sensor, separate them into individual components and add buttons for all the actions. Unfortunately all this work is far from simple as there is zero documentation on ESPHome custom components, so you have to dig through tons of python and cpp code in search for relevant example code that you can use as template. I'll try to get it done over the weekend.

image

jschroeter commented 1 week ago

Wow, that looks very promising, can't wait! Thanks for your efforts!

DaSchaef commented 1 week ago

Very cool.

When it is working I suggest that we:

github-k8n commented 6 days ago

Would be great to have this as an esphome component. @nholloh let me know if you have questions reg. this, i also had to teach myself esphome external components from scratch, maybe you can have a look at my component for vallox ventilation, it uses multiple different entities (buttons, numbers, sensors, selectors) so maybe it can help you a bit in understanding things... https://github.com/kotope/valloxesp/tree/esphome

nholloh commented 5 days ago

Hey @github-k8n, thanks for bringing this up. The documentation of esphome external components, or rather the lack thereof, really is frustrating. I'll take a look at your repo over the weekend.

I proposed to meet on discord to discuss some of the open topics here, since many of them seem to be connected to some extent. I believe your input could be super valuable, considering you probably have the most knowledge around esphome of all of us. Let me know if thats something you'd be interested in, then I'll send you the invite link.

github-k8n commented 5 days ago

@nholloh , sure, send me the link.

nholloh commented 5 days ago

@github-k8n https://discord.gg/TVyeQAQt