Part 6 - Buttons (switches)

In the Pi-Home project, you can use any standard buttons and switches for 230 V or special ones for 24 V or 12V. In smart homes, instead of switches (classic off/on positions) the buttons are preferred (return to original position after pressing) . The reason is obvious, we can attach more different functions to the button (repeated pressing, holding, etc). In our realizations we have a very good experience with classic 230V buttons from Hager/Berker, but of course it is possible to use any other brands.

 

What we'll need

 

Part 2 - OpenHAB na Raspberry Pi

230V buttons - design is up to you, Hager/Berker recommended

Arduino Mega with Ethernet Shield (DIN holder)

Krone LSA terminals

 

Power and scheme

We recommend to wire an UTP cable to the buttons in smart homes. CAT5 or CAT6 are enough. Every UTP/FTP has 8 wires. For one button we need only 2 wires (DATA and GND), for two buttons 3 wires, for four buttons 5 wires. You can use one UTP cable and connect more buttons, but be sure to keep a reserve, you never know when will be needed. The GND is always connected together and all GNDs are connected to the groundingKRONE terminal - in the picture the red terminal (it has all pins connected). Second contacts of the buttons are connected to the classic white KRONE terminal and individual pins are then connected from here to the pins of the Arduino Mega board. It goes through the KRONE terminal because of the possibilities of changes and better overview of cabling. Of course you can lead UTP wires directly to the Arduino pin, but it can become rigind and messy. More than 50 buttons or 25 two-buttons can be connected to one Arduino Mega board etc.

 

Pi-Home - zapojení vypínačů OpenHAB

 

Software

The aim is to send us the information via the MQTT protocol that the press of the button has occurred (connection of DATA and GND). If we hold the button, the information about the press will be repeated after the selected time delay, e.g. after half a second. Sketch of the model house buttons can be found below. The information about the press is captured via MQTT in OpenHAB where the update of the given button in the list according to the specific message of MQTT takes place. In OpenHAB the expiration (automatic shutdown) is set to 1s. The last step is then to set up rule (Rules) that perform the action when the value of the given button is updated - what action to take.

 

Sample sketch

In this simple sketch we are using libraries SPI.h, Ethernet2.h and PubSubClient.h. In the directory for Arduino there must be a Makefile (filename) with the contents below. Here is what libraries we will load and where they are located. You can search for libraries on the internet and download them. Furthermore, in Makefile there is an specification of Arduino, I use a specific name, as Arduino reports on the path /dev/serial/by-id/usb-Arduinoxxxx . Simply go to the folder and try to plug in/disconnect the given Arduino and record what name will appear here. Copy the device name to Makefile. In sketch there are declared variables (pins) on which individual buttons are attached. Pressing the button causes the connection of the Arduino DATA pin with GND and sending MQTT with the information that the button has been pressed. The Item of the given button is updated in OpenHAB and the rule is called if it is defined. The Arduino sketch pattern and an example of the rule for OpenHAB can be found below:

Example "Makefile"

ARDUINO_DIR   = /usr/share/arduino
AVRDUDE_CONF  = /etc/avrdude.conf
MONITOR_PORT = /dev/serial/by-id/usb-Arduino__www.arduino.cc__0042_85036313530351F0E032-if00
<--replace green text with your device name under
USER_LIB_PATH = /usr/share/arduino/libraries/
ARDUINO_LIBS = Ethernet2 SPI pubsubclient
ARDUINO_QUIET = 1
BOARD_TAG = mega
BOARD_SUB = atmega2560
include /usr/share/arduino/Arduino.mk

 

Example sketch "ArduinoPA3.ino"


/*
 Arduino 3 (PA03)
 
  - connects to an MQTT server
  - publishes "hello world" to the topic "pihome"
  - subscribes to the specific topic pihome/xxx
  - sends a specific "on"/"off" to the specific topic when a specific button is pressed
  - multiple arduino's with same generic sketch can run parallel to each other
  - multiple arduino's need each to have a unique ip-addres, unique mac address and unique MQTT client-ID
  - tested on arduino-mega with W5500 ethernet shield
*/

