إضافة عداد SDM-220 إلى OpenHab

لقد مر عام تقريبًا منذ أول منشور لي حول عداد كهربائي بواجهة RS485 / ModBus SDM-220 ، ثم كان هناك مقال ثانٍ حول كيفية جمع البيانات منه ومعالجة الإحصائيات. هذا هو الثالث ، آمل أن يكون الأخير. تتحدث عن كيفية دمج العداد مع OpenHab . والنتيجة هي جيدة تماما معي في النهاية.



لذلك ، تم إجراء أول محاولة لجمع الإحصائيات من العداد باستخدام خدمة سحابية خارجية ThingSpeak . كخادم محلي يقوم باستقصاء العداد ، استخدمنا عميل رفيع (كمبيوتر صغير) مع خادم Ubuntu مثبت على USB stick. كان هذا هو الخطأ الأول - محرك الأقراص المحمول "مات" بعد 3 أشهر (حادث ، على ما أظن). بعد عدم التوصل إلى استنتاجات ، قتلت محرك الأقراص المحمول الثاني في شهرين (انتظام). في الإصدار الثالث ، تم استخدام جيب USB مزود بمسمار 2.5 بوصة كمخزن.

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

بشكل عام ، قررت أن أتعلم OpenHab .

المهمة الأولى: الحصول على البيانات الأولية من العداد.


يتم تفصيل تثبيت OpenHab نفسه في التعليمات . بعد التثبيت ، تحتاج إلى تثبيت ربط ModBus - ملزم - modbus1 - 1.9.0 من خلال واجهة مستخدم Paper → لوحة Bindings

يتم تمرير ناقل Modus عبر محول USB-RS485 ، لذلك تحتاج إلى التأكد من وجود المحول في النظام وإضافة حقوق وصول مستخدم openhab إلى المنفذ:

lsusb Bus 002 Device 002: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC ls /dev/ttyUSB* /dev/ttyUSB0 sudo adduser openhab dialout sudo adduser openhab tty 

ثم يوصى بتهيئة الأذونات لـ Java (هذا موضح أيضًا بالتفصيل في تعليمات تثبيت OpenHab):

 sudo vi /etc/default/openhab2 EXTRA_JAVA_OPTS="-Dgnu.io.rxtx.SerialPorts=/dev/ttyUSB0" 

بعد هذه المعالجة ، تحتاج إلى تكوين ملف التكوين services / modbus.cfg :

  sudo vi /etc/openhab2/services/modbus.cfg #   poll=30000 #        ,        .  start -  .   connection      (9600,8,n,1),        . # - 0x00 serial.slave1.connection=/dev/ttyUSB0:9600:8:none:1:rtu:2000:1000:none:none serial.slave1.type=input serial.slave1.start=0 serial.slave1.length=2 serial.slave1.valuetype=float32 # - 0x06 serial.slave2.connection=/dev/ttyUSB0:9600:8:none:1:rtu:2000:1000:none:none serial.slave2.type=input serial.slave2.start=6 serial.slave2.length=2 serial.slave2.valuetype=float32 #  - 0x0C serial.slave3.connection=/dev/ttyUSB0:9600:8:none:1:rtu:2000:1000:none:none serial.slave3.type=input serial.slave3.start=12 serial.slave3.length=2 serial.slave3.valuetype=float32 #  ( ) - 0x156 serial.slave4.connection=/dev/ttyUSB0:9600:8:none:1:rtu:2000:1000:none:none serial.slave4.type=input serial.slave4.start=342 serial.slave4.length=2 serial.slave4.valuetype=float32 

ثم تحتاج إلى إنشاء عناصر البيانات في ملف items / sdm220.items :

 sudo vi /etc/openhab2/items/sdm220.items #    Group gSDM220 # ,      , energy -       Number sdm220_voltage " [%.1f ]" <energy> (gSDM220) {modbus="slave1:0"} Number sdm220_current " [%.2f ]" <energy> (gSDM220) {modbus="slave2:0"} Number sdm220_actpower " [%.1f ]" <energy> (gSDM220) {modbus="slave3:0"} Number sdm220_actcounter "  [%.1f *]" <energy> (gSDM220) {modbus="slave4:0"} 

يبقى لإضافة القراءات الحالية على لوحة القيادة. للقيام بذلك ، قم بتحرير ملف sitemaps / default.sitemap :

 sudo vi /etc/openhab2/sitemaps/default.sitemap sitemap default label="alk0v SmartHome (default sitemap)" { Frame label="" { Text item=sdm220_voltage Text item=sdm220_current Text item=sdm220_actpower Text item=sdm220_actcounter } } 

من حيث المبدأ ، هذا يكفي لرؤية قراءة العداد الحالية:



المهمة الثانية: تكوين HabPanel وتصور القراءات


يدعم OpenHab عدة لوحات تحكم. ظاهريًا ، أحببت HabPanel أكثر من غيرها . من خلال Paper UI → User Interfaces ، قم بتثبيت HabPanel - ui-habpanel - 2.0.0 .

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

