OpenHAB के वायरलेस होम एयर कंडीशनर नियंत्रक के माध्यम से Modbus RF24Network के माध्यम से


एक नियंत्रक के साथ एयर कंडीशनिंग को नियंत्रित करने के बारे में मेरे पहले लेख के बाद , 2 साल से थोड़ा अधिक समय बीत गया। इस दौरान, एयर कंडीशनर को दूर से नियंत्रित करने के विचार ने मुझे नहीं छोड़ा और कई पुनर्जन्म हुए। मुख्य स्थिति एयर कंडीशनर के लिए किसी भी तार की अनुपस्थिति थी।

यही है, नियंत्रक का नियंत्रण वायरलेस होना चाहिए।

पृष्ठभूमि


पहला प्रोटोटाइप Arduino UNO था। उसने UART पर टीमों को स्वीकार किया और एयर कंडीशनर को चालू और बंद करना जानता था। चूंकि वहाँ काम कर रहे कंप्यूटर से जुड़े arduinka से थोड़ा व्यावहारिक अर्थ था, सिर लगातार घर के सर्वर से बाद को जोड़ने के अवसर की तलाश में था। सर्वर से लेकर सभी पहेलियों के अपराधी तक कोई प्रत्यक्ष दृश्यता नहीं थी। अधिकतम सभी समान काम करने वाले कंप्यूटर पर लैन के साथ एक सॉकेट है - चूंकि यह एयर कंडीशनर के लगभग विपरीत है। ईथरनेट कवच उपलब्ध नहीं था। लेकिन याद रखें कि ज़ाशनिक में कहीं भी एक डी-लिंक डीएसएल -2500 यू डीएसएल मॉडेम है जो लंबे समय से उपयोग नहीं किया गया है, जिसमें बोर्ड पर सिर्फ एक पोर्ट है। लोहे के टुकड़े को दूसरा जीवन देने की इच्छा ने गुग्लिंग को जन्म दिया, जिसके परिणामस्वरूप, चमत्कारिक रूप से लेख को एक एडीएसएल मॉडेम में बदल दिया गया जो कि Arduino / CraftDuino के लिए एक ईथरनेट ढाल में बदल गया

आगे कूदते हुए और कस्टम फ़र्मवेयर बनाने की दिलचस्प प्रक्रिया को छोड़ते हुए, मैं अभी भी वांछित पोर्ट पर सुनने के लिए मॉडेम प्राप्त करने में कामयाब रहा और इसके माध्यम से UART को "फॉरवर्ड" किया। इस प्रकार, होम सर्वर पर, मैं पोर्ट को चालू / बंद करने के लिए स्थानीय मॉडेम पते को चालू करने के लिए एक कमांड भेज सकता हूं, जो इससे जुड़े arduino पर जाएगा।

लेकिन यह लेख उस बारे में नहीं है। अंतिम समाधान मोडबस प्रोटोकॉल और RF24Network वायरलेस नेटवर्क का उपयोग करता है और सब कुछ OpenHAB में नियंत्रित होता है।


इन दो वर्षों के दौरान, मैं चीन से बहुत सारे निशक्तियों का ऑर्डर करने में कामयाब रहा और उनमें से अधिकांश पंखों में इंतजार कर रहे थे। इस सूची में NRF24L01 + मॉड्यूल शामिल था, जो प्रयोग के लिए मुट्ठी भर द्वारा खरीदा गया था। और वह कोठरी में बेकार कहीं और चला गया होता, अगर एक दिन मैं लेखों की एक श्रृंखला पर ठोकर नहीं खाता:

से Borichउसके लिये आपका धन्यवाद!

उनके लिए धन्यवाद, मैं मोदाबस प्रोटोकॉल से परिचित हो गया। लेकिन सबसे महत्वपूर्ण बात, मैंने अपने लिए ओपनएचएबी की खोज की - जो मैं लंबे समय से देख रहा था। इसने मुझे लंबे समय से चल रहे विचारों को लागू करने के लिए प्रेरित किया।

लेखों के उदाहरणों के साथ खेलने के बाद, मैंने ऊपर वर्णित मॉडेम से ईथरनेट-शील्ड का उपयोग करके नियंत्रक और सर्वर को अलग करने का प्रयास करने का निर्णय लिया। इस समाधान ने हमें पोज़ किए गए कार्य को प्राप्त करने की अनुमति दी - ढाल और नियंत्रक एक काम कर रहे कंप्यूटर का उपयोग किए बिना, डेस्कटॉप पर स्थित थे, उसी समय, ढाल हमेशा स्थानीय नेटवर्क से जुड़ा होता है और होम सर्वर से पहुंच योग्य होता है।

