Прочел в буклете про WB5, что поддерживаются счетчики Энергомера, но на странице поддерживаемого оборудования информации нет. Поддерживается ли такой счетчик CE102M-R5?
пока нет. Скоро будет поддержка трёхфазных счётчиков CE303. У CE102, кажется, другой протокол. Поддержка пока не планируется.
Всё это касается стандартого ПО Wiren Board. Вы, естественно, можете сторонним скриптом считать данные. Похоже, что-то такое на просторах интернета есть: https://github.com/search?q=energomera
Попробую сторонним скриптом считать, спасибо за ссылку!
Вообще, код реализации не выглядит чем-то запредельно сложным. Надеюсь, найдете несколько дней и добавите в будущем
#!/usr/bin/python
import time
import serial
import readline
import binascii
import logging
import re
import sys
import argparse
import os.path
import subprocess
import struct
def unhexlify(s):
s = re.sub(r'[^0-9a-fA-F]','',s)
return binascii.unhexlify(s)
def makehex(s):
print "MAKEHEX get %s" % s
send_str=''
for c in bytearray(s):
cint =int(c)
cint &=0x7f
hvar=hex(cint)[2:4]
if len(hvar)==1:
hvar='0'+hvar
send_str+=hvar+' '
print "MAKEHEX make %s" % send_str
return send_str
def ask(serial,timeout,s):
send_bytes=unhexlify(makehex(s))
print "ASK send %s" % send_bytes
serial.write(send_bytes)
out=''
time.sleep(timeout)
while serial.inWaiting() > 0:
out += serial.read(1)
print "ASK get %s" % out
return out
def anspub(ans,subtop):
rs = re.findall('\((.*?)\)',ans)
print subtop+" ANSWER ",rs
for idx,cs in enumerate(rs):
topic="mosquitto_pub -t '/devices/energomera/controls/"+subtop+str(idx+1)+"' -m '"+str(cs)+"'"
print "SUBPROC CALL ",topic
subprocess.call(topic,shell='True')
return 1
def main():
parser = argparse.ArgumentParser(description='enerogemera whm poller',
add_help=True, formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-b', '--baud', dest='baud', type=int,
help='Baud rate', default=9600)
parser.add_argument('-p', '--parity', dest='parity', type=str,
help='set parity, one of [%s]' % ", ".join(serial.Serial.PARITIES), default='E')
parser.add_argument('-d', '--data-bits', dest='data_bits', type=int,
help='set number of data bits, i.e. bytesize', default=7)
parser.add_argument('-s', '--stop-bits', dest='stop_bits', type=float,
help='set number of stop bits, one of [%s]' % ", ".join(
str(x) for x in serial.Serial.STOPBITS
), default=1)
parser.add_argument('-t', '--timeout', dest='read_timeout', type=float,
help='number of seconds to wait for answer', default=1)
parser.add_argument('-a', '--address', dest='read_address', type=str,
help='device address to connect', default='777777')
parser.add_argument('-P', '--PORT', dest='port', type=str,
help='Serial port to open, i.e. /dev/ttyXXX', default='/dev/ttyAPP4')
args = parser.parse_args()
if args.baud not in serial.Serial.BAUDRATES:
print "incorrect baudrate %d" % args.baud
return 1
if args.parity not in serial.Serial.PARITIES:
print "incorrect parity %d" % args.partity
return 1
if args.stop_bits not in serial.Serial.STOPBITS:
print "incorrect stop bits setting %d" % args.stop_bits
return 1
if not args.read_address:
print "no device address %s" % args.read_address
return 1
if not args.port:
print "no PORT to connect %s" % args.port
return 1
ser = serial.Serial(
port=args.port,
baudrate=args.baud,
parity=args.parity,
stopbits=args.stop_bits,
bytesize=args.data_bits)
print "serial Energomera WHM adr=%s on %s: %d %s%s%s" % (
args.read_address,
ser.portstr,
ser.baudrate,
ser.bytesize,
ser.parity,
ser.stopbits)
ans=ask(ser,args.read_timeout,'/?'+args.read_address+'!\r\n')
if ans != '':
ans=ask(ser,args.read_timeout,chr(6)+'051\r\n')
if ans != '':
ans=ask(ser,args.read_timeout,chr(1)+'R1'+chr(2)+'POWEP()'+chr(3)+'d')
if ans != '':
anspub(ans,'power')
ans=ask(ser,args.read_timeout,chr(1)+'R1'+chr(2)+'ET0PE()'+chr(3)+'7')
if ans != '':
anspub(ans,'energy')
ans=ask(ser,args.read_timeout,chr(1)+'R1'+chr(2)+'CURRE()'+chr(3)+'Z')
if ans != '':
anspub(ans,'current')
ans=ask(ser,args.read_timeout,chr(1)+'R1'+chr(2)+'VOLTA()'+chr(3)+'_')
if ans != '':
anspub(ans,'voltage')
ans=ask(ser,args.read_timeout,chr(1)+'B0'+chr(3)+'u')
return 1
print "Energomera answer timeout"
return 0
if __name__ == '__main__':
rc = main()
sys.exit(rc)
вобщем хотел простенький скрипт на питоне для опроса энергомеры приложить - чего-то не понял как это вышло так…ну разберетесь если надо - работает давно на WB5 запуск по крону
Добрый день, Евгений! а ориентировочные сроки можете сказать?
а то реально, на объект пытались найти Меркурий поставить, но к нам их ни кто не возит (еще и проблема часового пояса)
спасибо!
Спасибо! Как счетчик привезут, протестирую. Немного удивило, что многие на Питоне пишут. А официальные адаптеры на чем пишутся?
Лучше сначала подключиться к счетчику штатной программой через преобразователь в rs485, убедиться в настройках интерфейса и адресации, в принципе если счетчик один то отвечает без адреса, можно скрипт подправить…
добрый день!
нет информации?
пока нет
как это сделать? поставил admin tools 11, а там нет 485 канала связи…
ээ, к программе существует руководство оператора - там все написано…
Наконец-то дошли руки до скрипта. Как понимаю, счетчик нужно регистрировать как serial device с указанием id и device type. Откуда взять эти значения?
Пока что запуск выглядит так:
serial Energomera WHM adr=777777 on /dev/ttyRS485-2: 9600 7E1
MAKEHEX get /?777777!
MAKEHEX make 2f 3f 37 37 37 37 37 37 21 0d 0a
ASK send /?777777!
ASK get
Energomera answer timeout
Это только в случае наличия шаблона (и поддержки) счетчика.
Если напишете шаблон - то можно так, да.
Используемый для подключения порт свободен в wb-mqtt-serail?
Для уверенности - остановите его перед экспериментами.
systemctl stop wb-mqtt-serial
Скорее всего этот скрипт для счетчика CE102, а не CE102M, у которого другой протокол. С CE102M работает этот скрипт Считывание показаний и программирование электросчетчика "Энергомера СЕ102М" по rs-485, только таймаут нужно больше 0,2 с выставить.
Полученные значения периодически отправляю в топики. Напр.:
mosquitto_pub -t '/devices/energomera-ce102m/controls/VOLTA' -m '209.52'
В веб-интерфейсе данные видны
Вопрос. Как это описать в шаблоне? Откуда взять поле address? Или по-другому всё делается?
Счетчик, этот счетчик, не через modbus rtu работает- для него шаблон не напишешь.
А разве нельзя эмулировать modbus на самом контроллере? Создать виртуальное устройство, например, и к нему обращаться как к реальному? Или как-то получать эти данные в js-скрипте другим способом?
Модбас - это просто транспорт. Данные - хранятся в mqtt топиках. Если скрипт на питоне туда их уже поместил - то к ним уже можно обратиться. Для удобства - да, можно создать еще и виртуальное устройство Но оно всего лишь служит для отображения mqtt.
На самом деле устройство и так автоматически создается, когда в mqtt-топик приходят данные, так что виртуальное устройство будет лишь его дублировать, так что я присвоил типы с помощью мета-топиков
И ещё питоновский скрипт получает и передает данные от счетчика с некоторой периодичностью. Какую частоту опроса принято выставлять для электрических счетчиков? Раз в секунду, чаще, реже?
Исключительно в зависимости от потребностей. Мне, например, для графиков достаточно значений вообще раз в минуту.
Если нужно засекать пики потребления - то чаще.