Closed ghost closed 6 years ago
Given the format description in the picture, it should be easy to add the new format. You need to add a new frame type with the type identifier 0xA1 to the ServiceData
struct in structs/eddystone.py
and implement the new frame struct (version number, battery level, temp, hum and mac).
Then implement a new wrapper class in packet_types/eddystone.py
and add it to parser.py
.
I could also implement it myself, but I am quite busy at the moment. However, I am happy to assist you if you have further questions.
Thank you very much for your help, I will try tonight and come back if needed
For the moment I'm a struggling at creating the new frame structure with correct data type but I will try again during the week
After a couple of hours, I'm still blocked at some point, it seems that my frame is filtered at some points but I'm not able to understand why.
Here is what I have done, if you could give it a look it would be greate
I've added the new frame type in ServiceData:
ServiceData = Struct(
"eddystone_identifier" / Const(EDDYSTONE_UUID),
"frame_type" / Byte,
"frame" / Switch(lambda ctx: ctx.frame_type,
{
EDDYSTONE_UID_FRAME: EddystoneUIDFrame,
EDDYSTONE_URL_FRAME: EddystoneURLFrame,
EDDYSTONE_TLM_FRAME: EddystoneTLMFrame,
EDDYSTONE_EID_FRAME: EddystoneEIDFrame,
EDDYSTONE_HT_FRAME: HTFrame,
}
)
)
creating the frame type itself (types are probably wrong) :
HTFrame = Struct(
"version" / Int8ul,
"battery" / Int8ul,
"temperature" / Int16ub,
"humidity" / Int16ub,
"mac" / Array(16, Byte),
)
I've created the new frame struct in Packet_typeeddystone.py :
class HTFrame(object):
def __init__(self, data):
self._version = data['version']
self._battery = data['battery']
self._temperature = data['temperature']
self._humidity = data['humidity']
self._mac = data['mac']
@property
def version(self):
return self._version
@property
def battery(self):
return self._battery
@property
def temperature(self):
return self._temperature
@property
def humidity(self):
return self._humidity
@property
def mac(self):
return self._mac
def __str__(self):
return "HTFrame test : " + str(self._temperature)
I've modified the parser to include the new frame type :
def parse_eddystone_packet(packet):
"""Parse an eddystone beacon advertisement packet."""
try:
frame = EddystoneFrame.parse(packet)
for tlv in frame:
if tlv['type'] == SERVICE_DATA_TYPE:
data = tlv['value']
if data['frame_type'] == EDDYSTONE_UID_FRAME:
return EddystoneUIDFrame(data['frame'])
elif data['frame_type'] == 161:
return HTFrame(data['frame'])
elif data['frame_type'] == EDDYSTONE_TLM_FRAME:
if data['frame']['tlm_version'] == EDDYSTONE_TLM_ENCRYPTED:
return EddystoneEncryptedTLMFrame(data['frame']['data'])
elif data['frame']['tlm_version'] == EDDYSTONE_TLM_UNENCRYPTED:
return EddystoneTLMFrame(data['frame']['data'])
elif data['frame_type'] == EDDYSTONE_URL_FRAME:
return EddystoneURLFrame(data['frame'])
elif data['frame_type'] == EDDYSTONE_EID_FRAME:
return EddystoneEIDFrame(data['frame'])
except ConstructError:
return None
return None
Looks good so far. To calculate the real temperature and humidity you need to convert it to a fixed point decimal number in the getter methods. The reason why your packets are still filtered could be that your beacon uses another UUID. Currently, 0xaafe is hardcoded but yours seems to use 0xe1ff. Try adding a “ or Const(b”\xe1\xff”)” everywhere the uuid is used in eddystone.py. You also always dump the packet bytes and inspect them manually.
Thank you !
It works :)
Great! Please submit your changes as a pull request so that others can use them as well.
Hi I will do it next week
Any news on this?
this is wonderful but in case beacon ACC packet which changes do inside your repo...
Hello,
Sorry to bother you but I'm trying to read a decimal temperature from a Minew eddyston beacon.
I have the constructor documentation but I don't understand how to modify your code to read correctly the temperature. My question is probably basic but my knowledges are also very limited
Below is the data format, may I ask you if you have a few time to take a look and give me some hints on how to be able to read the temperature and maybe the humidity.
Thanks a lot anyway for your beacontools is great