//------------------------------------------------------------------------------

#include <SPI.h>
#include <Ethernet2.h>
#include <PubSubClient.h>

// Set relay variables to Arduino digital pins


// pin 0 RX
// pin 1 TX
// pin 4 (SS for SD Card)
//B111 has underscore because B111 variable already exist in some of the library :D and PIN 5 is not usable as well
int B111_ = 39;
int B112 = 6;
int B121 = 7;
int B122 = 8;
int B131 = 9;
// pin 10 (SS for Ethernet)
int B132 = 11;
int B133 = 12;
int B134 = 13;

int B141 = 2;
int B142 = 3;
int B151 = 14;
int B152 = 15;
int B153 = 16;
int B154 = 17;
int B155 = 18;
int B156 = 19;
// pin 20 SDA
// pin 21 SCL

int B157 = 22;
int B158 = 24;
int B159 = 26;
int B160 = 28;
int B161 = 30;
int B162 = 32;
int B201 = 34;
int B202 = 36;
int B211 = 23;
int B212 = 25;
int B213 = 27;
int B214 = 29;
int B221 = 31;
int B222 = 33;
int B223 = 35;
int B224 = 37;          
int B231 = 38;
int B232 = 40;
int B233 = 42;
int B234 = 44;
int B241 = 46;
int B242 = 47;
int B243 = 48;
int B244 = 49;
     
//int rez = 39;
//int rez = 41;
//int rez = 43;
//int rez = 45;

// pin 50 (SS for Ethernet)
// pin 51 (MOSI)
// pin 52 (MISO)
// pin 53 (SCK)

//A0 (D54)
// int Rez = 54;
// int Rez = 55;
// int Rez = 56;
// int Rez = 57;
// int Rez = 58;
// int Rez = 59;
// pin 60 inaccesibble
// int Rez = 61;

//int rez = 63;
//int rez = 64;
//int rez = 65;
//int rez = 66;
//int rez = 67;
//int rez = 68;
//int rez = 69;
//A15 (D69)

// Set variables to act as virtual switches
// Set variable values initially to LOW (and not HIGH)
// HIGH or LOW as defautl is based on Relay Board               



//---------------------------------------------------------------------------

// Arduino MAC address must be unique for every node in same network
// To make a new unique address change last letter
// Arduino 3
byte mac[]    = { 0xCC, 0xFA, 0x0B, 0xCC, 0x19, 0x01 };  

// Unique static IP address of this Arduino 1
IPAddress ip(10,0,0,173);


// IP Address of your MQTT broker (OpenHAB server)
byte server[] = { 10, 0, 0, 24 };

// Handle and convert incoming MQTT messages ----------------------------------------



void callback(char* topic, byte* payload, unsigned int length) {
  // handle message arrived (no messages expected though)
}
 
 

// Initiate instances -----------------------------------

EthernetClient arduino3;
PubSubClient client(server, 1883, callback, arduino3);




