OpenHABs Wireless Home Air Conditioner Controller ĂĽber Modbus ĂĽber RF24Network


Nach meinem ersten Artikel über die Steuerung der Klimaanlage mit einer Steuerung vergingen etwas mehr als zwei Jahre. Während dieser Zeit verließ mich die Idee, die Klimaanlage fernzusteuern, nicht und hatte mehrere Wiedergeburten. Die Hauptbedingung war das Fehlen von Kabeln zur Klimaanlage.

Das heiĂźt, die Steuerung des Controllers muss drahtlos sein.

Hintergrund


Der erste Prototyp war der Arduino UNO. Sie akzeptierte Teams auf UART und wusste, wie man die Klimaanlage ein- und ausschaltet. weil Die an den funktionierenden Computer angeschlossene Arduinka hatte wenig praktischen Sinn. Der Kopf suchte ständig nach der Möglichkeit, diese mit dem Heimserver zu verbinden. Es gab keine direkte Sicht vom Server auf den Schuldigen aller Rätsel. Das Maximum ist eine Steckdose mit einem LAN auf demselben funktionierenden Computer - da sie fast gegenüber der Klimaanlage steht. Ein Ethernet-Shield war nicht verfügbar. Aber denken Sie daran, dass irgendwo in der Zashashnik ein DSL-2500U-DSL-Modem mit D-Link liegt, das seit langem nicht mehr verwendet wird und nur einen Port an Bord hat. Der Wunsch, dem Stück Eisen ein zweites Leben zu geben, führte zu Googeln, was wiederum auf wundersame Weise zu dem Artikel führte, ein ADSL-Modem in ein Ethernet-Shield für Arduino / CraftDuino zu verwandeln .

Ich sprang voran und übersprang den interessantesten Prozess zum Erstellen einer benutzerdefinierten Firmware. Trotzdem gelang es mir, das Modem dazu zu bringen, den gewünschten Port abzuhören und den UART durch diesen weiterzuleiten. Auf dem Heimserver könnte ich also einen Befehl zum Ein- und Ausschalten des Ports an die lokale Modemadresse senden, die an das mit ihm verbundene Arduino geht.

Aber in diesem Artikel geht es nicht darum. Die ultimative Lösung verwendet das Modbus-Protokoll und das drahtlose RF24Network- Netzwerk . Und alles wird in OpenHAB gesteuert.


Während dieser zwei Jahre konnte ich viele Nishtyaks aus China bestellen und die meisten warteten in den Startlöchern. Diese Liste enthielt das NRF24L01 + -Modul, das von einer Handvoll zum Experimentieren gekauft wurde. Und er wäre irgendwo im Leerlauf weiter gegangen, wenn ich eines Tages nicht auf eine Reihe von Artikeln gestoßen wäre:

von BorichDanke fĂĽr das!

Dank ihnen habe ich das Modbus-Protokoll kennengelernt. Vor allem aber habe ich OpenHAB für mich entdeckt - was ich schon lange gesucht habe. Dies veranlasste mich, langjährige Ideen umzusetzen.

Nachdem ich mit Beispielen aus den Artikeln herumgespielt hatte, beschloss ich, den Controller und den Server mithilfe des Ethernet-Shields vom oben beschriebenen Modem zu trennen. Diese Lösung ermöglichte es uns, die gestellte Aufgabe zu erfüllen - das Schild und der Controller befanden sich auf dem Desktop, ohne einen funktionierenden Computer zu verwenden. Gleichzeitig ist das Schild immer mit dem lokalen Netzwerk verbunden und vom Heimserver aus zugänglich.

Aber diese Entscheidung war zum Scheitern verurteilt.
ModbusRtu over TCP . modpoll, Arduino & Modbus . — 192.168.1.110 3000 !

OpenHAB. , , Modbus Binding «RTU over TCP». — ModbusRtu c TCP. OpenHAB-(ethernet)--(UART)-.

, ? Item . 1 Item . — . , , TCP Modbus Binding. .. .

Modbus Binding Item' host-port-slaveID .

, . . , .


Idee


