جهاز التحكم في مكيفات الهواء المنزلية اللاسلكية من OpenHAB عبر Modbus عبر RF24Network


بعد مقالتي الأولى حول التحكم في تكييف الهواء باستخدام وحدة تحكم ، مرت أكثر من عامين بقليل. خلال هذا الوقت ، لم تتركني فكرة التحكم في مكيف الهواء عن بعد ولديها العديد من الولادات. كان الشرط الرئيسي هو عدم وجود أي أسلاك لمكيف الهواء.

أي أن التحكم في وحدة التحكم يجب أن يكون لاسلكيًا.

خلفية


كان النموذج الأول هو Arduino UNO. قبلت الفرق على UART وعرفت كيفية تشغيل وإيقاف مكيف الهواء. لان كان هناك القليل من الإحساس العملي من arduinka المتصلة بالكمبيوتر العامل ، وكان الرأس يبحث باستمرار عن فرصة لربط الأخير بالخادم المنزلي. لم يكن هناك رؤية مباشرة من الخادم إلى الجاني لجميع الألغاز. الحد الأقصى هو مقبس مزود بشبكة LAN على نفس الكمبيوتر العامل - حيث أنه يقف تقريبًا مقابل مكيف الهواء. لم يكن درع Ethernet متاحًا. لكن تذكر أنه في مكان ما في zashashnik يوجد مودم d-link DSL-2500U dsl لم يتم استخدامه لفترة طويلة ، مع وجود منفذ واحد فقط على متن الطائرة. أدت الرغبة في إعطاء حياة ثانية لقطعة الحديد إلى googling ، مما أدى بدوره إلى معجزة مقالة تحويل مودم ADSL إلى درع إيثرنت لـ Arduino / CraftDuino .

من خلال المضي قدمًا وتخطي عملية مثيرة للاهتمام لإنشاء برامج ثابتة مخصصة ، تمكنت من الحصول على المودم للاستماع إلى المنفذ المطلوب و "توجيه" UART من خلاله. وهكذا ، على الخادم المنزلي ، يمكنني إرسال أمر لتشغيل / إيقاف تشغيل المنفذ إلى عنوان المودم المحلي ، والذي سيذهب إلى اردوينو متصل به.

لكن هذه المقالة ليست عن ذلك. الحل النهائي يستخدم بروتوكول Modbus وشبكة RF24Network اللاسلكية . ويتم التحكم في كل شيء في OpenHAB.


خلال هذين العامين ، تمكنت من طلب الكثير من جميع nishtyaks من الصين وكان معظمهم ينتظرون في الأجنحة. تضمنت هذه القائمة وحدة NRF24L01 + ، تم شراؤها من قبل حفنة للتجريب. وكان سيذهب أبعد من ذلك في مكان ما في خزانة الخمول ، إذا لم أتعثر في أحد الأيام على سلسلة من المقالات:

من عند بوريششكرا لك على ذلك!

بفضلهم ، تعرفت على بروتوكول Modbus. لكن الأهم من ذلك أنني اكتشفت OpenHAB لنفسي - ما كنت أبحث عنه منذ فترة طويلة. دفعني هذا إلى البدء في تنفيذ الأفكار القديمة.

بعد التلاعب بأمثلة من المقالات ، قررت أن أحاول فصل وحدة التحكم والخادم باستخدام درع ethernet من المودم الموصوف أعلاه. سمح لنا هذا الحل بتحقيق المهمة المطروحة - تم وضع الدرع ووحدة التحكم على سطح المكتب ، دون استخدام جهاز كمبيوتر يعمل ، وفي نفس الوقت ، كان الدرع متصلًا دائمًا بالشبكة المحلية ويمكن الوصول إليه من الخادم الرئيسي.

لكن هذا القرار محكوم عليه بالفشل.
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 + .. صحيح ، هذا يتطلب وحدتي تحكم على الأقل - أحدهما يؤدي دورًا مباشرًا ، والثاني يلعب دور جهاز التوجيه. يجب توصيل الثانية بالخادم ومن خلالها يتم الاتصال اللاسلكي مع الآخرين. عند الاتصال بها ، نحدد هوية المرؤوس الذي تستهدفه الحزمة. اتضح أن العديد من العبيد متاحين على منفذ تسلسلي واحد. نعم - هذه شبكة لاسلكية قائمة على Modbus.

بالمناسبة ، جعل Modbus من الممكن بناء شبكة مع سيد واحد - العديد من المرؤوسين. ومكتبة RF24Network - لجعل كل شيء لاسلكيًا ، وحتى مع التوجيه التلقائي بين عقد الشبكة.

تطوير مكتبة اردوينو


لتنفيذ هذا الحل ، استغرق الأمر بعض الوقت لتعديل مكتبة Modbus-Master-Slave-for-Arduino لتكون قادرة على الوراثة منه وتحميل طريقتين بشكل زائد. يتم أيضًا تحديث التطبيق الخاص بي (تتم إضافة خصائص مكتبة. وتقسيم ملف المكتبة إلى رأس ونص) لأحدث Arduino IDE 1.6.5. تسمح لك

