AM43 blinds control through MQTT

I have installed the sample yaml via esphome and changed to my mac address etc.
When I install the code i get this error

Compiling /data/lounge-blinds/.pioenvs/lounge-blinds/src/esphome/components/am43/am43.cpp.o
Compiling /data/lounge-blinds/.pioenvs/lounge-blinds/src/esphome/components/am43/am43_base.cpp.o
Compiling /data/lounge-blinds/.pioenvs/lounge-blinds/src/esphome/components/am43/cover/am43_cover.cpp.o
In file included from src/esphome/components/am43/am43.cpp:1:0:
src/esphome/components/am43/am43.h:6:46: fatal error: esphome/components/sensor/sensor.h: No such file or directory
compilation terminated.
*** [/data/lounge-blinds/.pioenvs/lounge-blinds/src/esphome/components/am43/am43.cpp.o] Error 1
esphome:
  name: lounge-blinds
  platform: ESP32
  board: nodemcu-32s 
  
# Enable logging
logger:

# Enable Home Assistant API
api:

ota:
  password: "fabe33f968e45454259943641816"

wifi:
  ssid: "xxxxxxxxx"
  password: "xxxxxxxxx"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Lounge-Blinds Fallback Hotspot"
    password: "YZwaINo1VDpB"

captive_portal:

external_components:
  - source: github://buxtronix/esphome-am43

esp32_ble_tracker:

ble_client:
  - mac_address: 02:4B:xx:xx:3C:E5
    id: am43_lounge
cover:
  - platform: am43
    name: "lounge blinds"
    ble_client_id: am43_lounge

What am I doing wrong?

Hi All,

If anyone is interested I have got this working with ESP32-Wroom-32. Initially had some issues with the BLE connection but the NimBLE people sorted it almost immediately.

https://www.amazon.co.uk/ESP-32S-Development-2-4GHz-Bluetooth-Antenna/dp/B071JR9WS9

Was wondering though which custom component you guys are using for this to control the curtain manually?

can someone explain this to me please?

#define SHADE_1 “02:e6:93:bf:85:ce”
#define SHADE_2 “11:22:33:44:55:66”
#define SHADE_3 “11:22:33:44:55:66”

#define DEVICE_ALLOWLIST “”
//#define DEVICE_ALLOWLIST SHADE_1
//#define DEVICE_ALLOWLIST SHADE_1 “,” SHADE_2 “,” SHADE_3

I have been with this for two days and I am not able to make it work, it only “publishes” “lwt” and “enabled” no more data

1 Like

You can use this without external_components.
AM43 is now supported in ESPHome by default.

Thanks Chris for a greate template, i’ve continued your job, and here what i got:

  1. fixed ‘Unknown’ battery’s state issue
  2. two blinds are controled, and easelly extend their count if necessary.
  3. blinds are merged to single (don’t necessary to create group in HA), i guess that here is no problem to split them if you’d like to conrol blinds separatly
  4. adding position control
esphome:
  name: am43
  platform: ESP32
  board: esp-wrover-kit
  on_boot:
    - script.execute: main
    - script.wait: main

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

logger:
  level: INFO

api:

ota:
  password: "f3c4853547d70265da463e82f7d66947"
   
esp32_ble_tracker:

globals:
  - id: position
    type: int
    restore_value: no
  
ble_client:
  - mac_address: 02:7B:F1:3A:C6:63
    id: bedroom_left_blind
    on_connect:
      - binary_sensor.template.publish:
          id: bedroom_left_blind_connected
          state: ON
    on_disconnect:
      - binary_sensor.template.publish:
          id: bedroom_left_blind_connected
          state: OFF
          
  - mac_address: 02:BD:67:49:4B:0D
    id: bedroom_right_blind
    on_connect:
      - binary_sensor.template.publish:
          id: bedroom_right_blind_connected
          state: ON
    on_disconnect:
      - binary_sensor.template.publish:
          id: bedroom_right_blind_connected
          state: OFF