Und dann habe ich endlich festgestellt, dass ich einen Controller machen muss, der auf dem Luftweg zugänglich ist. Die NRF24L01 + -Module sollten nicht verschwinden! .. Richtig, dies erforderte mindestens zwei Controller - einer spielt eine direkte Rolle, der zweite spielt die Rolle eines Routers. Der zweite sollte mit dem Server verbunden sein und über diesen wird die drahtlose Kommunikation mit den anderen ausgeführt. Bei der Verbindung geben wir die ID des Untergebenen an, für den das Paket bestimmt ist. Es stellt sich heraus, dass viele Slaves an einer seriellen Schnittstelle verfügbar sind. Ja, dies ist ein Modbus-basiertes drahtloses Netzwerk.

Modbus ermöglichte es übrigens, ein Netzwerk mit einem Master aufzubauen - vielen Untergebenen. Und die RF24Network- Bibliothek - um alles drahtlos zu machen und sogar mit automatischem Routing zwischen Netzwerkknoten.

Bibliotheksentwicklung fĂĽr Arduino


Um eine solche Lösung zu implementieren, war es ziemlich lang, die Modbus-Master-Slave-for-Arduino- Bibliothek so zu ändern , dass sie von ihr erben und einige Methoden überladen konnte. Meine Implementierung wurde auch für die neueste Arduino IDE 1.6.5 aktualisiert (library.properties wird hinzugefügt, die Bibliotheksdatei ist in Header und Body unterteilt).

Mit der Modbus-over-RF24Network-for-Arduino- Bibliothek können Sie zwei mögliche Verhaltensweisen implementieren - Proxy und Slave. Beispiel ModbusRF24Proxy ist eigentlich eine Implementierung eines „Routers“ und erfordert keine anderen Modifikationen als das Setzen der erforderlichen Pins.
Modbus ExampleRF24Proxy
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <ModbusRtu.h>
#include <ModbusRtuRF24.h>

#define stlPin  13  //     (   Arduino)

// nRF24L01(+) radio attached using Getting Started board 
RF24 radio(9, 10);

// Network uses that radio
RF24Network network(radio);

// Address of our node
const uint16_t this_node = 0;

//  ,   TX
ModbusRF24 proxy(network, 0, 0);
int8_t state = 0;
unsigned long tempus;

void setup() {
    //    
    io_setup();
    //    

    proxy.begin(57600);

    SPI.begin();
    radio.begin();
    network.begin(/*channel*/ 90, /*node address*/ this_node);

    //    100 
    tempus = millis() + 100;
    digitalWrite(stlPin, HIGH);
}

void io_setup() {
    digitalWrite(stlPin, HIGH);
    pinMode(stlPin, OUTPUT);
}

void loop() {

    // Pump the network regularly
    network.update();

    //  
    state = proxy.proxy();

    //      -    50  
    if (state > 4) {
        tempus = millis() + 50;
        digitalWrite(stlPin, HIGH);
    }
    if (millis() > tempus) digitalWrite(stlPin, LOW);
}


Ein Router oder Proxy verwendet ein spezielles Konstruktorformat:
//  ,   TX
ModbusRF24 proxy(network, 0, 0);

und Funktion
proxy.proxy();

Um eingehende Pakete an der seriellen Schnittstelle zu verarbeiten, senden Sie sie an das RF24-Netzwerk, empfangen Sie eine Antwort vom Netzwerk und senden Sie das Ergebnis an die serielle Schnittstelle zurĂĽck.

In dieser Implementierung hat der Proxy eine RF24Network-Adresse von Null:
// Address of our node
const uint16_t this_node = 0;

- d.h. Dies ist das Root-Gerät des Netzwerks. Bei Bedarf kann die Position in der Topologie des Proxy-Controllers geändert werden.

Modbus Beispiel RF24Slave
Arduino & Modbus:
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <ModbusRtu.h>
#include <ModbusRtuRF24.h>

#define ID   1      //  
#define btnPin  2   //  ,   
#define ledPin  7  //   

// nRF24L01(+) radio attached using Getting Started board 
RF24 radio(9, 10);

// Network uses that radio
RF24Network network(radio);

// Address of our node
const uint16_t this_node = ID;

//  
ModbusRF24 slave(network, ID);

//   modbus
uint16_t au16data[11];

void io_setup() {
    digitalWrite(ledPin, LOW);
    pinMode(ledPin, OUTPUT);
    pinMode(btnPin, INPUT);
}

