Livolo RF433 Switches

Have anyone ever built a full integration between Livolo switches and HASS without a RFXTRX433?

The RFX.com device is full compatible with Livolo switches, but I don’t have one, just some chinese RF transmitter and Receivers, a HASS running on a Rpi and a mysensors gateway plugged in.

Someone already got the Livolo code and built a Mysensors library (second page)
https://forum.arduino.cc/index.php?topic=153525.0
Tried the example and got switch response, but don’t know how to create a HASS switch instance based on that example.

Others have already connected directly on Pi GPIO


and

I thought about using Raspberry Pi RF Switch but Livolo is not listed as compatible in the wiki.
or follow ReneTode’s step here:

I have plenty of 2 and 3 gangs Livolo switches controled by BroadLink RM-PRO, which has limited compatibility with all the world (just an Android based Bridge) and does a poor job controlling those switches.

Which is the best way to put all them into HASS?

  • RPI GPIO 433 transmitter
  • Mysensors node with 433 transmitter
  • Plugging and coding a 433 transmitter into the mysensors gateway.

and how to do that?
thanks.

So i got 1 switch working with this mysensors sketch:

#define MY_DEBUG 
#define MY_RADIO_NRF24
#include <SPI.h>
#include <MySensors.h>
#include <livolo.h>

#define CHILD_ID 1

Livolo livolo(8);

bool initialValueSent = false;

MyMessage msg(CHILD_ID, V_LIGHT);

void setup() {
  
}

void presentation()  {   
  sendSketchInfo("Livolo", "1.0");
  present(CHILD_ID, S_LIGHT);
}

void loop() {
  int value = 0;
  if (!initialValueSent) {
    Serial.println("Sending initial value");
    send(msg.set(value==HIGH ? 1 : 0));
    Serial.println("Requesting initial value from controller");
    request(CHILD_ID, V_LIGHT);
    wait(2000, C_SET, V_LIGHT);
  }
}

void receive(const MyMessage &message) {
  if (message.type==V_LIGHT) {
     livolo.sendButton(6400, 120);
     if (!initialValueSent) {
       Serial.println("Receiving initial value from controller");
       initialValueSent = true;
     }
  }
}

Now I need to change for 9 switches, changing the livolo.sendButton(REM_ID, BUT_ID) and the all the rest.
Keep trying…

there are 2posible ways to go.

  1. you set up a child in youre arduino for every switch. if you have just a few and wont change them afterwards, that is a good way.
  2. use the principle i used, which sends a code to the arduino and then the arduino decides which switch it should use.

i chose that option because i have over 50 switches laying around, waiting to get used.

i dont know this livolo library, but it seems that you give in 2 values in the code for every switch (in this case 6400,120)
i would then send a code like A6400B120 to the arduino (from out of HA) and let the arduino translate that to 6400 and 120.
that way you could also send A1800B640 or A600B1100 if that would be values which turn the switch.

Nice @ReneTode.

The 2nd way should be great because I’ll never have to change the arduino programed sketch. Perfect.

No matter how many switches I have, I just create an arduino node which send received command lines from the gateway.
After that, I just create virtual switches on HA that send the complete code livolo.sendButton(A, B) to that node.

Much better than coding all switches as Child_IDs and have to change each time I add a new switch.

Have you done this using mysensors?
And about the HA, is it the command_line switches or mysensors switches using services?

Thanks again

to go that way (which i did with my mysensors version) you need to use the service mysensors_send_ir_code

i use appdaemon and made this app:

after that i only needed to change the appdaemon config like this:

[schakelaars]
module = RFSwitch
class = RFSwitch
switch01 = switch.afstandbediening_2_4
switch02 = switch.afstandbediening_2_5
switch03 = switch.afstandbediening_2_6
switch04 = switch.afstandbediening_2_7
total_switches = 11
switchcode1 = eraa02P01
switchcode2 = epch02P02
switchcode3 = ewan02P03
switchcode4 = hboo02P04
switchcode5 = hban02P05
switchcode6 = hhoe02P15
switchcode7 = jacu01B15
switchcode8 = wate01D31
switchcode9 = aqua01A31
switchcode10 = rene02M02
switchcode11 = olin02M03

you could reuse that code if you rewrite your arduino switch.
after that all you have to do is change the codes that i used like B15 or M02 through your codes like A6400B120

then only you need to make a input_boolean for every switch:

input_boolean:
  eraamhoek:
    name: Raam hoek
    initial: off
    icon: mdi:lightbulb-outline
  epchoek:
    name: PC hoek
    initial: off
    icon: mdi:lightbulb-outline
  ewandmeubel:
    name: Wandmeubel
    initial: off
    icon: mdi:lightbulb-outline

