Ha pasado casi un año desde mi
primera publicación sobre un medidor eléctrico con interfaz RS485 / ModBus
SDM-220 , luego hubo un
segundo artículo sobre cómo recopilar datos y procesar estadísticas. Este es el tercero, con suerte el último. Ella trata sobre cómo integrar el contador con
OpenHab . El resultado finalmente está completamente bien conmigo.

Entonces, el primer intento de recopilar estadísticas del contador se realizó utilizando un servicio externo en la nube
ThingSpeak . Como servidor local que sondea el contador, utilizamos un cliente ligero (mini computadora) con
Ubuntu Server instalado en la memoria USB. Este fue el primer error: la unidad flash "murió" después de 3 meses (un accidente, pensé). Al no haber llegado a ninguna conclusión, maté la segunda unidad flash en 2 meses (regularidad). En la tercera versión, un bolsillo usb con un tornillo de 2.5 "ya se usaba como almacenamiento.
El servicio ThingSpeak en sí mismo permite cierto procesamiento, pero no proporciona suficiente flexibilidad con la manipulación de datos. Los datos por día, por ejemplo, se recopilaron como la suma de datos por hora. Si algunos paquetes de datos no llegaron al servidor o envié algunos datos durante las pruebas, se produjo un error. Los pensamientos de que sería necesario mantener una contabilidad de dos tasas con referencia a la hora del día no fueron optimismo agregado.
En general, decidí aprender
OpenHab .
La primera tarea: obtener datos sin procesar del contador.
La instalación de OpenHab en sí se detalla en las
instrucciones . Después de la instalación, debe instalar el
enlace ModBus -
binding-modbus1 - 1.9.0 a través de la
interfaz de usuario de Paper → panel de enlacesEl bus Modus se sondea a través del adaptador USB-RS485, por lo que debe asegurarse de que el adaptador esté en el sistema y agregar los derechos de acceso de usuario de openhab al puerto:
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
Luego, se recomienda configurar permisos para Java (esto también se describe en detalle en las instrucciones de instalación de OpenHab):
sudo vi /etc/default/openhab2 EXTRA_JAVA_OPTS="-Dgnu.io.rxtx.SerialPorts=/dev/ttyUSB0"
Después de estas manipulaciones, debe configurar el archivo de configuración
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
Luego debe crear los
elementos de datos en el
archivo 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"}
Queda por agregar las lecturas actuales en el tablero. Para hacer esto, edite el archivo
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 principio, esto es suficiente para ver la lectura actual del medidor:

Tarea dos: configurar HabPanel y visualizar lecturas
OpenHab admite múltiples paneles de control. Exteriormente, me gustaba más
HabPanel . A través de
Paper UI → Interfaces de usuario, instale
HabPanel -
ui-habpanel - 2.0.0 .
Para dibujar gráficos, también necesita almacenar datos en algún lugar. OpenHab usa el término
Persistencia para bases de datos. Quería usar la base de datos MySQL, la comunidad discutió muchos problemas con esta base de datos, al final encontré una
instrucción que también funcionó para mí.
Por lo tanto, instale MySQL Persistence (persistence-mysql - 1.9.0).
Instalar MySQL:
sudo apt-get install mysql-server sudo mysql -u root -p
Configurar la base:
CREATE DATABASE OpenHAB; CREATE USER 'openhab'@'localhost' IDENTIFIED BY 'YOURPASSWORD'; GRANT ALL PRIVILEGES ON OpenHAB.* TO 'openhab'@'localhost'; quit
Reiniciar openhab:
sudo service openhab2 stop sudo service openhab2 start
Editar
servicios / 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
Edite
persistence / mysql.persist . Por defecto, los valores de todos los elementos se ingresarán en la base de datos con cada cambio:
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 todo está configurado correctamente, la tabla Artículos y las tablas Artículo XX para cada Artículo deberían aparecer en la base de datos.
mysql> use openhab; Database changed mysql> show tables; +
Ahora puedes traer belleza al HabPanel.
Agregue un Tablero, agregue nuevos widgets. Para mostrar valores, use el widget
Ficticio , para mostrar gráficos -
Gráfico . Todo es intuitivo aquí. Deducí los parámetros de potencia y voltaje en un gráfico usando dos escalas Y diferentes.
Especifique mysql como fuente de datos:

Establecer umbrales para el eje de tensión:

Agregue elementos, indique el color y el tipo de línea para ellos, para el voltaje indique el eje secundario:

Obtenemos el resultado :)

La tercera tarea: medición horaria y diaria de la electricidad consumida.
Mostrar un cambio de estado a lo largo del tiempo es bueno, pero también quería obtener estadísticas sobre el consumo durante una hora, día, mes. Es decir, la tarea es realizar periódicamente algunos cálculos. Aquí es donde entra el motor de reglas en OpenHab.
Entonces, configuramos
Reglas .
Primero debe agregar nuevos elementos a
items / sdm220.items :
Number sdm220_hourcounter (gSDM220) Number sdm220_daycounter (gSDM220)
Luego cree el
archivo rules / energy.rules , en el que debe especificar 2 reglas: una se ejecutará una vez por hora, la segunda, una vez al día.
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)
Puede usar la consola OpenHab para depurar. Nombre de usuario y contraseña estándar: openhab / habopen. Puedes conectarte con el comando:
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
O puede ver el archivo de registro:
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
Planeo cambiar el medidor de electricidad principal a un medidor de dos tarifas, según el cual la electricidad consumida en el rango de 23:00 a 07:00 se paga con un coeficiente de 0.5, por lo que me gustaría ver el efecto esperado y mantener una medición de dos tarifas. Al principio, simplemente agregué condiciones adicionales para tiempo a Artículos y Reglas y agregué las lecturas de día y de noche en dos tablas diferentes. Todo era hermoso en la base de datos, pero se veía torpe en el gráfico, ya que el gráfico conectaba los dos últimos valores con una línea recta:

Para divertir mi sentido de la belleza, tuve que molestarme un poco.
Entonces, el script final de Reglas para la contabilidad de dos tarifas se ve así:
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
Antes de editar el script, agregue los elementos necesarios:
Number sdm220_hourcounter_day (gSDM220) Number sdm220_hourcounter_night (gSDM220) Number sdm220_daycounter_day (gSDM220) Number sdm220_daycounter_night (gSDM220)
Ahora el diagrama de flujo horario y diario se ve así:

Eso es probablemente todo. También se planea agregar un cálculo de consumo de electricidad y dinero por mes para una tarifa diaria y nocturna y una generación de informes con envío por correo.