void io_poll() {
    // Coil[1]  Discrete[0]
    au16data[0] = au16data[1];
    //   1.3   
    digitalWrite(ledPin, bitRead(au16data[1], 3));
    //     0.3
    bitWrite(au16data[0], 3, digitalRead(btnPin));
    // Holding[5,6,7]  Input[2,3,4]
    au16data[2] = au16data[5];
    au16data[3] = au16data[6];
    au16data[4] = au16data[7];
    //    
    au16data[8] = slave.getInCnt();
    au16data[9] = slave.getOutCnt();
    au16data[10] = slave.getErrCnt();
}

void setup() {
    //    
    io_setup();

    Serial.begin(57600);
    Serial.println("RF24Network/examples/modbus_slave/");

    SPI.begin();
    radio.begin();
    network.begin(/*channel*/ 90, /*node address*/ this_node);
}

void loop() {

    // Pump the network regularly
    network.update();

    if (network.available()) {
        slave.poll(au16data, 11);
    }
    //    Modbus    
    io_poll();
}



Der Konstruktor ist in diesem Fall bereits anders:
//  
ModbusRF24 slave(network, ID);


Modbus-Registerstruktur


Nach den ersten erfolgreichen Versuchen, die Klimaanlage mit der Fähigkeit zu steuern, nur ein- und auszuschalten, nahm mein Appetit nur zu. Dies war jetzt noch nicht genug, und da ich OpenHAB-Funktionalität in meiner mobilen Anwendung habe, sollte mindestens die gesamte Funktionalität des nativen Control Panels ausgeführt werden.
Dies bedeutet, dass hier mindestens eine Liste von Funktionen aufgefĂĽhrt ist:
  • Anzeige des aktuellen Status
  • Ein- und Ausschalten der Klimaanlage, einzelne Modi (O 2 , Ionisation, Silent Mode);
  • Auswahl des aktuellen Modus (Auto, Heizung, KĂĽhlung, Entwässerung, LĂĽfter);
  • Anzeige von Temperatur und LĂĽfterdrehzahl fĂĽr jeden Modus. FĂĽr den LĂĽftermodus nur Geschwindigkeit;
  • vertikale Vorhangeinstellung (automatisch, 0 °, 15 °, 30 °, 45 °, 60 °);
  • horizontale Vorhangeinstellung (automatisch, "| |", "/ /", "/ |", "|", "");
  • Zeiteinstellung (Stunde, Minute);
  • auf Timer-Einstellung;
  • Aus-Timer-Einstellung;
  • PĂĽnktliche Einstellung (Stunde, Minute);
  • Einstellung der Abschaltzeit (Stunde, Minute);

Während des Entwicklungsprozesses hat sich die Struktur der Register bei mir oft geändert. Die aktuelle Version befindet sich unten unter dem Spoiler.
Modbus-Register
TypeByteBitName
Bit RO00CFG_OXYGEN1 —
Bit RO1CFG_ION1 —
Bit RO2CFG_QUIET1 —
Bit RO3CFG_TIMER1 — /
Bit RO4CFG_DELAY1 — /
Bit RO5CFG_SWING1 —
Bit RO6CFG_SWINGH1 —
Bit RO7CFG_SWINGV1 —
Bit RO8CFG_CLOCK1 —
Bit RO9
Bit RO10
Bit RO11CFG_AUTO1 — AUTO
Bit RO12CFG_COOL1 — COOL
Bit RO13CFG_HEAT1 — HEAT
Bit RO14CFG_DRY1 — DRY
Bit RO15CFG_FAN1 — FAN
Integer RO1CFG_TEMP. . : Min + Max*256
Integer RO2CFG_FAN_SPEEDFAN
Bit RO30STATE_POWER:0 — , 1 —
Bit RO1STATE_OXYGEN:0 — , 1 —
Bit RO2STATE_ION:0 — , 1 —
Bit RO3STATE_QUIET:0 — , 1 —
Bit RO4STATE_TIMER:0 — , 1 —
Bit RW8CONTROL_POWER
Bit RW9CONTROL_OXYGEN
Bit RW10CONTROL_ION
Bit RW11CONTROL_QUIET
Integer RO4RTC_HR_MI0x1308
Integer RW5RTCW_HR_MI0x1308
Integer RO6TEMPERATURE1. INT16,
Integer RO7TEMPERATURE2. INT16,
Bit RW80MODE_AUTO
Bit RW1MODE_COOL
Bit RW2MODE_HEAT
Bit RW3MODE_DRY
Bit RW4MODE_FAN
Integer RW9TEMP_AUTOAUTO
Integer RW10TEMP_COOLCOOL
Integer RW11TEMP_HEATHEAT
Integer RW12TEMP_DRYDRY
Integer RW13FAN_AUTOAUTO. 0: Auto
Integer RW14FAN_COOLCOOL. 0: Auto
Integer RW15FAN_HEATHEAT. 0: Auto
Integer RW16FAN_DRYDRY. 0: Auto
Integer RW17FAN_SPEEDFAN. 0: Auto
Bit RW180SWING_AUTO
Bit RW1SWINGV_00°
Bit RW2SWINGV_1515°
Bit RW3SWINGV_3030°
Bit RW4SWINGV_4545°
Bit RW5SWINGV_6060°
Bit RW190SWINGH_AUTO
Bit RW1SWINGH_VV|  |
Bit RW2SWINGH_LL/  /
Bit RW3SWINGH_LV/  |
Bit RW4SWINGH_VR|  \
Bit RW5SWINGH_RR\  \
Bit RW200TIMER_ON
Bit RW1TIMER_OFF
Integer RW21TIME_ON_HOUR
Integer RW22TIME_ON_MINUTE
Integer RW23TIME_OFF_HOUR
Integer RW24TIME_OFF_MINUTE
Integer RW25DS18B20_ENV.
Integer RW26DS18B20_NOZ.