लेकिन यह निर्णय असफलता के लिए किया गया था।
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 .

, . . , .


विचार


और फिर मैंने अंत में खुद को स्थापित किया कि मुझे एक नियंत्रक बनाने की आवश्यकता है जो हवा से सुलभ हो। NRF24L01 + मॉड्यूल गायब नहीं होना चाहिए! .. सच है, इसके लिए कम से कम दो नियंत्रकों की आवश्यकता होती है - एक प्रत्यक्ष भूमिका करता है, दूसरा एक राउटर की भूमिका निभाता है। दूसरा सर्वर से जुड़ा होना चाहिए और यह इसके माध्यम से है कि दूसरों के साथ वायरलेस संचार किया जाता है। इसे कनेक्ट करते समय, हम उस अधीनस्थ की आईडी को निर्दिष्ट करते हैं जिसे पैकेज का इरादा है। यह पता चला है कि एक सीरियल पोर्ट पर कई दास उपलब्ध हैं। हां - यह एक मोडबस आधारित वायरलेस नेटवर्क है।

वैसे, मोडबस, एक मास्टर के साथ एक नेटवर्क बनाने के लिए संभव बनाता है - कई अधीनस्थ। और RF24Network लाइब्रेरी - सब कुछ वायरलेस बनाने के लिए, और यहां तक ​​कि नेटवर्क नोड्स के बीच स्वचालित रूटिंग के साथ।

Arduino के लिए लाइब्रेरी डेवलपमेंट


इस तरह के समाधान को कार्यान्वित करने के लिए, मोडबस-मास्टर-स्लेव-फॉर-अरुडिनो लाइब्रेरी को संशोधित करने के लिए इसे से विरासत में प्राप्त करने और कुछ तरीकों को अधिभार करने में थोड़ा सा समय लगा मेरा कार्यान्वयन भी अपडेट किया गया है (नवीनतम पुस्तकालय के लिए पुस्तकालय पुस्तकालय को जोड़ दिया गया है। पुस्तकालय फ़ाइल को हेडर और बॉडी में विभाजित किया गया है) 1.6.5। मोडबस-ओवर-RF24Network-for-Arduino

लाइब्रेरी आपको दो संभावित व्यवहारों को लागू करने की अनुमति देता है - प्रॉक्सी और स्लेव। उदाहरण ModbusRF24Proxy वास्तव में एक "राउटर" का कार्यान्वयन है और आवश्यक पिन सेट करने के अलावा किसी भी संशोधन की आवश्यकता नहीं है।
मोडबस उदाहरणRF24Proxy
#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);
}


एक राउटर या प्रॉक्सी एक विशेष कंस्ट्रक्टर प्रारूप का उपयोग करता है:
//  ,   TX
ModbusRF24 proxy(network, 0, 0);

और कार्य करते हैं
proxy.proxy();

सीरियल पोर्ट पर आने वाले पैकेट को संसाधित करने के लिए, उन्हें RF24Network पर भेजें, नेटवर्क से प्रतिक्रिया प्राप्त करें, परिणाम को सीरियल पोर्ट पर वापस भेजें।

इस कार्यान्वयन में, प्रॉक्सी के पास शून्य का RF24Network पता है:
// Address of our node
const uint16_t this_node = 0;

- अर्थात। यह नेटवर्क का रूट डिवाइस है। यदि आवश्यक हो, तो प्रॉक्सी नियंत्रक की टोपोलॉजी में स्थिति को बदला जा सकता है।

मोडबस उदाहरण 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();
}



इस मामले में निर्माता पहले से ही अलग है:
//  
ModbusRF24 slave(network, ID);


मोडबस रजिस्टर संरचना


