6. díl - Ovládací tlačítka (vypínače)

V projektu Pi-Home můžete použít jakékoliv standardní tlačítka a vypínače pro 230 V nebo speciální pro 24 V atp. V inteligentních domech se namísto vypínačů (klasické polohy vypnuto/zapnuto) používají designově úplně stejné krytky, akorát mechanizmus je tlačítko (pružinka a po stisku vrácení do původní polohy)  . Důvod je zřejmý, na tlačítko můžeme navázat víc ruzných funkcí a neřešíme stav (opakované stlačení, podržení atd). V naších realizacích máme velmi dobrou zkušenost s klasickými 230V tlačítky od firmy Hager/Berker, ale samozřejmě je možné použít jakékoliv jiné značky.

 

Co budeme potřebovat:

2. díl - OpenHAB na Raspberry Pi

Klasické 230V tlačítka - volba dle designu, aby se vám líbily

Originál Arduino Mega s originál Ethernet 2 Shieldem (DIN držák)

Krone svorky / DIN držák

 

Napájení a propojení

Standardně se k tlačítku tahá UTP kabel. Postačí bohatě CAT5 nebo CAT6. Pro jednotlačítko potřebujeme pouze 2 žíly, pro dvojtlačítko 3 žíly, pro čtyřtlačítko 5 žil. Tam kde tedy bude víc tlačítek lze potáhnout i jeden UTP kabel a zapojit více tlačítek z jednoho kabelu, určitě si ale ponechte rezervu, nikdy nevíte co bude ještě potřeba. Vždy je zapojena země GND a ze všech tlačítek jsou všechny GND pospojované na zemnící KRONE svorce - na obrázku červená svorka (má všechny piny pospojené). Jednotlivé tlačítka jsou pak na klasické bílé KRONE svorce a jednotlivé vývody jsou pak odtud připojené k pinům desky Arduino Mega. Přes KRONE svorku to jde kvůli možnostem změn a lepšímu přehledu. Samozřejmě lze vyvést UTP žíly přímo na pin Arduina, ale může se to stát rigindní a nepřehledné. Na jednu Arduino Mega desku lze zapojit více než 50 jednotlačítek nebo 25 dvoutlačítek atd.

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

 

Software

Cílem je aby nám Arduino poslalo přes MQTT protokol informaci, že došlo ke stisku (spojení PIN a GND). Podržíme-li tlačítko bude se informace o stisku opakovat po zvolené časové prodlevě, např. po  půlsekundě. Sketch zapojení tlačítek modelového domu naleznete níže. Informace o stisku je přes MQTT odchycena v OpenHAB kde dojde k updatu u daného tlačítka v seznamu dle konkrétní zprávy MQTT. V OpenHAB je nastavena expirace (automatické vypnutí) na 1s. Posledním krokem je pak nastavení pravidel (Rules), které provedou akci když dojde k updatu hodnoty u daného tlačítka - jakou akci vyvolat.

Ukázkový sketch

V tomto jednoduchém sketchi jsou použité knihovny SPI.h, Ethernet2.h a PubSubClient.h. V adresáři pro Arduino se musí nacházet Makefile (název souboru) s obsahem níže. Zde je uvedeno, jaké knihovny budeme načítat a kde jsou umístěny. Knihovny můžete vyhledat na internetu a stáhnout. Dále je v Makefile jednoznačná specifikace Arduina, já používám specifický název, jak se Arduino hlásí na cestě /dev/serial/by-id/usb-Arduinoxxxx. Jednoduše jděte do složky a zkuste zapojit/odpojit dané Arduino a zaznamenejte si jaký název se zde objeví. Jmeno zařízení zkopírujte do Makefile. V sketchi jsou pak deklarované proměnné (piny), na kterých jsou připojeny jednotlivé tlačítka. Stisknutí tlačítka vyvolá spojení pinu Arduina s GND a zaslání MQTT s informací, že došlo k stisku. Aktualizuje se Item daného tlačítka v OpenHAB a vyvolá se pravidlo, pokud je definované. Vzor sketche Arduina a příklad pravidla Rule pro OpenHAB naleznete níže:

 

Vzorový "Makefile"

ARDUINO_DIR = /usr/share/arduino
BOARD_TAG    = mega2560
ARDUINO_PORT = /dev/serial/by-id/usb-Arduino__www.arduino.cc__0042_85531303630351119291-if00 (nahraďte vlastním názvem)
USER_LIB_PATH = /usr/share/arduino/libraries
ARDUINO_LIBS = Ethernet2 SPI pubsubclient
include /usr/share/arduino/Arduino.mk

 

Vzorový 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

V OpenHAB by jste již měli dle tutoriálu mít tlačítka připravené. Zkuste si tedy přidat nějaké pravidlo. Níže je vzorové pravidlo pro tlačítko B111 a rosvěcení/zhasnutí světla L111.

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

 

A je to! Teď můžete otestovat nějaké tlačítko. Toto řešení lze neomezeně rozšířit. Máme zkušenosti s bezproblémovou instalaci až s 200 tlačítky v rodinném domě.

 

Tip: Na jednu desku Arduino Mega s Ethernet shieldem se vejde přes 50 tlačítek.

 

Komentáře

Your profile picture

Chtěl bych se zeptat jak dlouhý může být UTP kabel aby Arduino bylo schopné detekovat sepnutí tlačítka ?

Your profile picture

V praxi máme odzkoušeno cca 50m. Zkoušeli jsme to i na 100m novém kotouči a ok. Neteče tam žádný proud, tudíž úbytek napětí zde prakticky není.