Die Register sind so organisiert, dass das gesamte Datenarray beim Start der Steuerung vom EEPROM aus initialisiert wird.
Die ersten 3 Register (CFG_ *) enthalten die Konfiguration von Funktionen, sie ändern sich nie und werden von der EEPROM-Firmware initialisiert.
Die Register 3-7 zeigen immer den aktuellen Status der Steuerung an. Die hohen Bits von Register 3 werden verwendet, um den Zustand zu ändern. Ihre Änderungen lösen das Ein- und Ausschalten der Klimaanlage und spezielle Modi aus. Nachdem der Befehl ausgeführt wurde, werden die niederwertigen Bits dieses Registers in die höherwertigen kopiert.
Register 4 enthält die aktuelle Reglerzeit, die aus der RTC gelesen wird. Der Wert wird im BCD-Format gespeichert, sodass bei Anzeige des Registers in hexadezimaler Schreibweise die Zeit unverändert gelesen wird - 12:34 ist 0x1234.
Register 5 wird verwendet, um die RTC-Zeit zu ändern.
Die Register 6-7 enthalten die Temperatur der DS18B20-Sensoren. Der Wert enthält eine vorzeichenbehaftete ganze Zahl und ist gleich T * 100, d.h. 25,67 ° C = 2567. Es sind maximal 2 Sensoren vorgesehen, die Anzahl kann jedoch leicht geändert werden, indem die Registertabelle erweitert wird, um die Sensoradressen und ihre Temperaturen zu speichern.
Die letzten 2 Bytes der Sensoradresse werden in den Registern 25-26 gespeichert. Setzen Sie beim Sensorwechsel das entsprechende Adressregister zurück. Wenn ein neuer Sensor erkannt wird, wird seine Adresse in den Registern 25-26 auf Vorhandensein überprüft. Befindet sich die Adresse in der Tabelle, wird der Temperaturwert des Sensors in das entsprechende Register 6-7 eingetragen. Wenn die Adresse nicht in der Tabelle enthalten ist und die Tabelle keine Zellen enthält, wird die aktuelle Sensoradresse in eine freie Zelle geschrieben.
Die vom Benutzer geänderten Register 8-26 werden im EEPROM gespeichert.

DrĂĽsen


Die Hardware besteht aus folgenden Komponenten:
  1. Arduino Pro Mini.
    Arduino Pro Mini NEW
  2. NRF24L01+ — 2.4
  3. LM1117-3.3 — 3.3 NRF24L01+
  4. DS1302 — RTC
  5. 32768 RTC
  6. DS18B20 — . 2
  7. — , ,











Die Rückmeldung an die Klimaanlage erfolgt durch Anschluss von Optokopplern an die entsprechenden LEDs. Somit ist eine galvanische Trennung mit dem Stromkreis der Klimaanlage gewährleistet. Der Strom der Eingänge für die Optokoppler wurde experimentell unter Verwendung von Widerständen so ausgewählt, dass der Ausgang des Optokopplers öffnet und die Helligkeit der Haupt-LED an der Klimaanlage nicht abfällt.

Neben dem IR-Empfänger der Klimaanlage wurde eine IR-LED installiert.