cover:
  - platform: am43
    id: bedroom_left_blind_cover_internal
    ble_client_id: bedroom_left_blind
    pin: 1234
    internal: true
    
  - platform: am43
    id: bedroom_right_blind_cover_internal
    ble_client_id: bedroom_right_blind
    pin: 1234
    internal: true
    
  - platform: template
    name: "Bedroom Blinds"
    id: bedroom_blinds_cover
    has_position: true
    lambda: |-
      return (id(bedroom_left_blind_cover_internal).position + id(bedroom_right_blind_cover_internal).position) / 2;
    open_action:
      then:
        - script.execute: open_action
        - script.wait: open_action
    close_action:
      then:
        - script.execute: close_action
        - script.wait: close_action
    stop_action:
      then:
        - script.execute: stop_action
        - script.wait: stop_action
    position_action:
      then:
        - lambda: |-
            id(position)=pos;
        - script.execute: position_action
        - script.wait: position_action

script:
  - id: open_action
    mode: restart
    then:
      - script.execute: enable_ble
      - script.wait: enable_ble
      - if:
          condition:
            and:
              - binary_sensor.is_on: bedroom_left_blind_connected
              - binary_sensor.is_on: bedroom_right_blind_connected
          then:
            - cover.open: bedroom_left_blind_cover_internal
            - cover.open: bedroom_right_blind_cover_internal
    
  - id: close_action
    mode: restart
    then:
      - script.execute: enable_ble
      - script.wait: enable_ble
      - if:
          condition:
            and:
              - binary_sensor.is_on: bedroom_left_blind_connected
              - binary_sensor.is_on: bedroom_right_blind_connected
          then:
            - cover.close: bedroom_left_blind_cover_internal
            - cover.close: bedroom_right_blind_cover_internal   
    
  - id: stop_action
    mode: restart
    then:
      - script.execute: enable_ble
      - script.wait: enable_ble
      - if:
          condition:
            and:
              - binary_sensor.is_on: bedroom_left_blind_connected
              - binary_sensor.is_on: bedroom_right_blind_connected
          then:
            - cover.stop: bedroom_left_blind_cover_internal
            - cover.stop: bedroom_right_blind_cover_internal
    
  - id: position_action
    mode: restart
    then:
      - script.execute: enable_ble
      - script.wait: enable_ble
      - if:
          condition:
            and:
              - binary_sensor.is_on: bedroom_left_blind_connected
              - binary_sensor.is_on: bedroom_right_blind_connected
          then:
            - lambda: |-
                auto call = id(bedroom_left_blind_cover_internal).make_call();
                call.set_position(id(position));
                call.perform();
                call = id(bedroom_right_blind_cover_internal).make_call();
                call.set_position(id(position));
                call.perform();
    
  - id: enable_ble
    mode: restart
    then:
      - logger.log: 
          format: "Enabling BLE..."
          level: INFO
      - switch.turn_on: bedroom_left_blind_ble
      - switch.turn_on: bedroom_right_blind_ble
      - wait_until:
          condition:
            and:
              - binary_sensor.is_on: bedroom_left_blind_connected
              - binary_sensor.is_on: bedroom_right_blind_connected
          timeout: 3min
      - if:
          condition:
            and:
              - binary_sensor.is_on: bedroom_left_blind_connected
              - binary_sensor.is_on: bedroom_right_blind_connected
          then: 
            - logger.log: 
                format: "BLE clients connected"
                level: INFO
          else: 
            - logger.log: 
                format: "Fail connect BLE clients"
                level: WARN

  - id: disable_ble
    mode: restart
    then:
      - logger.log: 
          format: "Disabling BLE..."
          level: INFO
      - switch.turn_off: bedroom_left_blind_ble
      - switch.turn_off: bedroom_right_blind_ble

  - id: sleeping_ble
    mode: restart
    then:
      - while: 
          condition:
            not:
              and:
                - binary_sensor.is_on: bedroom_left_blind_connected
                - binary_sensor.is_on: bedroom_right_blind_connected
          then:
            - logger.log: 
                format: "Conencting BLE again..."
                level: INFO
            - script.execute: enable_ble
            - script.wait: enable_ble
            
      - logger.log: 
          format: "Updating sensors..."
          level: INFO
      - delay: 2min
      
      - logger.log: 
          format: "Check that scripts not running..."
          level: INFO
      - while: 
          condition:
            or:
              - script.is_running: open_action
              - script.is_running: close_action
              - script.is_running: stop_action
              - script.is_running: position_action
          then:
            - logger.log: 
                format: "Still executing..."
                level: INFO
            - delay: 10s
      - script.execute: disable_ble
      - script.wait: disable_ble

  - id: main
    mode: single
    then:
      - while:
          condition:
            - lambda: "return true;"
          then:
            - script.execute: sleeping_ble
            - script.wait: sleeping_ble
            - delay: 60min
  