void setup(){
  Ethernet.begin(mac, ip);
  if (client.connect("arduino3", "openhabian", "openhabian")) {
    client.publish("pihome", "Hello world - here Arduino PA03 with IP 10.0.0.173");
  }
      pinMode(B111_,   INPUT);
 digitalWrite(B111_,   HIGH);
      pinMode(B112,   INPUT);
 digitalWrite(B112,   HIGH);
      pinMode(B121,   INPUT);
 digitalWrite(B121,   HIGH);
      pinMode(B122,   INPUT);
 digitalWrite(B122,   HIGH);
      pinMode(B131,   INPUT);
 digitalWrite(B131,   HIGH);
      pinMode(B132,   INPUT);
 digitalWrite(B132,   HIGH);
      pinMode(B133,   INPUT);
 digitalWrite(B133,   HIGH);
      pinMode(B134,   INPUT);
 digitalWrite(B134,   HIGH);
      pinMode(B141,   INPUT);
 digitalWrite(B141,   HIGH);
      pinMode(B142,   INPUT);
 digitalWrite(B142,   HIGH);
      pinMode(B151,   INPUT);
 digitalWrite(B151,   HIGH);
      pinMode(B152,   INPUT);
 digitalWrite(B152,   HIGH);
      pinMode(B153,   INPUT);
 digitalWrite(B153,   HIGH);
      pinMode(B154,   INPUT);
 digitalWrite(B154,   HIGH);
      pinMode(B155,   INPUT);
 digitalWrite(B155,   HIGH);
      pinMode(B156,   INPUT);
 digitalWrite(B156,   HIGH);
      pinMode(B157,   INPUT);
 digitalWrite(B157,   HIGH);
      pinMode(B158,   INPUT);
 digitalWrite(B158,   HIGH);
      pinMode(B159,   INPUT);
 digitalWrite(B159,   HIGH);
      pinMode(B160,   INPUT);
 digitalWrite(B160,   HIGH);
      pinMode(B161,   INPUT);
 digitalWrite(B161,   HIGH);
      pinMode(B162,   INPUT);
 digitalWrite(B162,   HIGH);
      pinMode(B201,   INPUT);
 digitalWrite(B201,   HIGH);
      pinMode(B202,   INPUT);
 digitalWrite(B202,   HIGH);
      pinMode(B211,   INPUT);
 digitalWrite(B211,   HIGH);
      pinMode(B212,   INPUT);
 digitalWrite(B212,   HIGH);
      pinMode(B213,   INPUT);
 digitalWrite(B213,   HIGH);
      pinMode(B214,   INPUT);
 digitalWrite(B214,   HIGH);
      pinMode(B221,   INPUT);
 digitalWrite(B221,   HIGH);
      pinMode(B222,   INPUT);
 digitalWrite(B222,   HIGH);
      pinMode(B223,   INPUT);
 digitalWrite(B223,   HIGH);
      pinMode(B224,   INPUT);
 digitalWrite(B224,   HIGH);
      pinMode(B231,   INPUT);
 digitalWrite(B231,   HIGH);
      pinMode(B232,   INPUT);
 digitalWrite(B232,   HIGH);
      pinMode(B233,   INPUT);
 digitalWrite(B233,   HIGH);
      pinMode(B234,   INPUT);
 digitalWrite(B234,   HIGH);
      pinMode(B241,   INPUT);
 digitalWrite(B241,   HIGH);
      pinMode(B242,   INPUT);
 digitalWrite(B242,   HIGH);
      pinMode(B243,   INPUT);
 digitalWrite(B243,   HIGH);
      pinMode(B244,   INPUT);
 digitalWrite(B244,   HIGH);
 
}


//-----------------------------------------------
long lastReconnectAttempt = 0;

boolean reconnect() {
  if (client.connect("arduino3", "openhabian", "openhabian")) {
    // Once connected, publish an announcement...
    client.publish("pihome","Arduino 3 - reconnected");
    client.subscribe("pihome/heating");
    client.subscribe("pihome/shutters");
  }
  return client.connected();
}
//----------------------------------------------