एयर कंडीशनर को नियंत्रित करने के पहले सफल प्रयासों के बाद केवल मेरी भूख को चालू और बंद करने की क्षमता में वृद्धि हुई। अब यह पहले से ही पर्याप्त नहीं था, और चूंकि मेरे मोबाइल एप्लिकेशन में OpenHAB कार्यक्षमता है, इसलिए इसे मूल नियंत्रण कक्ष की न्यूनतम कार्यक्षमता के रूप में करना चाहिए।
इसका मतलब यह है कि कम से कम सुविधाओं की एक सूची है:
  • वर्तमान स्थिति संकेत
  • एयर कंडीशनर को चालू और बंद करना, व्यक्तिगत मोड (ओ 2 , आयनीकरण, साइलेंट मोड);
  • वर्तमान मोड का चयन (ऑटो, हीटिंग, कूलिंग, ड्रेनेज, प्रशंसक);
  • प्रत्येक मोड के लिए तापमान और प्रशंसक गति का संकेत। प्रशंसक मोड के लिए, केवल गति;
  • ऊर्ध्वाधर पर्दा सेटिंग (ऑटो, 0 °, 15 °, 30 °, 45 °, 60 °);
  • क्षैतिज पर्दा सेटिंग (ऑटो, "| |", "/ /", "/ |", "| \", "\ \");
  • समय सेटिंग (घंटे, मिनट);
  • टाइमर सेटिंग पर;
  • टाइमर सेटिंग बंद;
  • समय पर सेटिंग (घंटे, मिनट);
  • शटडाउन समय सेटिंग (घंटे, मिनट);

विकास की प्रक्रिया के दौरान, रजिस्टरों की संरचना मेरे साथ कई बार बदल गई है। वर्तमान संस्करण स्पॉइलर के नीचे है।
मोडबस रजिस्टर
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_0
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.


रजिस्टरों को इस तरह से व्यवस्थित किया जाता है कि नियंत्रक शुरू होने पर पूरे डेटा सरणी को EEPROM से प्रारंभ किया जाता है।
पहले 3 रजिस्टरों (CFG_ *) में सुविधाओं का विन्यास है, वे कभी नहीं बदलते हैं और EEPROM फर्मवेयर द्वारा आरंभीकृत होते हैं।
रजिस्टर 3-7 हमेशा नियंत्रक की वर्तमान स्थिति को प्रदर्शित करता है। राज्य को बदलने के लिए रजिस्टर 3 के उच्च बिट्स का उपयोग किया जाता है। उनके परिवर्तन एयर कंडीशनर और विशेष मोड को चालू / बंद करते हैं। कमांड निष्पादित होने के बाद, इस रजिस्टर के निम्न-क्रम बिट्स को उच्च-क्रम वाले लोगों में कॉपी किया जाता है।
रजिस्टर 4 में वर्तमान नियंत्रक समय होता है, जिसे आरटीसी से पढ़ा जाता है। मान को BCD प्रारूप में सहेजा जाता है, ताकि जब रजिस्टर हेक्साडेसिमल नोटेशन में प्रदर्शित हो, तो समय को इस प्रकार पढ़ा जाता है - 12:34 0x1234 है।
RTC समय बदलने के लिए रजिस्टर 5 का उपयोग किया जाता है।
6-7 रजिस्टरों में DS18B20 सेंसर से तापमान होता है। मान में एक हस्ताक्षरित पूर्णांक होता है और T * 100 के बराबर होता है, अर्थात 25.67 ° C = 2567। अधिकतम 2 सेंसर प्रदान किए जाते हैं, लेकिन सेंसर के पते और उनके तापमान को संग्रहीत करने के लिए रजिस्टर तालिका का विस्तार करके संख्या को आसानी से बदला जा सकता है।
सेंसर पते के अंतिम 2 बाइट्स 25-26 रजिस्टरों में संग्रहीत किए जाते हैं। सेंसर बदलते समय, संबंधित पता रजिस्टर को रीसेट करें। जब एक नया सेंसर का पता लगाया जाता है, तो उसका पता 25-26 रजिस्टर में उपस्थिति के लिए जांचा जाता है। यदि पता तालिका में है, तो सेंसर का तापमान मान संबंधित रजिस्टर 6-7 में दर्ज किया गया है। यदि पता तालिका में नहीं है और तालिका में शून्य कोशिकाएं हैं, तो वर्तमान सेंसर पता एक मुक्त सेल में लिखा गया है।
8-26 पंजीकृत करता है, जब उपयोगकर्ता द्वारा संशोधित किया जाता है, EEPROM में सहेजा जाता है।

ग्रंथियों


हार्डवेयर में निम्नलिखित घटक होते हैं:
  1. Arduino प्रो मिनी।
    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. — , ,











Optocouplers को संबंधित एल ई डी से जोड़कर एयर कंडीशनर के साथ प्रतिक्रिया का एहसास होता है। इस प्रकार, एयर कंडीशनर के विद्युत सर्किट के साथ गैल्वेनिक अलगाव सुनिश्चित किया जाता है। ऑप्टोकॉपर्स के लिए इनपुट की धारा को प्रयोगात्मक रूप से प्रतिरोधों का उपयोग करके चुना गया था ताकि ऑप्टोकॉप्लर का आउटपुट खुल जाए और एयर कंडीशनर पर मुख्य एलईडी की चमक कम न हो।

एयर कंडीशनर के आईआर रिसीवर के बगल में एक आईआर एलईडी स्थापित किया गया था।

नियंत्रक कुछ प्रकार के चीनी चमत्कार से मिनी-यूएसबी चार्ज द्वारा संचालित होता है। चार्जिंग मामले से चीनी साधन वोल्टेज संपर्क हटा दिए गए थे, तारों को हटा दिया गया था। अपने आप को एयर कंडीशनर केस के बॉल्स में चार्ज करना, इसके साथ समानांतर में इनपुट 220 से जुड़ा हुआ है। नियंत्रक एक नियमित यूएसबी एबी केबल के साथ चार्ज करने के लिए जोड़ता है।

"राउटर" नियंत्रक एक अलग LM1117-3.3 के साथ Arduino Mega2560 और NRF24L01 + पर आधारित है। एक अलग 3.3 बिजली की आपूर्ति के अलावा, एक इलेक्ट्रोलाइट वायरलेस मॉड्यूल से जुड़ा हुआ है (मैंने इसे 470uf * 16v पर) बिजली के पैरों पर पाया। जैसा कि आप जानते हैं, आंतरिक Mega2560 3.3V पावर बस बहुत शोर है और मॉड्यूल ने डेटा संचारित करने से इनकार कर दिया, हालांकि यह सही तरीके से जवाब दिया। लेकिन एक संधारित्र के बिना एक अलग बिजली की आपूर्ति के साथ भी, कनेक्शन बहुत अस्थिर था।
ताकि USB के माध्यम से पोर्ट खोलने पर मेगा2560 रीसेट न हो, एक 10μf इलेक्ट्रोलाइट रीसेट पिन से जुड़ा होता है।

Openhab


Arduino और OpenHAB लेख बाइंडिंग प्लग में Modbus की एक विशेषता का वर्णन करता है, कि नियंत्रक के प्रत्येक चुनाव के साथ, बस के लिए एक घटना भेजता है प्लग में है, भले ही कुछ भी नहीं बदला है। मैंने सूट का पालन किया और प्लगइन को अंतिम रूप दिया।

मोडबस बाइंडिंग प्लगिन कॉन्फ़िगरेशन
#
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

आइटम सेटिंग्स
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"}


नियमों का उपयोग पूर्णांक तापमान को वास्तविक में बदलने के लिए किया जाता है, साथ ही नियंत्रक समय को एचएच: एमएम के रूप में प्रारूपित करने के लिए किया जाता है।
नियम सेटिंग्स
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


साइटमैप सेटिंग्स
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
                        }
                }
        }
}