binary_sensor:
  - platform: template
    name: "Bedroom Left Blind Connected"
    id: bedroom_left_blind_connected
  - platform: template
    name: "Bedroom Right Blind Connected"
    id: bedroom_right_blind_connected

sensor:
  - platform: uptime
    name: Uptime Sensor
  - platform: ble_rssi
    mac_address: 02:7B:F1:3A:C6:63
    name: "Bedroom Left Blind RSSI"
  - platform: ble_rssi
    mac_address: 02:BD:67:49:4B:0D
    name: "Bedroom Right Blind RSSI"
  
  - platform: am43
    ble_client_id: bedroom_left_blind
    illuminance:
      name: "Bedroom Left Blind Light"
      filters:
        - filter_out: nan
    battery_level:
      name: "Bedroom Left Blind Battery"
      filters:
        - filter_out: nan
    
  - platform: am43
    ble_client_id: bedroom_right_blind
    illuminance:
      name: "Bedroom Right Blind Light"
      filters:
        - filter_out: nan
    battery_level:
      name: "Bedroom Right Blind Battery"
      filters:
        - filter_out: nan

switch:
  - platform: restart
    name: "Bedroom Blind ESP Reboot"
    
  - platform: ble_client
    name: "Bedroom Left Blind BLE"
    id: bedroom_left_blind_ble
    internal: true
    ble_client_id: bedroom_left_blind
    disabled_by_default: true
      
  - platform: ble_client
    name: "Bedroom Right Blind BLE"
    id: bedroom_right_blind_ble
    internal: true
    ble_client_id: bedroom_right_blind
    disabled_by_default: true

1 Like

Can anyone share a configuration for a single blind with ble on/off etc?
I can’t get it to work…

Thank you for your script, this looks really nice.

What I can’t get to work is setting the position. Does it work for you?

Somehow variable “pos” does not get transfered to global var “position”.
The position_action (cover: template) does have the pos value (see below), but the script does not have the id(position) value (always 0). I double checked that I have the globals set and consulted the docs but can’t figure out whats wrong. (I’m a noob with such scripting.)

[07:52:45][D][cover:076]: 'Buro Cover' - Setting
[07:52:45][D][cover:084]:   Position: 31%
[07:52:45][I][main:161]: Enabling BLE...
[07:52:45][D][switch:013]: 'Buro Blind BLE' Turning ON.
[07:52:45][I][main:174]: BLE clients connected
[07:52:45][D][cover:076]: 'buro_blinds_am43_cover_internal' - Setting
[07:52:45][D][cover:084]:   Position: 0%

For testing, I moved the script part to the cover:template like this and it works:

    position_action:
      then:
#        - lambda: |-
#            id(position) = pos;
#        - script.execute: position_action
#        - script.wait: position_action

##temp edit: moved position_action-script to cover-template, replaced id(position) with pos
        - script.execute: enable_ble
        - script.wait: enable_ble
        - if:
            condition:
              and:
                - binary_sensor.is_on: buro_blinds_am43_connected
            then:
              - lambda: |-
                  auto call = id(buro_blinds_am43_cover_internal).make_call();
                  call.set_position(pos);
                  call.perform();

I am having the same issue and I am not using external_components. Any idea on how to resolve it?

I think you need to describe your problem and what your logs show. Not quite sure what you are referring to when replying to my comment.

