...
 
Commits (12)
This diff is collapsed.
......@@ -115,8 +115,26 @@ class TempHumSensor(EEP):
class A5_04_01(TempHumSensor): min = 0; max = 40
class A5_04_02(TempHumSensor): min = -20; max = 60
class A5_08_01(EEP):
fields = ['voltage', 'illumination', 'temperature', 'pir', 'occupancy']
@classmethod
def decode(cls, data):
return {
'voltage': 5.1 * data[0] / 255,
'illumination': 510 * data[1] / 255,
'temperature': 51 * data[2] / 255,
'pir': not bool(data[3] & 0x02),
'occupancy': not bool(data[3] & 0x01),
}
class MeterReading(EEP):
"""Base for the A5-12 subtypes"""
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.fields = [(i, cls.cum) for i in range(16)] + [(i, cls.cur) for i in range(16)]
@classmethod
def decode(cls, data):
value = (data[0] << 16) + (data[1] << 8) + data[2]
......
......@@ -343,14 +343,31 @@ class EltakoDiscoveryReply(EltakoMessage):
eltakomessage = super().parse(data)
if eltakomessage.org != cls.org or eltakomessage.is_request != cls.is_request or eltakomessage.address != cls.address:
raise ParseError("This is not an EltakoDiscoveryReply")
try:
is_fam = {0x00: True, 0x08: False}[eltakomessage.payload[3]]
except KeyError:
classifierbyte = eltakomessage.payload[3]
if classifierbyte == 0x00:
is_fam = True
double_size = False
elif classifierbyte == 0x08:
is_fam = False
double_size = False
elif classifierbyte == 0x0e:
# Quite odd a situation, so far only seen on FDG14
is_fam = False
double_size = True
else:
raise ParseError("Assumed fixed part 00 or 08 not present (found %02x)"%eltakomessage.payload[3])
reported_address = eltakomessage.payload[0]
reported_size = eltakomessage.payload[1]
memory_size = eltakomessage.payload[2]
model = eltakomessage.payload[4:8]
if double_size:
reported_size *= 2
if model != bytes((0x04, 0x34, 0x41, 0x00)):
raise ParseError("Odd 0e byte (where 00 or 08 would be consistent with the rest of the ecosystem) found on something else than a FDG14, please verify whether 0e actually means 'this device is actually twice as large on the bus as it annouces'.")
return EltakoDiscoveryReply(reported_address, reported_size, memory_size, model, is_fam)
def __repr__(self):
......
#!/usr/bin/env python3
import setuptools
extras_require = {
'serial': ['pyserial_asyncio', 'pyserial >= 3.4'],
'coap': ['aiocoap == 0.4a1'],
# Not usable yet as it's not exported via an entry point
'eltakotool': ['pyyaml', 'pyxdg'],
}
setuptools.setup(
name="eltakobus",
version="0.0.3",
version="0.0.6",
author="chrysn",
author_email="chrysn@fsfe.org",
description="Library for participating in the Eltako Series 14 RS485 bus",
url="https://gitlab.com/chrysn/eltakobus",
packages=setuptools.find_packages(),
extras_require={
'serial': ['pyserial_asyncio', 'pyserial >= 3.4'],
'coap': ['aiocoap == 0.4a1'],
# Not usable yet as it's not exported via an entry point
'eltakotool': ['pyyaml', 'pyxdg'],
},
extras_require=extras_require,
# Not that there'd be tests, but at least it fetches the right dependencies and syntax checks everything
tests_require=list(set(sum(extras_require.values(), []))),
classifiers=[
"Programming Language :: Python :: 3",
],
......