परिणाम ब्राउज़र के माध्यम से कुछ इस तरह दिखता है:

निष्कर्ष


मैं हाथी के रूप में परिणाम से प्रसन्न हूं। जहां भी मोबाइल इंटरनेट या वाईएफआई है, वहां एयर कंडीशनिंग कंट्रोल अब मेरे पास उपलब्ध है। स्मार्टफोन पर वीपीएन क्लाइंट का उपयोग करते हुए, मेरे होम सर्वर पर ओपनएचएबी ब्राउज़र और मोबाइल एप्लिकेशन के माध्यम से मेरे लिए सुलभ हो जाता है।
वायरलेस समाधान ने एयर कंडीशनिंग के साथ नियंत्रक को बारीकी से एकीकृत करना संभव बना दिया।
प्रतिक्रिया की उपस्थिति विश्वास दिलाती है कि भेजे गए आदेश को एयर कंडीशनर द्वारा प्राप्त किया गया था, और तापमान संवेदक स्पष्ट रूप से यह प्रदर्शित करते हैं - कुछ सेकंड के बाद आप एयर कंडीशनर के आउटलेट पर तापमान पढ़ने में बदलाव का निरीक्षण कर सकते हैं। खैर, कुछ मिनटों के बाद - और परिवेश का तापमान।
दिए गए शर्तों के करीब आने पर एयर कंडीशनर की प्रोफाइल का निरीक्षण करना दिलचस्प था।

निस्संदेह यह केवल वायरलेस नियंत्रक नहीं होगा जिसका मैं उपयोग करने की योजना बना रहा हूं।

कंट्रोलर में सेटिंग्स को अपडेट करने के लिए देशी रिमोट कंट्रोल के कमांड को पढ़ने के लिए स्वयं एयर कंडीशनर के आईआर रिसीवर का उपयोग करने की योजना है। इसके अलावा, IR रिसीवर पहले से ही एक ऑप्टोकॉप्टर के माध्यम से नियंत्रक से जुड़ा हुआ है।

अंत में पढ़ें एक विशेष धन्यवाद!

संदर्भ


  1. Arduino लाइब्रेरी ModbusRtu Modbus-Master-Slave-for-Arduino
  2. Arduino लाइब्रेरी ModbusRtuRF24 मोडबस -ओवर-RF24 नेटवर्क-के लिए Arduino

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


All Articles