Would be great if someone could paste a working configuration and/or short description on how to get it running with ESPhome if NOT using a separate ESP32 (or other device). I can’t install any of the configurations above as I’m trying to install it on the main device which is not a ESP32.

I understand the “external components” line is no longer necessary, right?

How should the ESPhome yaml look like if running on a standalone machine?

Thank you so much!

Got it to work on an ESP32 (Wroom). Kind of, that is: It worked once (both blinds went up), but since then I couldn’t connect to the blinds anymore and it’s very unstable overall.

[14:51:10][I][am43_cover:032]: [right_blind_cover_internal] Logging into AM43
[14:51:11][I][am43_cover:123]: [right_blind_cover_internal] AM43 pin accepted.
[14:51:39][I][ble_client:086]: Attempting BLE connection to 02:97:7a:90:93:1e
[14:51:39][W][ble_client:119]: connect to 02:97:7a:90:93:1e failed, status=133
[14:52:02][I][ble_client:086]: Attempting BLE connection to 02:97:7a:90:93:1e
[14:52:03][W][ble_client:119]: connect to 02:97:7a:90:93:1e failed, status=133
[14:52:08][I][ble_client:086]: Attempting BLE connection to 02:97:7a:90:93:1e
[14:52:09][W][ble_client:119]: connect to 02:97:7a:90:93:1e failed, status=133

Then, all of a sudden, it’s working again:

[14:55:15][I][ble_client:384]:  characteristic 0xFE51, handle 0xe, properties 0x16
[14:55:15][I][ble_client:384]:  characteristic 0xFE52, handle 0x11, properties 0x8
[14:55:15][I][main:172]: BLE clients connected
[14:56:42][I][main:156]: Enabling BLE...
[14:56:42][I][main:172]: BLE clients connected

Does anyone have any idea how to make it more stable?

Hmm, strange thing, i don’t have any trouble with lambda, glade that you have found workaround)

what should i flash it with? or only set it up and connect to the device?

You should read a bit on esphome.io to get a better understanding. There you can also find relevant channels to ask for or find more generic help.
GLHF

when I do sudo ./am43ctrl beef60027245 all I get is the following:

Usage: am43ctrl MAC1 MAC2 --express-port 3000 --url [mqtt|ws][s]://yourbroker.example.com

Options:
  --help                      Show help                                                                                     [boolean]
  --version                   Show version number                                                                           [boolean]
  -d, --debug                 Enable debug logging                                                                          [boolean]
  -l, --express-port          Port for express web server (if unset, express will not startup)                               [number]
  --url, --mqtt-url           MQTT broker URL
  --topic, --mqtt-base-topic  Base topic for MQTT                                                          [default: "homeassistant"]
  -p, --mqtt-password         Password for MQTT (if not specified as an argument, will prompt for password at startup)
  -u, --mqtt-username         Username for MQTT
  -i, --interval              Minutes interval for device polling (default is random 10 to 20)                  [number] [default: 0]
  -f, --fail-time             Seconds since last successful device connection before program exit (default is never exit)
                                                                                                                [number] [default: 0]

Examples:
  am43ctrl MAC1 MAC2 --url [broker_url]  Connect to devices with specific IDs only, publish to MQTT

can you help please?

ESPHome 2022.10.2 has introduced new rssi sensor which breaks previous script version. I’ve update the script which is worked on ESPHome 2022.11.0b4 (but without rssi still):

esphome:
  name: am43
  platform: ESP32
  board: esp-wrover-kit
  on_boot:
    - script.execute: main
    - script.wait: main

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

logger:
  level: DEBUG

api:

ota:
  password: "XXXXXXXXXXXXX"

globals:

  - id: position
    type: int
    restore_value: no

  - id: left_connected
    type: bool
    restore_value: no
    initial_value: 'false'

  - id: right_connected
    type: bool
    restore_value: no
    initial_value: 'false'

bluetooth_proxy:
  active: true
   
esp32_ble_tracker:
  
