ESP8266 with motor should be controlled from HA

Hi,
I have a esp8266 board connected with a dc motor (relay) which can move forwards and backwards for 30 seconds. So my plan is to have a input_number slider in HA from 0 to 30 and the motor should change the position.

Now I have some problems persisting the current position on the esp. I tried to solve that with mqtt with less effort.

My questions:

  • How can I react on “target-state” changes from HA?
  • How can I subscribe the “current state” from mqtt?
  • How can I publish the “new state” from mqtt (retained message)?

my current solution (it’s working a little bit but the communication with mqtt is very bad):
soll… target state
ist… current state

mqtt:
#  broker: homeassistant.local
  broker: 10.0.0.223
  port: 1883
  username: mqtt
  password: *******
#  topic_prefix: fbh
  discovery: false
  discovery_prefix: homeassistant

sensor:
  - platform: homeassistant
    id: "fbh_soll"
    entity_id: sensor.fbh_soll

  - platform: mqtt_subscribe
    id: fbh_ist
    topic: fbh/sensor/fbh_ist/state
    name: "FBH IST Kreis 1"
    retain: true


globals:    
  - id: fbh_diff
    type: int
    restore_value: no
    initial_value: '0'
    
  - id: fbh_ist_intern
    type: int
    restore_value: yes
    initial_value: '0'


switch:
    - platform: gpio
      pin: 
          number: GPIO5
          inverted : False
          mode: OUTPUT
      id: relay2
      restore_mode : ALWAYS_OFF

    - platform: gpio
      pin:
        number: GPIO4    
        inverted : False        
        mode: OUTPUT
      id: relay1
      restore_mode : ALWAYS_OFF
      
      
interval:
  - interval: 10s
    then:
# moving up
     - if:
        condition:
          lambda: 'id(fbh_ist_intern) = (int)(id(fbh_ist).state); return (((int)id(fbh_soll).state - (int)id(fbh_ist_intern)) > 0);'
        then:
          - logger.log: "more!"
          - switch.turn_off: relay2
          - switch.turn_on: relay1
          - delay: !lambda "id(fbh_diff) = (int)id(fbh_soll).state - (int)id(fbh_ist_intern); return 0;"
          - delay: !lambda "return id(fbh_diff)*1000;"
          - switch.turn_off: relay1
          - delay: !lambda "id(fbh_ist_intern) = (int)id(fbh_ist_intern)+(int)id(fbh_diff); return 0;"
          - delay: !lambda "id(fbh_ist).publish_state(id(fbh_ist_intern)); return 0;"
          - mqtt.publish:
             topic: fbh/sensor/fbh_ist/state
             payload: !lambda |-
               return esphome::to_string(id(fbh_ist_intern))+"a";
             retain: true

# moving down
     - if:
        condition:
          lambda: 'id(fbh_ist_intern) = (int)id(fbh_ist).state;  return (((int)id(fbh_ist_intern) - (int)id(fbh_soll).state) > 0);'
        then:
          - logger.log: "less!"
          - switch.turn_off: relay1
          - switch.turn_on: relay2
          - delay: !lambda "id(fbh_diff) = (int)id(fbh_ist_intern) - (int)id(fbh_soll).state; return 0;"
          - delay: !lambda "return id(fbh_diff)*1000;"
          - switch.turn_off: relay2
          - delay: !lambda "id(fbh_ist_intern) = (int)id(fbh_ist_intern)-(int)id(fbh_diff); return 0;"
          - delay: !lambda "id(fbh_ist).publish_state(id(fbh_ist_intern)); return 0;"
          - mqtt.publish:
             topic: fbh/sensor/fbh_ist/state
             payload: !lambda |-
               return esphome::to_string(id(fbh_ist_intern))+"b";
             retain: true

Maybe someone can help me with a simple bidirectional mqtt example.

Thanks!

Is there a reason you set the mqtt discovery to false? If you set it to true, the entities will be added. You should probable set up a template cover. It will give you positional commands.

1 Like

So the only state feedback is how much time each directional motor has been switched on? If that’s true it will be difficult to keep the state synced. a cover component seems like a better fit as @Mikefila suggested.

Also, you may want to interlock your switches if you don’t want them to be on at the same time.

1 Like