1 Like

Uol!!!
That is too much for my programming skills…

I think I will first try the previous way you got your switches, creating that Template2 platform and describing each switch on the configuration.yaml.

My steps till now:

  1. created a file in the <HA_dir>/components/switch/template2.py and copy your config into it.
  2. Updated your arduino sketch to 2.0 version and compiled to my node (with 433Mhz tx)
  3. Added those lines to configuration.yaml

The HA UI showed those switches but when I click, there is no signals between the gateway and the RF node.

Tried doing with the Input_Boolean as well, but nothing…

I think that is the longest I got with this method and my knowledge.

Besides that, Livolo Switches has different coded communication, and I think it will be necessary using the livolo.h library, therefore, I only need to learn how to send that command “livolo.sendButton(XXXX, XXX)” based on which switch was pressed on the HA UI.

Thanks for the help, but I think I’ll try doing the first way, once there are just 9 switches and I think it will be easier learning how the MyMessage (mysensors) works than copy and try adapt your great job to my needs…

Sorry for my lack of programming knowledge

i think you were on the right track, but you missed 1 thing:

you need appdaemon for it: https://github.com/acockburn/appdaemon

my code is an app for that.
if you have installed appdaemon and implemented that app youre input_boolean will work.

so actually (except rewriting the arduinosketch) there is no programming involved.

  1. install appdaemon
  2. copy the app i wrote to your appdir
  3. edit de config from appdaemon with the first lines i gave (with youre codes)
  4. add input_booleans

and you would be ready to go.

How can I copy your app?
Do I need to create a file called RFSwitch.py on my appdir and copy theses lines into it?

import appapi

class RFSwitch(appapi.AppDaemon):

  def initialize(self):
    self.listen_state(self.switch, "input_boolean")
  
  def switch(self, entity, attribute, old, new, kwargs):
    for counter in range(1,int(self.args["total_switches"])+1):
        boolean_name_start= self.args["switchcode" + str(counter)][0:4]
        switch_type = self.args["switchcode" + str(counter)][4:6]
        switch_code = self.args["switchcode" + str(counter)][6:]
        switch=self.args["switch" + switch_type]
        if entity[14:18] == boolean_name_start:
          if new == "on":
            self.call_service("switch/mysensors_send_ir_code", entity_id = switch, V_IR_SEND=switch_code + "t")
          else:
            self.call_service("switch/mysensors_send_ir_code", entity_id = switch, V_IR_SEND=switch_code + "f")

and what about that template2 you created three months ago (Jul 29)


do we need it?

I just did exactly you did, but nothing sent nor received.

In time, i need to tell you I’m running HA on Raspberry Pi which was installed using the all-in-one install method, where has been installed into a hass user.

This AppDaemon was installed into the pi user, and I got it running with a terminal command:

[email protected]:~/appdaemon $ appdaemon -c conf/appdaemon.cfg
2016-09-26 17:14:52.459253 INFO AppDaemon Version 1.3.4 starting
2016-09-26 17:14:53.074179 INFO Got initial state
2016-09-26 17:14:53.081631 INFO Loading Module: /home/pi/appdaemon/conf/apps/hello.py
2016-09-26 17:14:53.093469 INFO Loading Object hello_world using class HelloWorld from module hello
2016-09-26 17:14:53.102408 INFO hello_world: Hello from AppDaemon
2016-09-26 17:14:53.106373 INFO hello_world: You are now ready to run Apps!
2016-09-26 17:14:53.109985 INFO Loading Module: /home/pi/appdaemon/conf/apps/RFSwitch.py
2016-09-26 17:14:53.126147 INFO Loading Object schakelaars using class RFSwitch from module RFSwitch
2016-09-26 17:14:53.132268 INFO Waiting for App initialization: 1 remaining
2016-09-26 17:14:54.141196 INFO App initialization complete

and still nothing…
I thought about how the gateway knows which node_id it needs to send the command, once my node is number 19, probably different from yours.

oke you have appdaemon.

now you need to save this code:

###########################################################################################
#  Home Assistant App for switching Mysensors (mysensors.org) 433 Mhz switch              #
#  If you have klik-aan-klik_uit, ELRO, Blokker or Action 433 Mhz switches,               #
#  all you have to do is to install a general mysensors sketch on an arduino              #
#  with a cheap 433 mhz sender. you can connect an infinitiv amount of switches with      #
#  up to 99 arduino nodes.                                                                #
#                                                                                         #
#  the sketch can be found here:                                                          #
#  https://community.home-assistant.io/t/general-mysensors-433-mhz-switch/2588/3          #
#  this is an example from an appdaemon.cfg app part:                                     #
#                                                                                         #
#  [RFSwitch1]                                                                            #
#  module = RFSwitch                                                                      #
#  class = RFSwitch                                                                       #
#  switch01 = switch.remote_2_4                                                           #
#  switch02 = switch.remote_2_5                                                           #
#  switch03 = switch.remote_2_6                                                           #
#  switch04 = switch.remote_2_7                                                           #
#  total_switches = 3                                                                     #
#  switchcode1 = rfaa02P01                                                                #
#  switchcode2 = rfab02P02                                                                #
#  switchcode3 = rfac02P03                                                                #
#                                                                                         #
#  explanation:                                                                           #
#  switch 01 to 04 are the 4 switches that the mysensors node create.                     #
#  you can use more nodes just add 05, 06, 07, ...                                        #
#  total_switches is the amount you have in use. in this case P01,P02 and P03             #
#  switchcode is build up from 3 parts.                                                   #
#  1) rfaa, rfab, rfac, ... the start from the name of the input_boolean you made         #
#  2) 01, 02, 03, ..., 99 the number from the arduinoswitch you want to send the code to. #
#  3) P01, A31, M16, ... code to send                                                     #
#  ELROcode => (A/E) buttoncode, (01/31) dipswitchcode                                    #
#  KAKUcode => (A/P) groupcode(dipswitch), (01/16) buttoncode                             #
#  Blokkercode => (A) to keep the code unified, (01/16) buttoncode                        #
#  Actioncode =>  (A/D) buttoncode, (01/?) dipswitchcode                                  #
#                                                                                         #
#  Rene Tode ( [email protected] )                                                            #
#  ( with a lot off help from andrew cockburn (aimc) )                                    #
#  2016/08/16 Germany                                                                     #
#                                                                                         #
###########################################################################################

import appdaemon.appapi as appapi
import datetime
import time

class RFSwitch(appapi.AppDaemon):

  def initialize(self):
    self.listen_state(self.switch, "input_boolean")
  
  def switch(self, entity, attribute, old, new, kwargs):
    for counter in range(1,int(self.args["total_switches"])+1):
        boolean_name_start= self.args["switchcode" + str(counter)][0:4]
        switch_type = self.args["switchcode" + str(counter)][4:6]
        switch_code = self.args["switchcode" + str(counter)][6:]
        switch=self.args["switch" + switch_type]
        device, entity_name = self.split_entity(entity)

        if entity[14:18] == boolean_name_start:
          if new == "on":
            self.call_service("switch/mysensors_send_ir_code", entity_id = switch, V_IR_SEND=switch_code + "t")
          else:
            self.call_service("switch/mysensors_send_ir_code", entity_id = switch, V_IR_SEND=switch_code + "f")

as RFSwitch.py
and save it in the appdir you have given in the config from appdaemon.

then in the config from appdaemon you make this section with these entry’s:

[schakelaars]
module = RFSwitch
class = RFSwitch
switch01 = switch.your_livoloswitch (the child id from youre arduino)
total_switches = 3
switchcode1 =  inpa01A6400B120
switchcode2 =  inpb01A6400B120
switchcode3 =  inpc01A6400B120

youre inputboolean names then start with inpa, inpb and inpc.
off course you can use any name you like if you just use the 4 first characters in the config.

the part where i used template2 was succesfull, but i needed to put that back with every update and i had quite a long automation file.

appdaemon made it easy.

i took a little time and i think that your arduino sketch should look something like this:

#define MY_DEBUG 
#define MY_RADIO_NRF24
#include <SPI.h>
#include <MySensors.h>
#include <livolo.h>

#define CHILD_ID 1

Livolo livolo(8);

bool initialValueSent = false;

MyMessage msg(CHILD_ID, V_LIGHT);
MyMessage msgCode(CHILD_ID, V_IR_SEND );
MyMessage msgCodeRec(CHILD_ID, V_IR_RECEIVE);

void setup() {
  
}

void presentation()  {   
  sendSketchInfo("Livolo", "1.0");
  present(CHILD_ID, S_IR);
}

void loop() {
  int value = 0;
  if (!initialValueSent) {
    Serial.println("Sending initial value");
    send(msg.set(value==HIGH ? 1 : 0));
    Serial.println("Requesting initial value from controller");
    request(CHILD_ID, V_LIGHT);
    wait(2000, C_SET, V_LIGHT);
  }
}