//Priprava tlacitek
void loop()
{


// read the pushbutton input pin:
if (digitalRead(B111_)==LOW){
   client.publish("pihome/buttons","B111_push");
   delay(50);
  }
if (digitalRead(B112)==LOW){
   client.publish("pihome/buttons","B112_push");
   delay(50);
  }
if (digitalRead(B121)==LOW){
   client.publish("pihome/buttons","B121_push");
   delay(50);
  }
if (digitalRead(B122)==LOW){
   client.publish("pihome/buttons","B122_push");
   delay(50);
  }
if (digitalRead(B131)==LOW){
   client.publish("pihome/buttons","B131_push");
   delay(50);
  }
if (digitalRead(B132)==LOW){
   client.publish("pihome/buttons","B132_push");
   delay(50);
  }
if (digitalRead(B133)==LOW){
   client.publish("pihome/buttons","B133_push");
   delay(50);
  }  
if (digitalRead(B134)==LOW){
   client.publish("pihome/buttons","B134_push");
   delay(50);
  }   
if (digitalRead(B141)==LOW){
   client.publish("pihome/buttons","B141_push");
   delay(50);
  }
if (digitalRead(B142)==LOW){
   client.publish("pihome/buttons","B142_push");
   delay(50);
  }   
if (digitalRead(B151)==LOW){
   client.publish("pihome/buttons","B151_push");
   delay(50);
  }
if (digitalRead(B152)==LOW){
   client.publish("pihome/buttons","B152_push");
   delay(50);
  }
if (digitalRead(B153)==LOW){
   client.publish("pihome/buttons","B153_push");
   delay(50);
  }  
if (digitalRead(B154)==LOW){
   client.publish("pihome/buttons","B154_push");
   delay(50);
  }  
if (digitalRead(B155)==LOW){
   client.publish("pihome/buttons","B155_push");
   delay(50);
  }
if (digitalRead(B156)==LOW){
   client.publish("pihome/buttons","B156_push");
   delay(50);
  }
if (digitalRead(B157)==LOW){
   client.publish("pihome/buttons","B157_push");
   delay(50);
  }  
if (digitalRead(B158)==LOW){
   client.publish("pihome/buttons","B158_push");
   delay(50);
  }
if (digitalRead(B159)==LOW){
   client.publish("pihome/buttons","B159_push");
   delay(50);
  }  
if (digitalRead(B160)==LOW){
   client.publish("pihome/buttons","B160_push");
   delay(50);
  }                
if (digitalRead(B161)==LOW){
   client.publish("pihome/buttons","B161_push");
   delay(50);
  }    
if (digitalRead(B162)==LOW){
   client.publish("pihome/buttons","B162_push");
   delay(50);
  }    
if (digitalRead(B201)==LOW){
   client.publish("pihome/buttons","B201_push");
   delay(50);
  }    
if (digitalRead(B202)==LOW){
   client.publish("pihome/buttons","B202_push");
   delay(50);
  }        
if (digitalRead(B211)==LOW){
   client.publish("pihome/buttons","B211_push");
   delay(50);
  }
if (digitalRead(B212)==LOW){
   client.publish("pihome/buttons","B212_push");
   delay(50);
  }
if (digitalRead(B213)==LOW){
   client.publish("pihome/buttons","B213_push");
   delay(50);
  }  
if (digitalRead(B214)==LOW){
   client.publish("pihome/buttons","B214_push");
   delay(50);
  }  
if (digitalRead(B221)==LOW){
   client.publish("pihome/buttons","B221_push");
   delay(50);
  }
if (digitalRead(B222)==LOW){
   client.publish("pihome/buttons","B222_push");
   delay(50);
  }
if (digitalRead(B223)==LOW){
   client.publish("pihome/buttons","B223_push");
   delay(50);
  }  
if (digitalRead(B224)==LOW){
   client.publish("pihome/buttons","B224_push");
   delay(50);
  }   
if (digitalRead(B231)==LOW){
   client.publish("pihome/buttons","B231_push");
   delay(50);
  }
if (digitalRead(B232)==LOW){
   client.publish("pihome/buttons","B232_push");
   delay(50);
  }
if (digitalRead(B233)==LOW){
   client.publish("pihome/buttons","B233_push");
   delay(50);
  }  
if (digitalRead(B234)==LOW){
   client.publish("pihome/buttons","B234_push");
   delay(50);
  }    
if (digitalRead(B241)==LOW){
   client.publish("pihome/buttons","B241_push");
   delay(50);
  }
if (digitalRead(B242)==LOW){
   client.publish("pihome/buttons","B242_push");
   delay(50);
  }
if (digitalRead(B243)==LOW){
   client.publish("pihome/buttons","B243_push");
   delay(50);
  }  
if (digitalRead(B244)==LOW){
   client.publish("pihome/buttons","B244_push");
   delay(50);
  }                          
  //Wait 50 ms and repeat
  delay(50);
 
  if (!client.connected()) {
    long now = millis();
    if (now - lastReconnectAttempt > 5000) {
      lastReconnectAttempt = now;
      // Attempt to reconnect
      if (reconnect()) {
        lastReconnectAttempt = 0;
      }
    }
  } else {
    // Client connected

    client.loop();
}
 
}
// End of sketch ---------------------------------