ble_client:

  - mac_address: 02:7B:F1:3A:C6:63
    id: bedroom_left_blind
    on_connect:
      - globals.set:
          id: left_connected
          value: 'true'
    on_disconnect:
      - globals.set:
          id: left_connected
          value: 'false'
          
  - mac_address: 02:BD:67:49:4B:0D
    id: bedroom_right_blind
    on_connect:
      - globals.set:
          id: right_connected
          value: 'true'
    on_disconnect:
      - globals.set:
          id: right_connected
          value: 'false'

sensor:

  - platform: uptime
    name: Uptime Sensor

  # - platform: ble_client
  #   type: rssi
  #   ble_client_id: bedroom_left_blind
  #   name: "Bedroom Left Blind RSSI"

  # - platform: ble_client
  #   type: rssi
  #   ble_client_id: bedroom_right_blind
  #   name: "Bedroom Right Blind RSSI"
  
  - platform: am43
    ble_client_id: bedroom_left_blind
    illuminance:
      name: "Bedroom Left Blind Light"
      filters:
        - filter_out: nan
    battery_level:
      name: "Bedroom Left Blind Battery"
      filters:
        - filter_out: nan
    update_interval: 30sec
    
  - platform: am43
    ble_client_id: bedroom_right_blind
    illuminance:
      name: "Bedroom Right Blind Light"
      filters:
        - filter_out: nan
    battery_level:
      name: "Bedroom Right Blind Battery"
      filters:
        - filter_out: nan
    update_interval: 30sec

switch:

  - platform: restart
    name: "Bedroom Blind ESP Reboot"
    
  - platform: ble_client
    name: "Bedroom Left Blind BLE"
    id: bedroom_left_blind_ble
    ble_client_id: bedroom_left_blind
      
  - platform: ble_client
    name: "Bedroom Right Blind BLE"
    id: bedroom_right_blind_ble
    ble_client_id: bedroom_right_blind

cover:
  
  - platform: am43
    id: bedroom_left_blind_cover_internal
    ble_client_id: bedroom_left_blind
    pin: 1234
    internal: true
    
  - platform: am43
    id: bedroom_right_blind_cover_internal
    ble_client_id: bedroom_right_blind
    pin: 1234
    internal: true
    
  - platform: template
    name: "Bedroom Blinds"
    id: bedroom_blinds_cover
    has_position: true
    lambda: |-
      return (id(bedroom_left_blind_cover_internal).position + id(bedroom_right_blind_cover_internal).position) / 2;
    open_action:
      then:
        - script.execute: open_action
        - script.wait: open_action
    close_action:
      then:
        - script.execute: close_action
        - script.wait: close_action
    stop_action:
      then:
        - script.execute: stop_action
        - script.wait: stop_action
    position_action:
      then:
        - lambda: |-
            id(position)=pos;
        - script.execute: position_action
        - script.wait: position_action
    on_open:
      - logger.log: "Cover is Open!"
    on_closed:
      - logger.log: "Cover is Closed!"

