Help/idea with automation/scripts (Sonoff Basic with Tasmota)

Hello everyone!

I wonder if anyone could suggest the approach for this idea. I have 27 Sonoffs basic with GPIO14, TX and RX soldered with wires connected to the physical light switches. Everything works perfectly on Tasmota but now I need to set functions to TX and RX on Home Assistant, total of 54 commands (TOGGLE), no need for POWER1 TOGGLE since it is already configured on each light entity created. Also I want to use the HOLD message, so it will result on 135 commands (including POWER1 topic).

What do you guys think it would be the best approach? Create 135 automations looking the MQTT message and executing a script? Create 135 MQTT switches?

Something like this:

Total of 27 relays:

  • 81 physical switches
  • 54 TOGGLE commands
  • 81 HOLD commands

It would be very nice to have it on a single automation so the action could identify the trigger and execute a script…

Here are all topic states:

stat/s_1_luz_tv/POWER1
stat/s_1_luz_escada/POWER1
stat/s_1_sala_luz_corredor/POWER1
stat/s_1_sala_luz_mesa/POWER1
stat/s_1_sala_luz_escritorio/POWER1
stat/s_1_cozinha_luz_principal/POWER1
stat/s_1_cozinha_luz_fogao/POWER1
stat/s_1_cozinha_luz_area_serviço/POWER1
stat/s_1_quartos_2_luz_principal/POWER1
stat/s_1_quartos_2_luz_cabeceira/POWER1
stat/s_1_banheiros_2_luz_principal/POWER1
stat/s_1_banheiros_2_luz_espelho/POWER1
stat/s_1_quartos_1_luz_armario/POWER1
stat/s_1_quartos_1_luz_cabeceira/POWER1
stat/s_1_banheiros_1_luz_principal/POWER1
stat/s_1_banheiros_1_luz_espelho/POWER1
stat/s_1_banheiros_1_luz_mictorio/POWER1
stat/s_2_sala_luz_tv/POWER1
stat/s_2_sala_luz_escada/POWER1
stat/s_2_sala_luz_principal/POWER1
stat/s_2_sala_luz_mesa_jantar/POWER1
stat/s_2_sala_luz_balcao/POWER1
stat/s_2_sala_luz_acesso_terraco/POWER1
stat/s_2_cozinha_luz_principal/POWER1
stat/s_2_banheiro_luz_principal/POWER1
stat/s_2_terraco_luz_principal/POWER1
stat/s_2_terraco_luz_deck/POWER1

stat/s_1_luz_tv/POWER2
stat/s_1_luz_escada/POWER2
stat/s_1_sala_luz_corredor/POWER2
stat/s_1_sala_luz_mesa/POWER2
stat/s_1_sala_luz_escritorio/POWER2
stat/s_1_cozinha_luz_principal/POWER2
stat/s_1_cozinha_luz_fogao/POWER2
stat/s_1_cozinha_luz_area_serviço/POWER2
stat/s_1_quartos_2_luz_principal/POWER2
stat/s_1_quartos_2_luz_cabeceira/POWER2
stat/s_1_banheiros_2_luz_principal/POWER2
stat/s_1_banheiros_2_luz_espelho/POWER2
stat/s_1_quartos_1_luz_armario/POWER2
stat/s_1_quartos_1_luz_cabeceira/POWER2
stat/s_1_banheiros_1_luz_principal/POWER2
stat/s_1_banheiros_1_luz_espelho/POWER2
stat/s_1_banheiros_1_luz_mictorio/POWER2
stat/s_2_sala_luz_tv/POWER2
stat/s_2_sala_luz_escada/POWER2
stat/s_2_sala_luz_principal/POWER2
stat/s_2_sala_luz_mesa_jantar/POWER2
stat/s_2_sala_luz_balcao/POWER2
stat/s_2_sala_luz_acesso_terraco/POWER2
stat/s_2_cozinha_luz_principal/POWER2
stat/s_2_banheiro_luz_principal/POWER2
stat/s_2_terraco_luz_principal/POWER2
stat/s_2_terraco_luz_deck/POWER2