void receive(const MyMessage &message) {
  if (message.type==V_IR_SEND) {
   String codestring = message.getString();
   // here you need to put code to split the code you send
   // like (codea = int(a part from codestring)) and
   // codeb = int(a part from codestring)
   // the false true part is when you need to send two different codes to switch on and of
   // codec = the last character from your code
   // if(code[3]==char('t')){
      //Serial.println("schakelaar aangezet");
   //   Code3=true;
   // } else {
   //   //Serial.println("schakelaar uitgezet");
   //   Code3=false;
   // }
    if (message.sensor==CHILD_ID){
      livolo.sendButton(codea, codeb);
    }
    if (!initialValueSent) {
      Serial.println("Receiving initial value from controller");
      initialValueSent = true;
    }
  }
}

but @martinhjelmare could help you probably better there if you run into any trouble.

I assumed the switch.afstandbediening_2_4

both numbers are the first the node_ID assigned by the gateway, and the second number the child_ID that we assigned in the sketch, in this case, 1

my node_ID is 19 and the sketch name is livolo, so the string will be switch.livolo_19_1

so

[schakelaars]
module = RFSwitch
class = RFSwitch
switch01 = switch.livolo_19_1
total_switches = 12
switchcode1 = cade01A5504B16
switchcode2 = jant01A5504B56
switchcode3 = corr01A5504B8
switchcode4 = tele01A7849B19
switchcode5 = sanc01A7849B8
switchcode6 = vara01A7849B56
switchcode7 = cort01A17035B16
switchcode8 = sala01A17035B56
switchcode9 = sofa01A17035B8
switchcode10 = alla01A5504B42
switchcode11 = allb01A7849B42
switchcode12 = allc01A17035B42

but there is no communication yet…
is there a way to verify the daemon app is running?

the serial gateway from the arduino shows:

��E�q�t�!G֒�����Aá<�{�ey�HB�G��)0VStarting sensor (RNNNA-, 2.0.0)
TSM:INIT
TSM:RADIO:OK
TSP:ASSIGNID:OK (ID=19)
TSM:FPAR
TSP:MSG:SEND 19-19-255-255 s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=bc:
TSP:MSG:READ 0-0-19 s=255,c=3,t=8,pt=1,l=1,sg=0:0
TSP:MSG:FPAR RES (ID=0, dist=0)
TSP:MSG:PAR OK (ID=0, dist=1)
TSM:FPAR:OK
TSM:ID
TSM:CHKID:OK (ID=19)
TSM:UPL
TSP:PING:SEND (dest=0)
TSP:MSG:SEND 19-19-0-0 s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=ok:1
TSP:MSG:READ 0-0-19 s=255,c=3,t=25,pt=1,l=1,sg=0:1
TSP:MSG:PONG RECV (hops=1)
TSP:CHKUPL:OK
TSM:UPL:OK
TSM:READY
TSP:MSG:SEND 19-19-0-0 s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=ok:0100
TSP:MSG:SEND 19-19-0-0 s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=ok:2.0.0
TSP:MSG:SEND 19-19-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=ok:0
TSP:MSG:READ 0-0-19 s=255,c=3,t=6,pt=0,l=1,sg=0:M
TSP:MSG:SEND 19-19-0-0 s=255,c=3,t=11,pt=0,l=6,sg=0,ft=0,st=ok:Livolo
TSP:MSG:SEND 19-19-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=ok:1.0
TSP:MSG:SEND 19-19-0-0 s=1,c=0,t=20,pt=0,l=0,sg=0,ft=0,st=ok:
Request registration…
TSP:MSG:SEND 19-19-0-0 s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=ok:2
TSP:MSG:READ 0-0-19 s=255,c=3,t=27,pt=1,l=1,sg=0:1
Node registration=1
Init complete, id=19, parent=0, distance=1, registration=1
Sending initial value
TSP:MSG:SEND 19-19-0-0 s=1,c=1,t=2,pt=2,l=2,sg=0,ft=0,st=ok:0
Requesting initial value from controller
TSP:MSG:SEND 19-19-0-0 s=1,c=2,t=2,pt=0,l=0,sg=0,ft=0,st=ok:
TSP:MSG:READ 0-0-19 s=1,c=1,t=2,pt=0,l=1,sg=0:0

yeah you can check if the app is running correctly.

in the log you would see that the app is activated.
and if you put these lines beneath the call_service lines in the app:

self.log("i did send code " + switch_code + "t to " + switch,"INFO")

self.log("i did send code " + switch_code + "f to " + switch,"INFO")

you must see a log entry in your appdaemon log.

what is your sketchcode?