script:
  - id: open_action
    mode: restart
    then:
      - logger.log: 
          format: "Open..."
          level: INFO
      - script.execute: enable_ble
      - script.wait: enable_ble
      - cover.open: bedroom_left_blind_cover_internal
      - cover.open: bedroom_right_blind_cover_internal
      - logger.log: 
          format: "...opened"
          level: INFO
    
  - id: close_action
    mode: restart
    then:
      - logger.log: 
          format: "Close..."
          level: INFO
      - script.execute: enable_ble
      - script.wait: enable_ble
      - cover.close: bedroom_left_blind_cover_internal
      - cover.close: bedroom_right_blind_cover_internal
      - logger.log: 
          format: "...closed"
          level: INFO
    
  - id: stop_action
    mode: restart
    then:
      - logger.log: 
          format: "Stop..."
          level: INFO
      - script.execute: enable_ble
      - script.wait: enable_ble
      - cover.stop: bedroom_left_blind_cover_internal
      - cover.stop: bedroom_right_blind_cover_internal
      - logger.log: 
          format: "...stoped"
          level: INFO
    
  - id: position_action
    mode: restart
    then:
      - logger.log: 
          format: "Set position..."
          level: INFO
      - script.execute: enable_ble
      - script.wait: enable_ble
      - lambda: |-
          auto call = id(bedroom_left_blind_cover_internal).make_call();
          call.set_position(id(position));
          call.perform();
          call = id(bedroom_right_blind_cover_internal).make_call();
          call.set_position(id(position));
          call.perform();
    
  - id: enable_ble
    mode: restart
    then:
      - logger.log: 
          format: "Enabling BLE..."
          level: INFO
      - if:
          condition:
            - switch.is_off: bedroom_left_blind_ble
          then:
            - switch.turn_on: bedroom_left_blind_ble
      - if:
          condition:
            - switch.is_off: bedroom_right_blind_ble
          then:
            - switch.turn_on: bedroom_right_blind_ble
      - wait_until:
          condition:
            lambda: |-
              return id(left_connected) && id(right_connected);
          timeout: 1min
      - if:
          condition:
            lambda: |-
              return !id(left_connected) || !id(right_connected);
          then: 
            - logger.log: 
                format: "... fail connect BLE clients, trying again ... "
                level: WARN
            - script.execute: enable_ble
            - script.wait: enable_ble
      - logger.log: 
          format: "...BLE enabled"
          level: INFO

  - id: disable_ble
    mode: single
    then:
      - logger.log: 
          format: "Disabling BLE..."
          level: INFO
      - switch.turn_off: bedroom_left_blind_ble
      - switch.turn_off: bedroom_right_blind_ble
      - wait_until:
          condition:
            lambda: |-
              return !id(left_connected) && !id(right_connected);
      - logger.log: 
          format: "...BLE disabled"
          level: INFO

  - id: update_sensors
    mode: single
    then:
      - logger.log: 
          format: "Updating sensors..."
          level: INFO
      - script.execute: enable_ble
      - script.wait: enable_ble
      - delay: 1min
      - logger.log: 
          format: "Check that scripts not running..."
          level: INFO
      - while: 
          condition:
            or:
              - script.is_running: open_action
              - script.is_running: close_action
              - script.is_running: stop_action
              - script.is_running: position_action
          then:
            - logger.log: 
                format: "Something Still executing..."
                level: INFO
            - delay: 10s
      - script.execute: disable_ble
      - script.wait: disable_ble
      - logger.log: 
          format: "...sensors updated"
          level: INFO

  - id: main
    mode: single
    then:
      - while:
          condition:
            - lambda: "return true;"
          then:
            - script.execute: update_sensors
            - script.wait: update_sensors
            - delay: 60min

Here is a new version with worked position and verified on EspHome 2022.11.0

esphome:
  name: am43
  platform: ESP32
  board: esp-wrover-kit
  on_boot:
    - script.execute: main
    - script.wait: main

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

logger:
  level: INFO

api:

ota:
  password: "XXXXXXXXX"
  
ble_client:

  - mac_address: 02:7B:F1:3A:C6:63
    id: bedroom_left_blind
    on_connect:
      - binary_sensor.template.publish:
          id: left_connected
          state: ON
      - logger.log: 
          format: "CONNECT LEFT"
          level: INFO
    on_disconnect:
      - binary_sensor.template.publish:
          id: left_connected
          state: OFF
      - logger.log: 
          format: "DISCONNECT LEFT"
          level: INFO
          
  - mac_address: 02:BD:67:49:4B:0D
    id: bedroom_right_blind
    on_connect:
      - binary_sensor.template.publish:
          id: right_connected
          state: ON
      - logger.log: 
          format: "CONNECT RIGHT"
          level: INFO
    on_disconnect:
      - binary_sensor.template.publish:
          id: right_connected
          state: OFF
      - logger.log: 
          format: "DISCONNECT RIGHT"
          level: INFO

binary_sensor:

  - platform: template
    device_class: connectivity
    id: left_connected
    name: "Left connected"

  - platform: template
    device_class: connectivity
    id: right_connected
    name: "Right connected"

  - platform: template
    device_class: opening
    id: left_open_status
    name: "Left status"

  - platform: template
    device_class: opening
    id: right_open_status
    name: "Right status"