stat/s_1_luz_tv/POWER3
stat/s_1_luz_escada/POWER3
stat/s_1_sala_luz_corredor/POWER3
stat/s_1_sala_luz_mesa/POWER3
stat/s_1_sala_luz_escritorio/POWER3
stat/s_1_cozinha_luz_principal/POWER3
stat/s_1_cozinha_luz_fogao/POWER3
stat/s_1_cozinha_luz_area_serviço/POWER3
stat/s_1_quartos_2_luz_principal/POWER3
stat/s_1_quartos_2_luz_cabeceira/POWER3
stat/s_1_banheiros_2_luz_principal/POWER3
stat/s_1_banheiros_2_luz_espelho/POWER3
stat/s_1_quartos_1_luz_armario/POWER3
stat/s_1_quartos_1_luz_cabeceira/POWER3
stat/s_1_banheiros_1_luz_principal/POWER3
stat/s_1_banheiros_1_luz_espelho/POWER3
stat/s_1_banheiros_1_luz_mictorio/POWER3
stat/s_2_sala_luz_tv/POWER3
stat/s_2_sala_luz_escada/POWER3
stat/s_2_sala_luz_principal/POWER3
stat/s_2_sala_luz_mesa_jantar/POWER3
stat/s_2_sala_luz_balcao/POWER3
stat/s_2_sala_luz_acesso_terraco/POWER3
stat/s_2_cozinha_luz_principal/POWER3
stat/s_2_banheiro_luz_principal/POWER3
stat/s_2_terraco_luz_principal/POWER3
stat/s_2_terraco_luz_deck/POWER3

I have a working singe automation for a Xiaomi Cube that goes like this:

- alias: BotĂŁo Xiaomi quarto
  trigger:
    platform: mqtt
    topic: 'zigbee2mqtt/casa_xiaomi_botao_quarto_01'
  condition:
    condition: template
    value_template: "{{ trigger.payload_json.click in ('single','double','triple','quadruple','many','long') }}"
  action:
    service_template: "script.botao_xiaomi_quarto_01_{{ trigger.payload_json.click }}"

I was thinking of something like this, so I could just create all scripts like this: script.interruptor_s_1_luz_tv_POWER2_TOGGLE.

Thanks a lot!

So it looks like you could do something like this, but you’d need to name your scripts based on the second phrase in your topics.

Also, i’m not versed well in MQTT, i just got the /+ thing from the documents, no clue if that’s how it works.

  - alias: mqtt
    trigger:
      - platform: mqtt
        topic: stat/+
    condition:
      - condition: template
        value_template: "{{ trigger.payload_json.click in ('single','double','triple','quadruple','many','long') }}"
    action:
       - service_template: >
           script.{{ trigger.topic.split('/')[1] }}
         data_template:
           power: >
             {{ trigger.topic.split('/')[-1] }}

I’m not sure if that would work because you aren’t providing enough information. Is this just for a toggle? What would these scripts look like?

1 Like

Hello! Thanks for your time, I really appreciate it.

Sorry, I was definitely not clear enough explaining my ideia.

That automation sample is the one I use for Xiaomi wireless buttons, over Zigbee2MQTT protocol, so that is what the click type is. I like the way the service template is created using the json information from the message.

What I really need is to use my Sonoffs Basics with 3 physical buttons, one for the real relay and 2 for virtual relays that results on POWER2 and POWER3 messages over MQTT. Both topics can broadcast TOGGLE and HOLD commands, so excluding the POWER1 TOOGLE command (already set on the light entity), I can use POWER1 HOLD, POWER2 TOOGLE, POWER2 HOLD, POWER3 TOGGLE and POWER3 HOLD to trigger scripts using automation (MQTT trigger).

I am not sure the best way to simplify this process of calling the correct script by stripping the full topic sent by the device, for example:

If I press TOGGLE on POWER2 using the device s_1_luz_tv I get stat/s_1_luz_tv/RESULT = TOGGLE. So I need to figure out how to strip this message to know which device and what command is sent and use it on the service_template to simplify the script entity_id, so this example would be script.interruptor_s_1_luz_tv_POWER2_TOGGLE.

So just one automation could call any of the 135 pre made scripts.

This process will be used with other POWER# topics and HOLD/TOGGLE messages to call different scripts.

All scripts would be pre-configured and named accordingly, so I can change it later if needed.

Sorry if I was not able to explain it better :slight_smile:

Thanks again my friend!

Not sure if this would help:

Since this is the message I get when TOOGLE is sent using POWER2 - stat/s_1_luz_tv/RESULT = {"POWER2":"TOGGLE"}, maybe this would work?

- service_template: script.interruptor_{{ trigger.topic.split('/')[1] }}_{{ trigger.payload_json }}_{{ trigger.payload_json.POWER1 }}{{ trigger.payload_json.POWER2 }}{{ trigger.payload_json.POWER3 }}

Or when I get stat/s_1_luz_tv/POWER2 = TOGGLE i could use:

- service_template: script.interruptor_{{ trigger.topic.split('/')[1] }}_{{ trigger.topic.split('/')[2] }}_{{ trigger.payload_json }}

To use with script.interruptor_s_1_luz_tv_POWER2_TOGGLE

Can tx and Rx shorted to ground be used to send mqtt messages on the sonoff basic using tasmota?

Yes! That is what I did. You need to set the module to generic and then set two pins as relays and switches, so it thinks it is activating relays and sends POWER2 and POWER3 messages.

Here is a backlog for it:

Backlog Module 18; GPIO0 9; GPIO1 10; GPIO2 0; GPIO3 11; GPIO4 0; GPIO5 0; GPIO12 17; GPIO13 52; GPIO14 9; GPIO15 18; GPIO16 19; SetOption13 1; SerialLog 0, SetOption26 0; SwitchTopic 1; SwitchMode1 5; SwitchMode2 5; SwitchMode3 5; SetOption32 20

Thanks. I have a module where gpio14 doesn’t seem to work so I might try soldering something into tx or Rx.

I use toggle buttons rather than momentary. Do you know if Rx or Rx can be pulled to ground on boot without doing anything wiered

1 Like

I use RX and TX just like GPIO14, you can do everything with them. I have both momentary and toggle switches, you just need to change switchmode in console. Also, you can only use HOLD with toggle switches, obviously. Good luck!

Do you have an example of this premade script?

That is the beauty of it: I can create anything I want by just using the correct name standard.

Something like this:

script.interruptor_s_1_luz_tv_POWER2_TOGGLE:
  alias: "Luz painel TV"
  sequence:
  - service: light.toggle
    entity_id: light.ledsuitecama

As simple as that or as complex as I need. The main problem here is how to call the correct script given the topic and message information only by the automation.

Thanks!

I’m wondering if you even need to make a script for each one. Anyways, this should work assuming the stat/+ bullshit works and if this is how your topics come across:

  - alias: mqtt
    trigger:
      - platform: mqtt
        topic: stat/+
    condition:
      - condition: template
        value_template: "{{ trigger.payload_json.items() | list | length >= 1 and trigger.topic.split('/') | length == 3 }}"
    action:
       - service_template: >
           {% set args = trigger.payload_json.items() | list %}
           {% set power, action = args[0] %}
           {% set a, scriptname, c = trigger.topic.split('/') %}
           script.interruptor_{{ scriptname }}_{{ power }}_{{ action }}
1 Like

Amazing job! I will try it ASAP and let you know the results! Thanks again mate!

You may want to check and see if the 3rd split item in your trigger topic is equal to “RESULT” as well to filter out similar topics.

Ok.

Just to make sure: the scriptname variable would be the MQTT topic for the device, correct? The script name will adapt to relative topic and actions…

Thanks.

The way it’s written, this topic:

stat/s_1_luz_tv/RESULT

with this payload:

{"POWER2":"TOGGLE"}

should run this script:

script.interruptor_s_1_luz_tv_POWER2_TOGGLE
1 Like

Also: I am thinking about the trigger condition… Wouldn’t be better to have de devices topics (list above) as conditions? Since I use Zigbee2MQTT and many other MQTT devices, it could only trigger by the topics I want.

Just a tough.

you could move the topics to start with something other than stat for this. Otherwise, you’ll be writing out all triggers by hand.

1 Like

Hello my friend! After a couple of days of testing this worked out for me. Since Power2 and Power3 sends TOGGLE commands, I’ve created individual automations (so I can disable them by their function) to call scripts named after the trigger action/topic result:

- alias: BotĂŁo Sonoff - Hold
  trigger:
    - platform: mqtt
      topic: cmnd/#
      payload: 'HOLD'  
  action:
    - service_template: script.interruptor_{{ trigger.topic.split('/')[1] | lower }}_{{ trigger.topic.split('/')[2] | lower }}_hold

- alias: BotĂŁo Sonoff - Power 2 toggle
  trigger:
    - platform: mqtt
      topic: cmnd/+/POWER2
      payload: 'TOGGLE'
  action:
    - service_template: script.interruptor_{{ trigger.topic.split('/')[1] | lower }}_{{ trigger.topic.split('/')[2] | lower }}_power2

- alias: BotĂŁo Sonoff - Power 3 toggle
  trigger:
    - platform: mqtt
      topic: cmnd/+/POWER3
      payload: 'TOGGLE'
  action:
    - service_template: script.interruptor_{{ trigger.topic.split('/')[1] | lower }}_{{ trigger.topic.split('/')[2] | lower }}_power3

Since POWER1 are usually configured as light or switch, the message sent is either ON or OFF, so no problems on using those automations/scripts.

I’ve found some great info HERE. like this:

Topics/Subscriptions

Messages in MQTT are published on topics. There is no need to configure a topic, publishing on it is enough. Topics are treated as a hierarchy, using a slash (/) as a separator. This allows sensible arrangement of common themes to be created, much in the same way as a filesystem. For example, multiple computers may all publish their hard drive temperature information on the following topic, with their own computer and hard drive name being replaced as appropriate:

sensors/COMPUTER_NAME/temperature/HARDDRIVE_NAME

Clients can receive messages by creating subscriptions. A subscription may be to an explicit topic, in which case only messages to that topic will be received, or it may include wildcards. Two wildcards are available, + or #.

+ can be used as a wildcard for a single level of hierarchy. It could be used with the topic above to get information on all computers and hard drives as follows:

sensors/+/temperature/+

As another example, for a topic of "a/b/c/d", the following example subscriptions will match:

a/b/c/d

+/b/c/d

a/+/c/d

a/+/+/d

+/+/+/+

The following subscriptions will not match:

a/b/c

b/+/c/d

+/+/+

# can be used as a wildcard for all remaining levels of hierarchy. This means that it must be the final character in a subscription. With a topic of "a/b/c/d", the following example subscriptions will match:

a/b/c/d

#

a/#

a/b/#

a/b/c/#

+/b/c/#

Zero length topic levels are valid, which can lead to some slightly non-obvious behaviour. For example, a topic of "a//topic" would correctly match against a subscription of "a/+/topic". Likewise, zero length topic levels can exist at both the beginning and the end of a topic string, so "/a/topic" would match against a subscription of "+/a/topic", "#" or "/#", and a topic "a/topic/" would match against a subscription of "a/topic/+" or "a/topic/#".

Thanks for your help!

Hello @petro! How are you today my friend?

I was wondering if you could help me again, with a new take on this automation.

I’ve learned to work with rules inside Tasmota so now I can control all switches by using buttons, so now I just publish mqtt messages when a any of the three buttons are pressed (toggle and hold functions).

The topic structure are like this:

stat/device_topic/BUTTON {"BUTTON1":"HOLD"}

Here is the main idea for the automation:

- alias: Sonoff buttons
  initial_state: true
  trigger:
    - platform: mqtt
      topic: stat/+/BUTTON
  action:
    - service_template: script.interruptor_{{ trigger.topic.split('/')[1] | lower }}_{{ trigger.payload_json.split('.')[0] | lower }}_{{ trigger.payload_json.split('.')[1] | lower }}

Trigger seems to be working fine but I have not been able to parse just a part of the trigger.json_payload since I call a script name by using just the BUTTON# part and final “action” part to call the correct script.

So I can call this script, for example:

interruptor_device_topic_button1_hold:
  alias: "Luz principal"
  sequence:
    - service: light.toggle
      entity_id: light.cozinha

I am getting this error with this automation:

Error while executing automation automation.botoes_sonoff. Error rendering template for call_service at pos 1: UndefinedError: 'dict object' has no attribute 'split'

Can you please help me with this parsing code?

Thanks a lot!

Hmm, I’m on my phone, when I get home I’ll take a look

1 Like