Trying to find the appdaemon.log, but nothing
My sketch

#define MY_DEBUG 
#define MY_RADIO_NRF24
#include <SPI.h>
#include <MySensors.h>
#include <livolo.h>

#define CHILD_ID 1

Livolo livolo(8);

bool initialValueSent = false;

MyMessage msg(CHILD_ID, V_LIGHT);
MyMessage msgCode(CHILD_ID, V_IR_SEND );
MyMessage msgCodeRec(CHILD_ID, V_IR_RECEIVE);

void setup() {
  
}

void presentation()  {   
  sendSketchInfo("Livolo", "1.0");
  present(CHILD_ID, S_IR);
}

void loop() {
  int value = 0;
  if (!initialValueSent) {
    Serial.println("Sending initial value");
    send(msg.set(value==HIGH ? 1 : 0));
    Serial.println("Requesting initial value from controller");
    request(CHILD_ID, V_LIGHT);
    wait(2000, C_SET, V_LIGHT);
    initialValueSent = true;
  }
}

void receive(const MyMessage &message) {
  if (message.type==V_IR_SEND) {
   String codestring = message.getString();
   // here you need to put code to split the code you send
   // like (codea = int(a part from codestring)) and
   // codeb = int(a part from codestring)
   // the false true part is when you need to send two different codes to switch on and of
   // codec = the last character from your code
   // if(code[3]==char('t')){
      //Serial.println("schakelaar aangezet");
   //   Code3=true;
   // } else {
   //   //Serial.println("schakelaar uitgezet");
   //   Code3=false;
   // }
    if (message.sensor==CHILD_ID){
      livolo.sendButton(6400, 120);
    }
    if (!initialValueSent) {
      Serial.println("Receiving initial value from controller");
      initialValueSent = true;
    }
  }
}

I changed the stringcodes for the initial numbers just to test… when i got the communication, I’ll think about that codestring.

in the configuration file from appdaemon you have set the place where you put the log.
if you have it as stdout you will see it in youre terminal.

before you did show the part where we can see appdaemon is running correct and the app is active.
can you see the switch.livolo_19_1 in HA?

if so, how are youre inputbooleans configured?

in fact I can’t see the livolo_19_1 in HA. I just see the inputbooleans switches. But I though it was supposed to not be seen, once it is only the way the booleans will communicate with the node.

And there is no log file from appdaemon, even after I set the place on the daemon config file.

my inputbooleans are configured this way:

input_boolean:
  cadeiras:
    name: Cadeiras
    initial: off
    icon: mdi:lightbulb-outline
  jantar:
    name: Mesa de Jantar
    initial: off
    icon: mdi:lightbulb-outline
  corredor:
    name: Corredor
    initial: off
    icon: mdi:lightbulb-outline
  televisao:
    name: Televisao
    initial: off
    icon: mdi:lightbulb-outline
  sanca:
    name: Sanca
    initial: off
    icon: mdi:lightbulb-outline
  varanda:
    name: Varanda
    initial: off
    icon: mdi:lightbulb-outline
  cortina:
    name: Cortinas
    initial: off
    icon: mdi:lightbulb-outline
  sala:
    name: Sala Centro
    initial: off
    icon: mdi:lightbulb-outline
  sofa:
    name: Sofa
    initial: off
    icon: mdi:lightbulb-outline

But when I recently tried that configuration with arduino only, assembly each switch a child_id, without rebooting Raspberry Pi or HA, I got switches from 2 to 10 id on the HA interface, which let me think that the livolo_19_1 was there, hidden, but was there. Am I wrong?

only if you hide the switch it will not show.
but it should still show up in the entitylist (developerstools)
if it doesnt show up there then the child isnt right presented.

do you still have the code where you got 2 to 10?
all you have to do is lose the 3 to 10 parts and put in the part where you splitt out the code in the recieve void.

you can also try to change the child id to 11 or higher. (could be that HA remembers the old ones, i got that sometimes and with the little knowledge i have it was easier to take a new number)

the switch you set in appdaemon must exist in HA for it to work.

when I turn the node on, I can see in the HA log (mysensors debug)

16-09-26 20:39:13 homeassistant.components.mysensors: Update sensor_update: node 19
16-09-26 20:39:14 homeassistant.components.mysensors: Update sensor_update: node 19
16-09-26 20:39:14 homeassistant.components.mysensors: Update sensor_update: node 19
16-09-26 20:39:14 homeassistant.components.mysensors: Update sensor_update: node 19
16-09-26 20:39:14 homeassistant.components.mysensors: Update sensor_update: node 19