sensor:

  - platform: uptime
    name: Uptime Sensor

  # - platform: ble_client
  #   id: bedroom_left_blind_rssi
  #   type: rssi
  #   ble_client_id: bedroom_left_blind
  #   name: "Bedroom Left Blind RSSI"

  # - platform: ble_client
  #   id: bedroom_right_blind_rssi
  #   type: rssi
  #   ble_client_id: bedroom_right_blind
  #   name: "Bedroom Right Blind RSSI"
  
  - platform: ble_rssi
    id: bedroom_left_blind_rssi
    mac_address: 02:7B:F1:3A:C6:63
    name: "Bedroom Left Blind RSSI"

  - platform: ble_rssi
    id: bedroom_right_blind_rssi
    mac_address: 02:BD:67:49:4B:0D
    name: "Bedroom Right Blind RSSI"

  - platform: am43
    ble_client_id: bedroom_left_blind
    illuminance:
      name: "Bedroom Left Blind Light"
      filters:
        - filter_out: nan
    battery_level:
      name: "Bedroom Left Blind Battery"
      filters:
        - filter_out: nan
    update_interval: 30sec
    
  - platform: am43
    ble_client_id: bedroom_right_blind
    illuminance:
      name: "Bedroom Right Blind Light"
      filters:
        - filter_out: nan
    battery_level:
      name: "Bedroom Right Blind Battery"
      filters:
        - filter_out: nan
    update_interval: 30sec

switch:

  - platform: restart
    name: "Bedroom Blind ESP Reboot"
    
  - platform: ble_client
    name: "Bedroom Left Blind BLE"
    id: bedroom_left_blind_ble
    ble_client_id: bedroom_left_blind
      
  - platform: ble_client
    name: "Bedroom Right Blind BLE"
    id: bedroom_right_blind_ble
    ble_client_id: bedroom_right_blind

cover:
  
  - platform: am43
    id: bedroom_left_blind_cover_internal
    ble_client_id: bedroom_left_blind
    pin: 1234
    internal: true
    on_open:
      - binary_sensor.template.publish:
          id: left_open_status
          state: ON
    on_closed:
      - binary_sensor.template.publish:
          id: left_open_status
          state: OFF

  - platform: am43
    id: bedroom_right_blind_cover_internal
    ble_client_id: bedroom_right_blind
    pin: 1234
    internal: true
    on_open:
      - binary_sensor.template.publish:
          id: right_open_status
          state: ON
    on_closed:
      - binary_sensor.template.publish:
          id: right_open_status
          state: OFF
    
  - platform: template
    name: "Bedroom Blinds"
    id: bedroom_blinds_cover
    has_position: true
    lambda: |-
      return (id(bedroom_left_blind_cover_internal).position + id(bedroom_right_blind_cover_internal).position) / 2;
    open_action:
      then:
        - script.execute: open_action
    close_action:
      then:
        - script.execute: close_action
    stop_action:
      then:
        - script.execute: stop_action
    position_action:
      then:
        - script.execute: 
            id: position_action
            value: !lambda return pos;