Der Controller wird durch Mini-USB-Aufladung mit einem chinesischen Wunder betrieben. Chinesische Netzspannungskontakte wurden aus dem Ladegehäuse entfernt, Drähte wurden entfernt. Die Aufladung selbst hat sich im Darm des Klimakastens niedergelassen und ist parallel dazu mit dem Eingang 220 verbunden. Der Controller wird über ein normales USB-AB-Kabel mit dem Laden verbunden.

Der Router-Controller basiert auf dem Arduino Mega2560 und NRF24L01 + mit einem separaten LM1117-3.3. Zusätzlich zu einem separaten 3,3-Netzteil ist ein Elektrolyt an das Funkmodul (ich fand es bei 470uf * 16 V) an den Leistungsbeinen angeschlossen. Wie Sie wissen, ist der interne Mega2560 3,3-V-Energiebus sehr verrauscht und das Modul hat sich geweigert, Daten zu übertragen, obwohl es richtig geantwortet hat. Aber auch mit einem separaten Netzteil ohne Kondensator war die Verbindung sehr instabil.
Damit der Mega2560 beim Ă–ffnen des Anschlusses ĂĽber USB nicht zurĂĽckgesetzt wird, wird ein 10ÎĽf Elektrolyt an den Reset-Pin angeschlossen.

Openhab


Der Artikel von Arduino & OpenHAB beschreibt eine Funktion des Modbus Binding-Plug-Ins, bei der das Plug-In bei jeder Abfrage des Controllers ein Ereignis an den Bus sendet, auch wenn sich nichts geändert hat. Ich folgte dem Beispiel und stellte das Plugin fertig.

Konfiguration des Modbus-Bindungs-Plugins
#
modbus:serial.ac_hall_state.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_state.id=1
modbus:serial.ac_hall_state.start=48
modbus:serial.ac_hall_state.length=5
modbus:serial.ac_hall_state.type=discrete

#
modbus:serial.ac_hall_power.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_power.id=1
modbus:serial.ac_hall_power.start=56
modbus:serial.ac_hall_power.length=4
modbus:serial.ac_hall_power.type=coil

#
modbus:serial.ac_hall_rtc.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_rtc.id=1
modbus:serial.ac_hall_rtc.start=4
modbus:serial.ac_hall_rtc.length=1
modbus:serial.ac_hall_rtc.type=holding

#
modbus:serial.ac_hall_temperature.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_temperature.id=1
modbus:serial.ac_hall_temperature.start=6
modbus:serial.ac_hall_temperature.length=2
modbus:serial.ac_hall_temperature.type=holding
modbus:serial.ac_hall_temperature.valuetype=int16

#
modbus:serial.ac_hall_mode.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_mode.id=1
modbus:serial.ac_hall_mode.start=8
modbus:serial.ac_hall_mode.length=1
modbus:serial.ac_hall_mode.type=holding

#
modbus:serial.ac_hall_temp.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_temp.id=1
modbus:serial.ac_hall_temp.start=9
modbus:serial.ac_hall_temp.length=4
modbus:serial.ac_hall_temp.type=holding

#
modbus:serial.ac_hall_fan.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_fan.id=1
modbus:serial.ac_hall_fan.start=13
modbus:serial.ac_hall_fan.length=5
modbus:serial.ac_hall_fan.type=holding

#
modbus:serial.ac_hall_swing.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_swing.id=1
modbus:serial.ac_hall_swing.start=18
modbus:serial.ac_hall_swing.length=2
modbus:serial.ac_hall_swing.type=holding

#
modbus:serial.ac_hall_timer.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_timer.id=1
modbus:serial.ac_hall_timer.start=320
modbus:serial.ac_hall_timer.length=2
modbus:serial.ac_hall_timer.type=coil

#
modbus:serial.ac_hall_timer_time.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_timer_time.id=1
modbus:serial.ac_hall_timer_time.start=21
modbus:serial.ac_hall_timer_time.length=4
modbus:serial.ac_hall_timer_time.type=holding

# DS18B20
modbus:serial.ac_hall_ds18b20.connection=/dev/ttyACM0:57600:8:none:1:rtu
modbus:serial.ac_hall_ds18b20.id=1
modbus:serial.ac_hall_ds18b20.start=25
modbus:serial.ac_hall_ds18b20.length=2
modbus:serial.ac_hall_ds18b20.type=holding

