BLE_Client Notify Help for Custom Generlink Integration

Hey All!

Long time lurker here, absorbing all I can here and everywhere Google takes me. I’ve finally ran into a problem that I can’t seem to find an answer to so I created an account for help. I’m trying to create a custom BLE relay for my Generlink Automatic Power Transfer Switch to get status updates to HomeAssistant. There is a simple OEM app and I was able to use nRF Connect to figure out the command to request updates and see how the updates are formatted. All in all, it’s a very simple setup that uses the command ~STA} for data requests and returns whether it is on utility power, generator power, load limits, and fault.

Utility power available returns ~UON} or ~UOFF}
On generator power will return ~GON} or ~GOFF}
Device is at the Load Limits returns ~LOCK}
Device fault returns ~FAULT}

So far I have been able to get my ESP32 to connect to the Generlink, send the command, and receive partial data back. Right now I have two problems:

  1. The logger seems to be missing the fist line of data on every update.
  2. I am trying to take the data that is received on notification from the ~STA} command and parse it to make 4 binary sensors to indicate the current status. I am not able to read in this data to my text_sensor even though I know the characteristic_uuid is correct via nRF Connect.

For issue 1, the logger shows the following:

[21:43:27.134]~GOFF}
[21:43:27.134]~LOCK}
[21:43:27.134]’

But, there should be a line for ~UON} before the ~GOFF} line. This is consistent on each scan, but when I use nRF Connect that line is there.

For issue 2, I am at a loss. From all my searching, since this data is returned in hex, I need to use text_sensor and convert it to a string via lambda so I can parse it for the binary sensors. But, it seems like I am not properly getting the notifications that are in the logs sent to my generlink_notify sensor. Within the logger, I see this line directly after the “Disconnected from Generlink ATS” line:

[21:42:57.130][D][text_sensor:087]: ‘generlink_notify’: Sending state ‘’

I am not a coder by any stretch and the little bit I know about how BLE works has been from this project so please forgive any issues with the below code or if this is a very simple problem that easily fixed.

Thanks in advance!

Edit: Uploaded a screenshot from nRF Connect

esphome:
  name: esp32-generlink
  friendly_name: Generlink BLE Bridge

esp32:
  board: esp32dev
  framework:
    type: arduino

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: true
  # Optional manual IP
  manual_ip:
    static_ip: X.X.X.X
    gateway: X.X.X.X
    subnet: X.X.X.X

logger:
  level: DEBUG

api:
  encryption:
    key: !api_key

ota:
  - platform: esphome
    
# Initialize BLE tracker
esp32_ble_tracker:
  id: ble_tracker
  scan_parameters: 
    active: True
    interval: 320ms
    window: 30ms      

# BLE client for Generlink ATS
ble_client:
  - mac_address: F0:5D:77:C7:44:99
    id: generlink
    auto_connect: False
    on_connect: 
      then:
        - lambda: |-
            ESP_LOGI("generlink", "Connected to Generlink ATS.");
    on_disconnect: 
      then:
        - lambda: |-
              ESP_LOGW("generlink", "Disconnected from Generlink ATS.");

# Poll Generlink every 30 seconds
interval:
  - interval: 30s
    then: 
      - ble_client.connect: generlink
      - delay: 5s
      - ble_client.ble_write:
          id: generlink
          service_uuid: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
          characteristic_uuid: 6e400002-b5a3-f393-e0a9-e50e24dcca9e
          # Write ~STA} to generlink for current status
          value: [0x7E, 0x53, 0x54, 0x41, 0x7D]
      - ble_client.disconnect: generlink
  
# Read from Generlink
text_sensor:
  - platform: ble_client
    id: generlink_notify
    service_uuid: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
    characteristic_uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e
    notify: True
    on_notify: 
      then:
        - lambda: |-
            std::string raw(x.begin(), x.end());
            raw.erase(std::remove(raw.begin(), raw.end(), '\0'), raw.end());
            ESP_LOGI("generlink_notify", "Received: %s", raw.c_str());
            id(generlink_notify).publish_state(raw);


For 1), try to output the raw hex content of the message. You might get multiple ones in one go.

See format_hexto get a printable output

https://api-docs.esphome.io/namespaceesphome#af98fcb3567b9f10990a44513bf32c80f

That’s actually useful for 2) as well