OpenHAB

In OpenHAB you should already have the buttons ready according to the tutorial. Try adding a rule. Below is a model rule for the B111 button and the L111 light on/off.

configuration: {}
triggers:
  - id: "2"
    configuration:
      itemName: B111
      state: ON
      previousState: OFF
    type: core.ItemStateChangeTrigger
conditions: []
actions:
  - inputs: {}
    id: "1"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: |2
        
         if(L111.state == ON){   
         sendCommand(L111, OFF)
         }else{
         sendCommand(L111, ON)
         }
    type: script.ScriptAction

 

That's it! Now you can test some buttons. This solution can be extended indefinitely. We have experience with seamless installation of up to 200 buttons in a family home.

Add comment

Nejlepší články z blogu

Tailscale - remote access without public IP
Tailscale - remote access without public IPRating: 
90%

The Tailscale service solves access between individual devices if you don't have a public IP address. It's free for one user with support for up to 100 devices. We'll show you how to install Tailscale on a Raspberry Pi that you'll have at home and on a client (Android, iPhone) from which you'll want to access the home Raspberry Pi. Our example will be remote access to OpenHAB running on a Raspberry Pi. However, the same setup applies to many other applications - home NAS, PiHole, Home Assistant, Domoticz, NextCloud, and others.

Shelly OpenHAB MQTT
Shelly vs OpenHABRating: 
90%

The Shelly brand is known for its products that primarily communicate over WiFi, including smart plugs, relay switches, blinds control relays, and many other devices. One of the advantages for deployment is the ability to both read and control these devices using the universal MQTT protocol. Across existing add-ons for both OpenHAB and Home Assistant, we will demonstrate how to use Shelly devices without installing any additional extensions.

Victron & OpenHAB
Victron vs Smart HomeRating: 
0%

In this post, we will show you how to retrieve information from a photovoltaic power plant by Victron. We will connect to the Cerbo unit via MQTT. Based on these values, we can control various appliances (heating, boiler, etc.) and prevent the battery from being drained when they don't need to be.

Smart Home GoodWe inverter
Smart Home vs GoodWeRating: 
50%

In the post, we will demonstrate step by step how to communicate directly with the GoodWe inverter in a smart home setup and obtain real-time information (unlike the SEMS portal). This information is essential if we want to react to current parameters in a smart home, such as activating additional cooling or controlling a socket with a various load.

Voice control smart home
Voice control of the houseRating: 
60%

In this article, we will connect the Amazon Echo Dot voice assistant with open source home automation. We won't be using OpenHAB Cloud, so everything runs locally. In this case, a few additional settings are necessary, but the result is worth it!

MikroTik - Winbox, DHCP, Ranges
Basics - Winbox, DHCPRating: 
68.8%

In this series, we will look at the step-by-step setup of MikroTik devices for home users or a small business (up to 25 people). In the first article, we will focus on the initial setup - we will download Winbox and set up DHCP for the primary network and guest network. Similarly, we will also adjust the WiFi settings.

Alarm Smart Home PIR
Alarm from existing PIR sensors in a smart home.Rating: 
0%

In a your smart home, PIR sensors may not only be used to switch lights on and off based on motion, it is possible to utilize these sensors to detect the presence of motion in a particular room. This information can be used to create a relatively reliable uncertified home security system. In this guide, you will find the logic for how this can work in the OpenHAB software in our model smart home.

NFC Tag Example in Smart Home
NFC tags in smart homeRating: 
80%

NFC (Near Field Communication) tags are small plastic or paper stickers that can be used to automate various functions in the smart home. In this article, we will show you examples of use and a guide on how to write an action on an NFC tag using a mobile phone.

WireGuard iOS
WireGuard on iOS devicesRating: 
88%

In this article, you will find a detailed guide on how to connect to WireGuard VPN from iOS.

WireGuard on Android device
WireGuard on Android devicesRating: 
80%

In this article, you will find a detailed guide on how to connect to WireGuard VPN from Android.