Elementeinstellungen
Contact AC_HALL_STATE_POWER             "AC_HALL_STATE_POWER [MAP(air_cond.map):%s]"    (){modbus="ac_hall_state:0"}
Contact AC_HALL_STATE_OXYGEN            "AC_HALL_STATE_OXYGEN [MAP(air_cond.map):%s]"   (){modbus="ac_hall_state:1"}
Contact AC_HALL_STATE_ION               "AC_HALL_STATE_ION [MAP(air_cond.map):%s]"      (){modbus="ac_hall_state:2"}
Contact AC_HALL_STATE_QUIET             "AC_HALL_STATE_QUIET [MAP(air_cond.map):%s]"    (){modbus="ac_hall_state:3"}
Contact AC_HALL_STATE_TIMER             "[MAP(air_cond.map):%s]"                  (){modbus="ac_hall_state:4"}

Switch  AC_HALL_CONTROL_POWER           ""                   <climate>       (){modbus="ac_hall_power:0"}
Switch  AC_HALL_CONTROL_OXYGEN          " O2"                                  (){modbus="ac_hall_power:1"}
Switch  AC_HALL_CONTROL_ION             ""                                     (){modbus="ac_hall_power:2"}
Switch  AC_HALL_CONTROL_QUIET           " "                                   (){modbus="ac_hall_power:3"}

Number  AC_HALL_RTC                     "RTC[%x]"                                       (){modbus="ac_hall_rtc:0"}
String  AC_HALL_RTC_S                   " [%s]"         <clock>         ()

Group   gAC_HALL_TEMPERATURE            "Living Room temp"

Number  AC_HALL_TEMPERATURE_ENV         "[%d]"                                   (){modbus="ac_hall_temperature:0"}
Number  AC_HALL_TEMPERATURE_NOZ         "[%d]"                                     (){modbus="ac_hall_temperature:1"}
Number  AC_HALL_TEMPERATURE_ENVF        " [%.2f °C]"     <temperature>           (gAC_HALL_TEMPERATURE)
Number  AC_HALL_TEMPERATURE_NOZF        " [%.2f °C]"       <temperature>           (gAC_HALL_TEMPERATURE)

Number  AC_HALL_DS18B20_ENV             "ENV[%x]"                                       (){modbus="ac_hall_ds18b20:0"}
Number  AC_HALL_DS18B20_NOZ             "NOZZLES[%x]"                                   (){modbus="ac_hall_ds18b20:1"}

Number  AC_HALL_MODE                    ""                                              (){modbus="ac_hall_mode:0"}

Number  AC_HALL_TEMP_AUTO               "[%d °C]"    <temperature>           (){modbus="ac_hall_temp:0"}
Number  AC_HALL_TEMP_COOL               "[%d °C]"    <temperature>           (){modbus="ac_hall_temp:1"}
Number  AC_HALL_TEMP_HEAT               "[%d °C]"    <temperature>           (){modbus="ac_hall_temp:2"}
Number  AC_HALL_TEMP_DRY                "[%d °C]"    <temperature>           (){modbus="ac_hall_temp:3"}

Number  AC_HALL_FAN_AUTO                "[%d]"                                  (){modbus="ac_hall_fan:0"}
Number  AC_HALL_FAN_COOL                "[%d]"                                  (){modbus="ac_hall_fan:1"}
Number  AC_HALL_FAN_HEAT                "[%d]"                                  (){modbus="ac_hall_fan:2"}
Number  AC_HALL_FAN_DRY                 "[%d]"                                  (){modbus="ac_hall_fan:3"}
Number  AC_HALL_FAN_SPEED               "[%d]"                                  (){modbus="ac_hall_fan:4"}

Number  AC_HALL_SWINGV                  ""                                              (){modbus="ac_hall_swing:0"}
Number  AC_HALL_SWINGH                  ""                                              (){modbus="ac_hall_swing:1"}

Switch  AC_HALL_TIMER_ON                " "              <clock>         (){modbus="ac_hall_timer:0"}
Switch  AC_HALL_TIMER_OFF               " "             <clock>         (){modbus="ac_hall_timer:1"}