script:

  - id: open_action
    mode: restart
    then:
      - script.stop: close_action
      - script.stop: stop_action
      - script.stop: position_action
      - script.stop: update_sensors
      - logger.log: 
          format: "Open ..."
          level: INFO
      - script.execute: enable_ble
      - script.wait: enable_ble
      - cover.open: bedroom_left_blind_cover_internal
      - cover.open: bedroom_right_blind_cover_internal
      - while:
          condition:
            not:
              and:
                - binary_sensor.is_on: left_open_status
                - binary_sensor.is_on: right_open_status
          then:
            - logger.log: 
                format: "... opening ..."
                level: INFO
            - delay: 1sec
      - logger.log: 
          format: "... opened"
          level: INFO
      - script.execute: update_sensors
    
  - id: close_action
    mode: restart
    then:
      - script.stop: open_action
      - script.stop: stop_action
      - script.stop: position_action
      - script.stop: update_sensors
      - logger.log: 
          format: "Close ..."
          level: INFO
      - script.execute: enable_ble
      - script.wait: enable_ble
      - cover.close: bedroom_left_blind_cover_internal
      - cover.close: bedroom_right_blind_cover_internal
      - while:
          condition:
            not:
              and:
                - binary_sensor.is_off: left_open_status
                - binary_sensor.is_off: right_open_status
          then:
            - logger.log: 
                format: "... closing ..."
                level: INFO
            - delay: 1sec
      - logger.log: 
          format: "... closed"
          level: INFO
      - script.execute: update_sensors
    
  - id: stop_action
    mode: restart
    then:
      - script.stop: open_action
      - script.stop: close_action
      - script.stop: position_action
      - script.stop: update_sensors
      - logger.log: 
          format: "Stop ..."
          level: INFO
      - script.execute: enable_ble
      - script.wait: enable_ble
      - cover.stop: bedroom_left_blind_cover_internal
      - cover.stop: bedroom_right_blind_cover_internal
      - logger.log: 
          format: "... stoped"
          level: INFO
      - script.execute: update_sensors
    
  - id: position_action
    mode: restart
    parameters:
      value: float
    then:
      - script.stop: open_action
      - script.stop: close_action
      - script.stop: stop_action
      - script.stop: update_sensors
      - logger.log: 
          format: "Set position %f ..."
          level: INFO
          args: [ value ]
      - script.execute: enable_ble
      - script.wait: enable_ble
      - cover.control:
          id: bedroom_left_blind_cover_internal
          position: !lambda return value;
      - cover.control:
          id: bedroom_right_blind_cover_internal
          position: !lambda return value;
      - script.execute: update_sensors
    
  - id: enable_ble
    mode: restart
    then:
      - script.stop: disable_ble
      - logger.log: 
          format: "Enabling BLE..."
          level: INFO
      - if:
          condition:
            - switch.is_off: bedroom_left_blind_ble
          then:
            - switch.turn_on: bedroom_left_blind_ble
      - if:
          condition:
            - switch.is_off: bedroom_right_blind_ble
          then:
            - switch.turn_on: bedroom_right_blind_ble
      - while:
          condition:
            not:
              and:
                - binary_sensor.is_on: left_connected
                - binary_sensor.is_on: right_connected
          then:
            - logger.log: 
                format: "... waiting connection ..."
                level: INFO
            - delay: 1sec
      - logger.log: 
          format: "...BLE enabled"
          level: INFO

  - id: disable_ble
    mode: single
    then:
      - logger.log: 
          format: "Disabling BLE ..."
          level: INFO
      - switch.turn_off: bedroom_left_blind_ble
      - switch.turn_off: bedroom_right_blind_ble
      - logger.log: 
          format: "... BLE disabled"
          level: INFO

  - id: update_sensors
    mode: single
    then:
      - logger.log: 
          format: "Updating sensor ..."
          level: INFO
      - script.execute: enable_ble
      - script.wait: enable_ble
      - delay: 1min
      - while: 
          condition:
            or:
              - script.is_running: open_action
              - script.is_running: close_action
              - script.is_running: stop_action
              - script.is_running: position_action
          then:
            - logger.log: 
                format: "... domething Still executing ..."
                level: INFO
            - delay: 10s
      - script.execute: disable_ble
      - script.wait: disable_ble
      - logger.log: 
          format: "... sensors updated"
          level: INFO

  - id: main
    mode: single
    then:
      - while:
          condition:
            - lambda: "return true;"
          then:
            - script.execute: update_sensors
            - script.wait: update_sensors
            - delay: 60min

1 Like

Thank you, working really nice!

looks great, but can’t connect to my AM43

16:34:06	[I]	[main:275]	
... waiting connection ...
16:34:06	[W]	[am43:098]	
[02:9E:88:EB:B5:F6] Cannot poll, not connected

It’s to old (2020) or what I think I’m trying all :confused:

1 Like

make sure that you have set valid mac in the ble_client.mac_address and sensor.platform: ble_rssi.mac_address. And double check pin, ble_client_id, id for cover.platform: am43 sections. Don’t hesitate to share you conf and logs if there is some issues still.