لذا ، قم بتثبيت MySQL Persistent (persistent-mysql - 1.9.0).

تثبيت MySQL:

 sudo apt-get install mysql-server sudo mysql -u root -p 

قم بإعداد القاعدة:

 CREATE DATABASE OpenHAB; CREATE USER 'openhab'@'localhost' IDENTIFIED BY 'YOURPASSWORD'; GRANT ALL PRIVILEGES ON OpenHAB.* TO 'openhab'@'localhost'; quit 

إعادة تشغيل openhab:

 sudo service openhab2 stop sudo service openhab2 start 

تحرير الخدمات / mysql.cfg :

 # the database url like 'jdbc:mysql://<host>:<port>/<database>' (without quotes) url=jdbc:mysql://localhost:3306/openhab # the database user user=openhab # the database password password=YOURPASSWORD 

تحرير المثابرة / mysql.persist . بشكل افتراضي ، سيتم إدخال قيم جميع العناصر في قاعدة البيانات مع كل تغيير:

 Strategies { // if no strategy is specified for an item entry below, the default list will be used everyMinute : "0 * * * * ?" every5Minutes : "0 */5 * * * ?" everyHour : "0 0 * * * ?" everyDay : "0 0 0 * * ?" default = everyChange } Items { // persist all items once a day and on every change and restore them from the db at startup * : strategy = default, restoreOnStartup } 

إذا تم تكوين كل شيء بشكل صحيح ، يجب أن يظهر جدول العناصر وجداول ItemXX لكل عنصر في قاعدة البيانات.

 mysql> use openhab; Database changed mysql> show tables; +-------------------+ | Tables_in_openhab | +-------------------+ | Item1 | | Item2 | | Item3 | | Item4 | | Items | +-------------------+ 5 rows in set (0.00 sec) mysql> select * from Items; +--------+--------------------------+ | ItemId | ItemName | +--------+--------------------------+ | 1 | sdm220_voltage | | 2 | sdm220_actpower | | 3 | sdm220_actcounter | | 4 | sdm220_current | +--------+--------------------------+ 4 rows in set (0.00 sec) 

الآن يمكنك إحضار الجمال إلى HabPanel.

أضف لوحة تحكم ، أضف أدوات جديدة إليها. لعرض القيم ، استخدم عنصر الواجهة الوهمي ، لعرض الرسوم البيانية - الرسم البياني . كل شيء بديهي هنا. استنتجت معلمات الطاقة والجهد على رسم بياني واحد باستخدام مقياسين مختلفين لـ Y.

حدد mysql كمصدر بيانات:



تعيين عتبات لمحور الجهد:



إضافة عناصر ، تشير إلى لون ونوع الخط بالنسبة لهم ، للجهد يشير إلى المحور الثانوي:



نحصل على النتيجة :)



المهمة الثالثة: القياس اليومي للساعة والكهرباء المستهلكة


من الجيد عرض تغيير في الحالة بمرور الوقت ، لكنني أردت أيضًا الحصول على إحصاءات حول الاستهلاك لمدة ساعة أو يوم أو شهر. أي أن المهمة هي إجراء بعض الحسابات بشكل دوري. هذا هو المكان الذي يأتي فيه محرك القاعدة في OpenHab.

لذا ، نقوم بتكوين القواعد .

تحتاج أولاً إلى إضافة عناصر جديدة إلى العناصر / sdm220.items :

 Number sdm220_hourcounter (gSDM220) Number sdm220_daycounter (gSDM220) 

ثم قم بإنشاء ملف Rules / energy.rules ، حيث تحتاج إلى تحديد قاعدتين : سيتم تنفيذ واحدة مرة واحدة في الساعة ، والثانية - مرة واحدة في اليوم.

 rule "Energy by hour" when Time cron "0 0 * * * ?" then // .            var hour = sdm220_actcounter.state as DecimalType - sdm220_actcounter.historicState(now.minusHours(1), "mysql":).state as DecimalType //      logInfo("TEST","sdm220_hourcounter = "+hour) //  Item postUpdate(sdm220_hourcounter, hour) end rule "Energy by day" when Time cron "0 0 0 * * ?" then var day = sdm220_actcounter.state as DecimalType - sdm220_actcounter.historicState(now.minusDays(1), "mysql":).state as DecimalType postUpdate(sdm220_daycounter, day) 

يمكنك استخدام وحدة تحكم OpenHab لتصحيح الأخطاء. اسم المستخدم وكلمة المرور القياسيان: openhab / habopen. يمكنك الاتصال به عن طريق الأمر:

 ssh -p 8101 openhab@localhost openhab> log:tail 19:22:00.012 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_hourcounter_day = 0.526123046875 19:22:00.014 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_daycounter = 10.861083984375 19:22:09.462 [INFO ] [marthome.event.ItemStateChangedEvent] - sdm220_current changed from 16.0433025360107421875 to 5.69449329376220703125 19:22:11.500 [INFO ] [marthome.event.ItemStateChangedEvent] - sdm220_actcounter changed from 2387.51904296875 to 2387.5458984375 19:22:13.532 [INFO ] [marthome.event.ItemStateChangedEvent] - sdm220_voltage changed from 192.7679595947265625 to 200.4195098876953125 19:22:15.568 [INFO ] [marthome.event.ItemStateChangedEvent] - sdm220_actpower changed from 2271.8486328125 to 1132.8717041015625 19:23:00.014 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_hourcounter_day = 0.515869140625 19:23:00.015 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_daycounter = 10.8769531250 