Number  AC_HALL_TIME_ON_HR              "[%02d]"                                     (){modbus="ac_hall_timer_time:0"}
Number  AC_HALL_TIME_ON_MI              "[%02d]"                                  (){modbus="ac_hall_timer_time:1"}
Number  AC_HALL_TIME_OFF_HR             "[%02d]"                                     (){modbus="ac_hall_timer_time:2"}
Number  AC_HALL_TIME_OFF_MI             "[%02d]"                                  (){modbus="ac_hall_timer_time:3"}


Regeln werden verwendet, um ganzzahlige Temperaturen in reale zu konvertieren und die Reglerzeit in die Form HH: MM zu formatieren.
Regeleinstellungen
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import java.io.File

rule "Update AC_HALL ENV temp"
        when
                Item AC_HALL_TEMPERATURE_ENV received update
        then
                var Number T = AC_HALL_TEMPERATURE_ENV.state as DecimalType
                var Number H = T/100
                postUpdate(AC_HALL_TEMPERATURE_ENVF, H)
end
rule "Update AC_HALL NOZZLES temp"
        when
                Item AC_HALL_TEMPERATURE_NOZ received update
        then
                var Number T = AC_HALL_TEMPERATURE_NOZ.state as DecimalType
                var Number H = T/100
                postUpdate(AC_HALL_TEMPERATURE_NOZF, H)
end
rule "Update AC_HALL_RTC clock"
        when
                Item AC_HALL_RTC received update
        then
                var Number T = AC_HALL_RTC.state as DecimalType
                var H = T.intValue / 256
                var M = T.intValue % 256
                var S = String::format("%02x:%02x",H,M)
                postUpdate(AC_HALL_RTC_S, S)
end


Sitemaps-Einstellungen
sitemap demo label="Demo House"{
        Frame label="HOME"{
                Text label=" " icon="ac_cond"{
                        Frame label="" {
                                Switch item= AC_HALL_CONTROL_POWER labelcolor=[AC_HALL_STATE_POWER==OPEN="blue"]
                                Switch item= AC_HALL_CONTROL_OXYGEN labelcolor=[AC_HALL_STATE_OXYGEN==OPEN="blue"]
                                Switch item= AC_HALL_CONTROL_ION labelcolor=[AC_HALL_STATE_ION==OPEN="blue"]
                                Switch item= AC_HALL_CONTROL_QUIET labelcolor=[AC_HALL_STATE_QUIET==OPEN="blue"]
                                Text item=AC_HALL_STATE_TIMER labelcolor=[AC_HALL_STATE_TIMER==OPEN="blue"] icon="clock-on"
                                Text item=AC_HALL_RTC_S
                                Text item=AC_HALL_TEMPERATURE_ENVF
                                Text item=AC_HALL_TEMPERATURE_NOZF
                        }

                        Frame label=""{
                                Selection item=AC_HALL_MODE label="" mappings=[1=AUTO, 2=COOL, 4=HEAT, 8=DRY, 16=FAN]
                                Text item=AC_HALL_TEMP_AUTO visibility=[AC_HALL_MODE==1]
                                Text item=AC_HALL_TEMP_COOL visibility=[AC_HALL_MODE==2]
                                Text item=AC_HALL_TEMP_HEAT visibility=[AC_HALL_MODE==4]
                                Text item=AC_HALL_TEMP_DRY visibility=[AC_HALL_MODE==8]

                                Text item=AC_HALL_FAN_AUTO visibility=[AC_HALL_MODE==1]
                                Text item=AC_HALL_FAN_COOL visibility=[AC_HALL_MODE==2]
                                Text item=AC_HALL_FAN_HEAT visibility=[AC_HALL_MODE==4]
                                Text item=AC_HALL_FAN_DRY visibility=[AC_HALL_MODE==8]
                                Text item=AC_HALL_FAN_SPEED visibility=[AC_HALL_MODE==16]

                                Selection item=AC_HALL_SWINGV label="" mappings=[1=AUTO, 2="0°", 4="15°", 8="30°", 16="45°", 32="60°"]
                                Selection item=AC_HALL_SWINGH label="" mappings=[1=AUTO, 4="/   /", 8="/   |", 2="|   |", 16="|   \\", 32="\\   \\"]

                                Text label="" icon="settings"{
                                        Frame label="AUTO"{
                                                Setpoint item=AC_HALL_TEMP_AUTO minValue=16 maxValue=30 step=1
                                                Switch   item=AC_HALL_FAN_AUTO mappings=[0=AUTO, 1="1", 2="2", 3="3", 4="4", 5="5"]
                                        }
                                        Frame label="COOL"{
                                                Setpoint item=AC_HALL_TEMP_COOL minValue=16 maxValue=30 step=1
                                                Switch   item=AC_HALL_FAN_COOL mappings=[0=AUTO, 1="1", 2="2", 3="3", 4="4", 5="5"]
                                        }
                                        Frame label="HEAT"{
                                                Setpoint item=AC_HALL_TEMP_HEAT minValue=16 maxValue=30 step=1
                                                Switch   item=AC_HALL_FAN_HEAT mappings=[0=AUTO, 1="1", 2="2", 3="3", 4="4", 5="5"]
                                        }
                                        Frame label="DRY"{
                                                Setpoint item=AC_HALL_TEMP_DRY minValue=16 maxValue=30 step=1
                                                Switch   item=AC_HALL_FAN_DRY mappings=[0=AUTO, 1="1", 2="2", 3="3", 4="4", 5="5"]
                                        }
                                        Frame label="FAN"{
                                                Switch item=AC_HALL_FAN_SPEED mappings=[0=AUTO, 1="1", 2="2", 3="3", 4="4", 5="5"]
                                        }
                                        Frame label=""{
                                                Text item=AC_HALL_DS18B20_ENV
                                                Text item=AC_HALL_DS18B20_NOZ
                                        }
                                }
                        }
                        Frame label="" {
                                Switch item= AC_HALL_TIMER_ON labelcolor=[AC_HALL_STATE_TIMER==OPEN="blue"]
                                Setpoint item=AC_HALL_TIME_ON_HR minValue=0 maxValue=23 step=1
                                Setpoint item=AC_HALL_TIME_ON_MI minValue=0 maxValue=50 step=5

                                Switch item= AC_HALL_TIMER_OFF labelcolor=[AC_HALL_STATE_TIMER==OPEN="blue"]
                                Setpoint item=AC_HALL_TIME_OFF_HR minValue=0 maxValue=23 step=1
                                Setpoint item=AC_HALL_TIME_OFF_MI minValue=0 maxValue=50 step=5
                        }
                }
                Text item=AC_HALL_RTC_S
                Text item=AC_HALL_TEMPERATURE_ENVF{
                        Frame label=" "{
                                Chart item=gAC_HALL_TEMPERATURE period=h refresh=60000
                        }
                        Frame label=" 4 " {
                                Chart item=gAC_HALL_TEMPERATURE period=4h refresh=600000
                        }
                }
        }
}



