Merge pull request #70 from bremme/master

Add SocketReader to connect to remote serial port
This commit is contained in:
Nigel Dokter 2021-11-21 18:10:17 +01:00 committed by GitHub
commit dc2f493739
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 111 additions and 0 deletions

View File

@ -46,6 +46,25 @@ process because the code is blocking (not asynchronous):
To be documented.
**Socket client**
Read a remote serial port (for example using ser2net) and work with the parsed telegrams.
It should be run in a separate process because the code is blocking (not asynchronous):
.. code-block:: python
from dsmr_parser import telegram_specifications
from dsmr_parser.clients import SocketReader
socket_reader = SocketReader(
host='127.0.0.1',
port=2001,
telegram_specification=telegram_specifications.V4
)
for telegram in socket_reader.read():
print(telegram) # see 'Telegram object' docs below
Parsing module usage
--------------------

View File

@ -1,5 +1,6 @@
from dsmr_parser.clients.settings import SERIAL_SETTINGS_V2_2, \
SERIAL_SETTINGS_V4, SERIAL_SETTINGS_V5
from dsmr_parser.clients.serial_ import SerialReader, AsyncSerialReader
from dsmr_parser.clients.socket_ import SocketReader
from dsmr_parser.clients.protocol import create_dsmr_protocol, \
create_dsmr_reader, create_tcp_dsmr_reader

View File

@ -0,0 +1,91 @@
import logging
import socket
from dsmr_parser.clients.telegram_buffer import TelegramBuffer
from dsmr_parser.exceptions import ParseError, InvalidChecksumError
from dsmr_parser.parsers import TelegramParser
from dsmr_parser.objects import Telegram
logger = logging.getLogger(__name__)
class SocketReader(object):
BUFFER_SIZE = 256
def __init__(self, host, port, telegram_specification):
self.host = host
self.port = port
self.telegram_parser = TelegramParser(telegram_specification)
self.telegram_buffer = TelegramBuffer()
self.telegram_specification = telegram_specification
def read(self):
"""
Read complete DSMR telegram's from remote interface and parse it
into CosemObject's and MbusObject's
:rtype: generator
"""
buffer = b""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_handle:
socket_handle.connect((self.host, self.port))
while True:
buffer += socket_handle.recv(self.BUFFER_SIZE)
lines = buffer.splitlines(keepends=True)
if len(lines) == 0:
continue
for data in lines:
self.telegram_buffer.append(data.decode('ascii'))
for telegram in self.telegram_buffer.get_all():
try:
yield self.telegram_parser.parse(telegram)
except InvalidChecksumError as e:
logger.warning(str(e))
except ParseError as e:
logger.error('Failed to parse telegram: %s', e)
buffer = b""
def read_as_object(self):
"""
Read complete DSMR telegram's from remote and return a Telegram object.
:rtype: generator
"""
buffer = b""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_handle:
socket_handle.connect((self.host, self.port))
while True:
buffer += socket_handle.recv(self.BUFFER_SIZE)
lines = buffer.splitlines(keepends=True)
if len(lines) == 0:
continue
for data in lines:
self.telegram_buffer.append(data.decode('ascii'))
for telegram in self.telegram_buffer.get_all():
try:
yield Telegram(telegram, self.telegram_parser, self.telegram_specification)
except InvalidChecksumError as e:
logger.warning(str(e))
except ParseError as e:
logger.error('Failed to parse telegram: %s', e)
buffer = b""