Ajout d'un compteur SDM-220 à OpenHab

Près d'un an s'est écoulé depuis ma première publication sur un compteur électrique avec interface RS485 / ModBus SDM-220 , puis il y avait un deuxième article sur la façon de collecter des données et de traiter les statistiques. C'est le troisième, espérons-le dernier. Elle explique comment intégrer le compteur à OpenHab . Le résultat me convient enfin parfaitement.



Ainsi, la première tentative de collecte de statistiques à partir du compteur a été effectuée à l'aide d'un service cloud externe ThingSpeak . En tant que serveur local qui interroge le compteur, nous avons utilisé un client léger (mini-ordinateur) avec Ubuntu Server installé sur la clé USB. Ce fut la première erreur - le lecteur flash "est mort" après 3 mois (un accident, je pensais). N'ayant tiré aucune conclusion, j'ai tué le deuxième lecteur flash en 2 mois (régularité). Dans la troisième version, une poche USB avec une vis de 2,5 "était déjà utilisée comme rangement.

Le service ThingSpeak lui-même permet un certain traitement, mais n'offre pas une flexibilité suffisante avec la manipulation des données. Les données par jour, par exemple, ont été collectées comme la somme des données par heure. Si certains paquets de données ne sont pas arrivés sur le serveur ou si j'ai envoyé des données pendant les tests, une erreur s'est produite. Les opinions selon lesquelles il serait nécessaire de tenir une comptabilité à deux taux en se référant à l'heure de la journée ne se sont pas ajoutées à l'optimisme.

En général, j'ai décidé d'apprendre OpenHab .

La première tâche: obtenir les données brutes du compteur.


L'installation d'OpenHab lui-même est détaillée dans les instructions . Après l'installation, vous devez installer la liaison ModBus - binding-modbus1 - 1.9.0 via l' interface utilisateur du papier → panneau Liaisons

Le bus Modus est interrogé via l'adaptateur USB-RS485, vous devez donc vous assurer que l'adaptateur est dans le système et ajouter les droits d'accès utilisateur openhab au port:

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 

Il est ensuite recommandé de configurer les autorisations pour Java (cela est également décrit en détail dans les instructions d'installation d'OpenHab):

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

Après ces manipulations, vous devez configurer le fichier de configuration 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 

Ensuite, vous devez créer les éléments de données dans le fichier 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"} 

Il reste à ajouter les lectures actuelles sur le tableau de bord. Pour ce faire, modifiez le fichier 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 } } 

En principe, cela suffit pour voir la lecture actuelle du compteur:



Tâche deux: configurer HabPanel et visualiser les lectures


OpenHab prend en charge plusieurs panneaux de contrôle. Extérieurement, j'aimais le plus HabPanel . Via Paper UI → User Interfaces, installez HabPanel - ui-habpanel - 2.0.0 .

Pour dessiner des graphiques, vous devez également stocker des données quelque part. OpenHab utilise le terme Persistance pour les bases de données. Je voulais utiliser la base de données MySQL, la communauté a discuté de beaucoup de problèmes avec cette base de données, à la fin j'ai trouvé une instruction qui fonctionnait aussi pour moi.

Installez donc MySQL Persistence (persistence-mysql - 1.9.0).

Installez MySQL:

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

Configurer la base:

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

Redémarrez openhab:

 sudo service openhab2 stop sudo service openhab2 start 

Modifier les services / 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 

Modifiez persistence / mysql.persist . Par défaut, les valeurs de tous les articles seront entrées dans la base de données à chaque modification:

 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 } 

Si tout est correctement configuré, la table Items et les tables ItemXX pour chaque article doivent apparaître dans la base de données.

 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) 

Vous pouvez maintenant apporter de la beauté au HabPanel.

Ajoutez un tableau de bord, ajoutez-y de nouveaux widgets. Pour afficher les valeurs, utilisez le widget factice , pour afficher les graphiques - Graphique . Tout est intuitif ici. J'ai déduit les paramètres de puissance et de tension sur un graphique en utilisant deux échelles Y différentes.

Spécifiez mysql comme source de données:



Définissez des seuils pour l'axe de tension:



Ajouter des éléments, indiquez la couleur et le type de ligne pour eux, car la tension indique l'axe secondaire:



On obtient le résultat :)



La troisième tâche: le comptage horaire et quotidien de l'électricité consommée


Afficher un changement d'état dans le temps, c'est bien, mais je voulais aussi obtenir des statistiques de consommation sur une heure, un jour, un mois. Autrement dit, la tâche consiste à effectuer périodiquement certains calculs. C'est là qu'intervient le moteur de règles d'OpenHab.

Nous configurons donc les règles .

Vous devez d'abord ajouter de nouveaux éléments à items / sdm220.items :

 Number sdm220_hourcounter (gSDM220) Number sdm220_daycounter (gSDM220) 

Créez ensuite le fichier rules / energy.rules , dans lequel vous devez spécifier 2 règles: une sera exécutée une fois par heure, la seconde - une fois par jour.

 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) 

Vous pouvez utiliser la console OpenHab pour le débogage. Nom d'utilisateur et mot de passe standard: openhab / habopen. Vous pouvez vous y connecter avec la commande:

 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 

Ou vous pouvez afficher le fichier journal:

 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 

Je prévois de changer le compteur d'électricité principal en un compteur à deux tarifs, selon lequel l'électricité consommée dans la plage de 23h00 à 07h00 est payée avec un coefficient de 0,5, donc je voudrais voir l'effet attendu et garder un compteur à deux tarifs. Au début, j'ai simplement ajouté des conditions supplémentaires de temps aux éléments et règles et ajouté les lectures de jour et de nuit dans deux tableaux différents. Tout était beau dans la base de données, mais cela semblait maladroit sur le graphique, car le graphique connectait les deux dernières valeurs avec une ligne droite:



Pour amuser mon sens de la beauté, j'ai dû m'inquiéter un peu.

Ainsi, le script de règles final pour la comptabilité à deux tarifs ressemble à ceci:

 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 

Avant de modifier le script, ajoutez les éléments nécessaires:

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

Maintenant, l'organigramme horaire et quotidien ressemble à ceci:



C’est probablement tout. Il est également prévu d'ajouter un calcul de la consommation d'électricité et d'argent par mois pour un tarif journalier et nocturne et une génération de rapport avec envoi par mail.

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


All Articles