Your profile picture

Výborný blog, díky za veškeré info!
Počítá se s tím, že od každého vypínače vedou dvě žíly až k rozvaděči? Není zde nějaká, z pohledu vhodného HW, sběrnicová alternativa? Snadno se totiž mohu dostat do rozložení vypínačů tak, že ke každému budu muset tahat samostatný FTP kabel, ze kterého ale využiji jen 2 žíly. Úspora za elektroinstalaci je pak pryč.
Díky

Your profile picture

Díky za dotaz, chceme právě ponechat možnost používat jakékoliv tlačítka přes všechny výrobce a design, takže alternativa není. Ale z praxe většinou používáme 2 a 4 tlačítka ( použijeme 3 a 5 žil + necháváme rezervu, nikdy nevíte). Když se to natáhne Cat5e tak to není takový ranec. 

Přidat komentář

Nejlepší články z blogu

Linux Live Distribution Persistent USB
Vytvoření Persistent Live USBHodnocení: 
20%

Jak si vyzkoušet Linux? Přímo na vašem notebooku nebo počítači nabootováním z USB flash disku, nebo ještě lépe z externího SSD. Pokud se vám to zalíbí, v tomto návodu naleznete postup, jak vytvořit persistentní live distribuci, což znamená, že všechny změny, které v Linuxu uložíte, tam zůstanou. Můžete si tedy nainstalovat aplikace, ukládat dokumenty atd. Prostě takový přenositelný Linux v kapse, který lze spustit na jakémkoliv podporovaném počítači nebo notebooku.

SmartHome WhatsApp notifikace OpenHAB, Home Assistant
WhatsApp - notifikace zdarmaHodnocení: 
0%

Rádi byste dostávali notifikace z chytré domácnosti formou zpráv do WhatsApp messengeru? Ačkoliv z tohoto messengeru nejsme nadšení, mnoho lidí jej používá a je zbytečné instalovat jiný pouze kvůli chytrému domu. Pro daný kontakt je pak možné nastavit specifické zvonění, takže budete hned vědět, že zpráva přišla z vašeho domu. Našli jsme možnost, jak toto využívat bez poplatku. Jmenuje se CallMeBot...

Tailscale - VPN bez veřejné IP
Tailscale - přístup bez veřejné IP adresyHodnocení: 
100%

Služba Tailscale řeší přístup mezi jednotlivými zařízeními, pokud nemáte možnost veřejné IP adresy. Pro jednoho uživatele je zdarma s podporou max 100 zařízení. Ukážeme si jak Tailscale nainstalovat na Raspberry Pi, které budeme mít někde doma a do klienta (Android, iPhone) ze kterého budeme chtít přistupovat k domácímu Raspberry Pi. Náším příkladem bude vzdálený přístup k OpenHAB běžícím na Raspberry Pi. Nicméně stejné nastavení platí pro spoustu jiných aplikací - domácí NAS, PiHole, Home Assistant, Domoticz, NextCloud a jiné.

Shelly MQTT implementace
Shelly a OpenHABHodnocení: 
100%

Značka Shelly je známa svými produkty komunikujicími hlavně přes WiFi a zahrnujicími ovládané zásuvky, relé pod vypínače, relé pro ovládaní žaluzíí a mnoho dalších produktů. Jedna z výhod pro nasazení je možnost načítat a taky ovládat tyto zařízení pomocí univerzálního protokolu MQTT. Napříč existujícímu addonu pro OpenHAB i Home Assistant si ukážeme jak používat Shelly zařízení bez instalace jakéhokoliv rozšíření.

Victron & OpenHAB
Victron a chytrý důmHodnocení: 
100%

V tomto příspěvku si ukážeme jak načítat informace z fotovoltaické elektrárny od firmy Victron. Propojíme se s jednotkou Cerbo přes MQTT. Na základě těchto hodnot pak můžeme spínat různé spotřebiče (topení, bojler atp.) a předejít plýtvání baterie pro velké spotřebiče v době, kdy nemusí běžet atp.

GoodWe a chytrá domácnost
Smart Home a GoodWeHodnocení: 
100%

V příspěvku ukážeme krok po kroku jak komunikovat chytrou domácnosti přímo se střídačem Goodwe a dostávát aktuální informace (narozdíl od SEMS portálu). Tyto informace jsou nezbytné pokud chceme v chytrém domě nějak reagovat na aktuální parametry např. spínání dodatečného chlazení nebo spínání zásuvky se zátěží.

Ovládání domu hlasem
Hlasové ovládání domu AlexouHodnocení: 
100%

V tomto článku propojíme hlasového asistenta Amazon Echo Dot s open source domácí automatizací. Nepoužíváme OpenHAB Cloud, tz. vše běží lokálně. V tomto případě je nutných pár nastavení navíc, nicméně výsledek stojí za to!

NFC Tag Chytrý dům
NFC tagy v chytrém doměHodnocení: 
100%

NFC (Near Field Communication) tagy jsou malé plastové nebo papírové nálepky, které mohou být použity k automatizaci různých funkcí v domácnosti. V čláku vám ukážeme příklady použití a návod jak zapsat akci na NFC tag pomocí mobilního telefonu.

WireGuard iOS
Nastavení WireGuard připojení v iOSHodnocení: 
0%

V tomto článku najdete podrobný návod, jak se připojit k WireGuard VPN z iOS.

WireGuard z Androidu
Nastavení WireGuard připojení v AndroiduHodnocení: 
100%

V tomto článku najdete podrobný návod, jak se připojit k WireGuard VPN z Androidu.