أو يمكنك عرض ملف السجل:

 tail -f /var/log/openhab2/openhab.log 2017-04-18 19:17:45.587 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'energy.rules' 2017-04-18 19:18:00.259 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_hourcounter_day = 0.571044921875 2017-04-18 19:18:00.272 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_daycounter = 10.8330078125 2017-04-18 19:19:00.015 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_daycounter = 10.83789062500 2017-04-18 19:19:00.025 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_hourcounter_day = 0.557861328125 2017-04-18 19:20:00.013 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_hourcounter_day = 0.55517578125 2017-04-18 19:20:00.024 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_daycounter = 10.859130859375 

أخطط لتغيير عداد الكهرباء الرئيسي إلى عداد ثنائي التعريفة ، والذي بموجبه يتم دفع الكهرباء المستهلكة في النطاق من الساعة 23:00 إلى 07:00 بمعامل 0.5 ، لذلك أود أن أرى التأثير المتوقع والحفاظ على قياس التعريفة. في البداية ، أضفت ببساطة شروطًا إضافية للوقت إلى العناصر والقواعد وأضفت قراءات النهار والليل إلى جدولين مختلفين. كان كل شيء جميلًا في قاعدة البيانات ، لكنه بدا خرقاء على الرسم البياني ، حيث ربط المخطط بين القيمتين الأخيرتين بخط مستقيم:



لتسلية شعوري بالجمال ، كان علي أن أزعجني قليلاً.

لذا ، يبدو نص القواعد النهائية للمحاسبة ذات التعريفتين كالتالي:

 rule "Energy by hour" when Time cron "0 0 * * * ?" then var hour = sdm220_actcounter.state as DecimalType - sdm220_actcounter.historicState(now.minusHours(1), "mysql":).state as DecimalType //   if(now.getHourOfDay > 7 && now.getHourOfDay < 23) { logInfo("TEST","sdm220_hourcounter_day = "+hour) postUpdate(sdm220_hourcounter_day, hour) } else { //        //      primary key  timestamp,               if(now.getHourOfDay==7) { postUpdate(sdm220_hourcounter_night, hour) Thread::sleep(1000) postUpdate(sdm220_hourcounter_night, 0) Thread::sleep(1000) postUpdate(sdm220_hourcounter_day, 0) Thread::sleep(1000) postUpdate(sdm220_hourcounter_day, hour) } else if(now.getHourOfDay==23) { postUpdate(sdm220_hourcounter_day, hour) Thread::sleep(1000) postUpdate(sdm220_hourcounter_day,0) Thread::sleep(1000) postUpdate(sdm220_hourcounter_night, 0) Thread::sleep(1000) postUpdate(sdm220_hourcounter_night, hour) } else { postUpdate(sdm220_hourcounter_night, hour) } } postUpdate(sdm220_hourcounter, hour) end rule "Energy by day" when Time cron "0 0 0 * * ?" then var day = sdm220_actcounter.state as DecimalType - sdm220_actcounter.historicState(now.minusDays(1), "mysql":).state as DecimalType //night counter, 00:00..07:00 + 23:00..00:00 var day2 = sdm220_actcounter.historicState(now.minusHours(17),"mysql":).state as DecimalType - sdm220_actcounter.historicState(now.minusDays(1), "mysql":).state as DecimalType + sdm220_actcounter.state as DecimalType - sdm220_actcounter.historicState(now.minusHours(1),"mysql":).state as DecimalType //day counter, 07:00..23:00 var day1 = sdm220_actcounter.historicState(now.minusHours(1),"mysql":).state as DecimalType - sdm220_actcounter.historicState(now.minusHours(17),"mysql":).state as DecimalType logInfo("TEST","sdm220_daycounter_day = "+day1) logInfo("TEST","sdm220_daycounter_night = "+day2) logInfo("TEST","sdm220_daycounter = "+day) postUpdate(sdm220_daycounter, day) postUpdate(sdm220_daycounter_day, day1) postUpdate(sdm220_daycounter_night, day2) end 

قبل تحرير البرنامج النصي ، أضف العناصر الضرورية:

 Number sdm220_hourcounter_day (gSDM220) Number sdm220_hourcounter_night (gSDM220) Number sdm220_daycounter_day (gSDM220) Number sdm220_daycounter_night (gSDM220) 

الآن ، يبدو المخطط الانسيابي للساعة واليوم كما يلي:



ربما هذا كل شيء. ومن المقرر أيضًا إضافة حساب للكهرباء واستهلاك الأموال شهريًا لتعريفة يومية وليلية وإعداد تقرير مع الإرسال عبر البريد.

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


All Articles