Das Ergebnis sieht über einen Browser ungefähr so ​​aus:

Fazit


Ich bin mit dem Ergebnis als Elefant zufrieden. Die Steuerung der Klimaanlage steht mir jetzt ĂĽberall dort zur VerfĂĽgung, wo es mobiles Internet oder WLAN gibt. Mit einem VPN-Client auf einem Smartphone kann ich auf OpenHAB auf meinem Heimserver sowohl ĂĽber den Browser als auch ĂĽber die mobile Anwendung zugreifen.
Die drahtlose Lösung ermöglichte die enge Integration der Steuerung in die Klimaanlage.
Das Vorhandensein von Rückmeldungen gibt die Gewissheit, dass der gesendete Befehl von der Klimaanlage empfangen wurde, und die Temperatursensoren zeigen dies deutlich - nach einigen Sekunden können Sie eine Änderung des Temperaturmesswerts am Ausgang der Klimaanlage beobachten. Nun, nach ein paar Minuten - und der Umgebungstemperatur.
Es war interessant, das Profil der Klimaanlage zu beobachten, wenn man sich den gegebenen Bedingungen nähert.

Zweifellos wird dies nicht der einzige drahtlose Controller sein, den ich verwenden möchte.

Es ist geplant, den IR-Empfänger der Klimaanlage selbst zu verwenden, um die Befehle der nativen Fernbedienung zu lesen und die Einstellungen in der Steuerung zu aktualisieren. Darüber hinaus ist der IR-Empfänger selbst bereits über einen Optokoppler mit der Steuerung verbunden.

Lesen Sie bis zum Ende ein besonderes Dankeschön!

Verweise


  1. Arduino-Bibliothek ModbusRtu Modbus-Master-Slave-fĂĽr-Arduino
  2. Arduino-Bibliothek ModbusRtuRF24 Modbus-over-RF24-Netzwerk-fĂĽr-Arduino

Source: https://habr.com/ru/post/de384243/


All Articles