مكتبة Modbus-over-RF24Network-for-Arduino بتنفيذ سلوكين محتملين - Proxy و Slave. مثال 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 في تطبيق الهاتف المحمول الخاص بي ، فيجب أن تعمل كحد أدنى جميع وظائف لوحة التحكم الأصلية.
هذا يعني هنا قائمة الميزات على الأقل:
  • مؤشر الحالة الحالية
  • تشغيل وإيقاف مكيف الهواء ، الأوضاع الفردية (O 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 على وقت وحدة التحكم الحالية ، والذي تتم قراءته من RTC. يتم حفظ القيمة في تنسيق BCD ، بحيث عندما يتم عرض السجل بترميز سداسي عشري ، يتم قراءة الوقت كما هو - 12:34 هو 0x1234.
يتم استخدام التسجيل 5 لتغيير وقت RTC.
تسجيلات 6-7 تحتوي على درجة الحرارة من أجهزة الاستشعار DS18B20. تحتوي القيمة على عدد صحيح موقّع وتساوي T * 100 ، أي 25.67 درجة مئوية = 2567. يتم توفير مستشعرين كحد أقصى ، ولكن يمكن تغيير الرقم بسهولة من خلال توسيع جدول التسجيل لتخزين عناوين المستشعرات ودرجات حرارتها.
يتم تخزين البايتتين الأخيرتين من عنوان المستشعر في السجلات 25-26. عند تغيير المستشعرات ، أعد تعيين سجل العنوان المقابل. عند اكتشاف مستشعر جديد ، يتم التحقق من وجوده في السجلات من 25 إلى 26. إذا كان العنوان في الجدول ، يتم إدخال قيمة درجة حرارة المستشعر في السجل المقابل 6-7. إذا لم يكن العنوان في الجدول وكان الجدول يحتوي على خلايا صفرية ، فسيتم كتابة عنوان المستشعر الحالي في خلية مجانية.
يتم حفظ السجلات 8-26 ، عند تعديلها بواسطة المستخدم ، في EEPROM.

الغدد


يتكون الجهاز من المكونات التالية:
  1. اردوينو برو ميني.
    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 بأضواء LED المقابلة. وبالتالي ، يتم ضمان العزل الجلفاني مع الدائرة الكهربائية لمكيف الهواء. تم اختيار تيار مدخلات optocouplers تجريبيًا باستخدام مقاومات بحيث يتم فتح خرج optocoupler ولا ينخفض ​​سطوع LED الرئيسي في مكيف الهواء.

تم تثبيت IR LED بجانب مستقبل IR لمكيف الهواء.

وحدة التحكم مدعومة بشحن USB صغير من نوع ما من المعجزة الصينية. تمت إزالة جهات اتصال التيار الكهربائي الصينية من علبة الشحن ، وتمت إزالة الأسلاك. استقر الشحن نفسه في أحشاء صندوق مكيف الهواء ، متصلاً بمدخل 220 بالتوازي معها. تتصل وحدة التحكم بالشحن باستخدام كبل USB AB عادي.

تحكم "الموجه" يعتمد على Arduino Mega2560 و NRF24L01 + مع LM1117-3.3 منفصل. بالإضافة إلى مصدر طاقة 3.3 منفصل ، يتم توصيل المنحل بالكهرباء بالوحدة اللاسلكية (وجدته عند 470 فائق التوهج * 16 فولت) على أرجل الطاقة. كما تعلم ، فإن ناقل الطاقة Mega2560 3.3V الداخلي صاخب للغاية ورفضت الوحدة نقل البيانات ، على الرغم من أنها ردت بشكل صحيح. ولكن حتى مع وجود مصدر طاقة منفصل بدون مكثف ، كان الاتصال غير مستقر للغاية.
حتى لا يتم إعادة ضبط mega2560 عند فتح المنفذ عبر USB ، يتم توصيل إلكتروليت 10μf بدبوس إعادة التعيين.

Openhab


و المادة اردوينو وOpenHAB يصف سمة من سمات مودبوس ربط المكونات في، مع أن كل استطلاع للتحكم، والمكونات في يرسل حدث إلى الحافلة، حتى كأن شيئا لم يتغير. اتبعت حذوها وانتهت من البرنامج المساعد.

تكوين البرنامج المساعد مودبوس ملزم
#
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"}


تستخدم القواعد لتحويل درجات الحرارة الصحيحة إلى درجات حرارة حقيقية ، وكذلك لتنسيق وقت التحكم إلى النموذج HH: MM.
إعدادات القواعد
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
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
                        }
                }
        }
}



تبدو النتيجة شيئًا كهذا من خلال متصفح:

استنتاج


أنا سعيد بالنتيجة كفيلة. التحكم في تكييف الهواء متاح لي الآن أينما كان هناك إنترنت محمول أو WiFI. باستخدام عميل VPN على هاتف ذكي ، أصبح OpenHAB على خادم المنزل الخاص بي في متناولي من خلال المتصفح ومن خلال تطبيق الهاتف المحمول.
جعل الحل اللاسلكي من الممكن دمج وحدة التحكم عن كثب مع تكييف الهواء.
إن وجود التعليقات يعطي الثقة في أن الأمر المرسل تم استقباله بواسطة مكيف الهواء ، ومستشعرات درجة الحرارة توضح ذلك بوضوح - بعد بضع ثوانٍ يمكنك ملاحظة تغير في قراءة درجة الحرارة في مخرج مكيف الهواء. حسنًا ، بعد بضع دقائق - ودرجة الحرارة المحيطة.
كان من المثير للاهتمام ملاحظة ملف تعريف مكيف الهواء عند الاقتراب من الظروف المحددة.

مما لا شك فيه أنه لن يكون وحدة التحكم اللاسلكية الوحيدة التي أخطط لاستخدامها.

هناك خطط لاستخدام مستقبل الأشعة تحت الحمراء لمكيف الهواء نفسه لقراءة أوامر جهاز التحكم عن بعد الأصلي لتحديث الإعدادات في وحدة التحكم. علاوة على ذلك ، فإن مستقبل IR نفسه متصل بالفعل عبر optocoupler إلى وحدة التحكم.

اقرأ حتى النهاية شكرا خاصا!

المراجع


  1. مكتبة Arduino ModbusRtu Modbus-Master-Slave-for-Arduino
  2. مكتبة اردوينو ModbusRtuRF24 Modbus-over-RF24 Network-for-Arduino

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


All Articles