Skip to content

Commit

Permalink
Add parser for tetonika_eye
Browse files Browse the repository at this point in the history
  • Loading branch information
Ernst79 committed Oct 5, 2023
1 parent 3787d42 commit 1ea18a4
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
11 changes: 11 additions & 0 deletions custom_components/ble_monitor/ble_parser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,13 @@ def parse_advertisement(
# Jaalee
sensor_data = parse_jaalee(self, man_spec_data, mac, rssi)
break
elif len(man_spec_data_list) == 2:
# Teltonika Eye (can send both iBeacon and Teltonika data in one message)
second_man_spec_data = man_spec_data_list[1]
second_comp_id = (second_man_spec_data[3] << 8) | second_man_spec_data[2]
if second_comp_id == 0x089A:
sensor_data = parse_teltonika(self, second_man_spec_data, local_name, mac, rssi)
break
else:
# iBeacon
sensor_data, tracker_data = parse_ibeacon(self, man_spec_data, mac, rssi)
Expand Down Expand Up @@ -325,6 +332,10 @@ def parse_advertisement(
man_spec_data = b"".join(man_spec_data_list)
sensor_data = parse_hormann(self, man_spec_data, mac, rssi)
break
elif comp_id == 0x089A:
# Teltonika
sensor_data = parse_teltonika(self, man_spec_data, local_name, mac, rssi)
break
elif comp_id == 0x094F and data_len == 0x15:
# Mikrotik
sensor_data = parse_mikrotik(self, man_spec_data, mac, rssi)
Expand Down
48 changes: 47 additions & 1 deletion custom_components/ble_monitor/ble_parser/teltonika.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ def parse_teltonika(self, data, complete_local_name, source_mac, rssi):
"""Teltonika parser"""
result = {"firmware": "Teltonika"}
teltonika_mac = source_mac
device_id = (data[3] << 8) | data[2]

if complete_local_name == "PUCK_T1":
if device_id == 0x089A:
device_type = "EYE sensor"
elif complete_local_name == "PUCK_T1":
device_type = "Blue Puck T"
elif complete_local_name == "PUCK_TH":
device_type = "Blue Puck RHT"
Expand Down Expand Up @@ -62,6 +65,49 @@ def parse_teltonika(self, data, complete_local_name, source_mac, rssi):
# Battery
(batt,) = unpack("<b", packet[5:6])
result.update({"battery": batt})
elif comp_id == 0x089A:
flags = packet[5]
sensor_data = packet[6:]
if flags & (1 << 0): # bit 0
# Temperature
(temp,) = unpack(">h", sensor_data[0:2])
result.update({"temperature": temp / 100})
sensor_data = sensor_data[2:]
if flags & (1 << 1): # bit 1
# Humidity
humi = sensor_data[0]
result.update({"humidity": humi})
sensor_data = sensor_data[1:]
if flags & (1 << 2): # bit 2
# Magnetic sensor presence
if flags & (1 << 3): # bit 3
# magnetic field is detected
result.update({"magnetic field": 1})
else:
# magnetic field is not detected
result.update({"magnetic field": 0})
if flags & (1 << 4): # bit 4
# Movement sensor counter
# Most significant bit indicates movement state
# 15 least significant bits represent count of movement events.
movement = sensor_data[0] & (1 << 7)
count = ((sensor_data[0] & 0b01111111) << 8) + sensor_data[1]
result.update({"movement": movement, "count": count})
sensor_data = sensor_data[2:]
if flags & (1 << 5): # bit 5
# Movement sensor angle
# Most significant byte – pitch (-90/+90)
# Two least significant bytes – roll (-180/+180)
(pitch, roll,) = unpack(">bh", sensor_data[0:3])
result.update({"roll": roll, "pitch": pitch})
sensor_data = sensor_data[3:]
if flags & (1 << 6): # bit 6
# Low battery indication sensor presence
result.update({"low battery": 1})
if flags & (1 << 7): # bit 7
# Battery voltage value presence
volt = round(2.0 + sensor_data[0] * 0.01, 3)
result.update({"voltage": volt})
data_size -= packet_size
packet_start += packet_size

Expand Down
23 changes: 23 additions & 0 deletions custom_components/ble_monitor/test/test_teltonika.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,26 @@ def test_ela_blue_puck_T_with_batt(self):
assert sensor_msg["temperature"] == 27.12
assert sensor_msg["battery"] == 13
assert sensor_msg["rssi"] == -35

def test_teltonika_eye(self):
"""Test Teltonika parser for Teltonika Eye sensor."""
data_string = "043E46020103001897035ECFD03a0201061AFF4C000215FFFFFFFF0B8C404510C655AAB636EBEFBB700055020C094D50315F313233343536370EFF9A0801B708B4120CCB0BFFC767DD"
data = bytes(bytearray.fromhex(data_string))
# pylint: disable=unused-variable
ble_parser = BleParser()
sensor_msg, tracker_msg = ble_parser.parse_raw_data(data)

assert sensor_msg["firmware"] == "Teltonika"
assert sensor_msg["type"] == "EYE sensor"
assert sensor_msg["mac"] == "D0CF5E039718"
assert sensor_msg["packet"] == "no packet id"
assert sensor_msg["data"]
assert sensor_msg["temperature"] == 22.28
assert sensor_msg["humidity"] == 18
assert sensor_msg["magnetic field"] == 0
assert sensor_msg["movement"] == 0
assert sensor_msg["count"] == 3275
assert sensor_msg["roll"] == -57
assert sensor_msg["pitch"] == 11
assert sensor_msg["voltage"] == 3.03
assert sensor_msg["rssi"] == -35

0 comments on commit 1ea18a4

Please sign in to comment.