protobin 0.0.39__tar.gz → 0.0.41__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {protobin-0.0.39 → protobin-0.0.41}/PKG-INFO +1 -1
- {protobin-0.0.39 → protobin-0.0.41}/protobin/fields.py +3 -3
- {protobin-0.0.39 → protobin-0.0.41}/pyproject.toml +1 -1
- {protobin-0.0.39 → protobin-0.0.41}/tests/demo.json +10 -0
- {protobin-0.0.39 → protobin-0.0.41}/tests/teltonika.json +8 -0
- {protobin-0.0.39 → protobin-0.0.41}/tests/tests.py +78 -2
- {protobin-0.0.39 → protobin-0.0.41}/.gitignore +0 -0
- {protobin-0.0.39 → protobin-0.0.41}/LICENSE.txt +0 -0
- {protobin-0.0.39 → protobin-0.0.41}/README.md +0 -0
- {protobin-0.0.39 → protobin-0.0.41}/protobin/__init__.py +0 -0
- {protobin-0.0.39 → protobin-0.0.41}/protobin/errors.py +0 -0
- {protobin-0.0.39 → protobin-0.0.41}/protobin/interfaces.py +0 -0
- {protobin-0.0.39 → protobin-0.0.41}/protobin/protocol.py +0 -0
- {protobin-0.0.39 → protobin-0.0.41}/protobin/singleton.py +0 -0
- {protobin-0.0.39 → protobin-0.0.41}/tests/codec8.json +0 -0
- {protobin-0.0.39 → protobin-0.0.41}/tests/demo.yaml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: protobin
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.41
|
|
4
4
|
Summary: Python library for encode and decode data in protobin format
|
|
5
5
|
Project-URL: Homepage, https://github.com/drmelectronic/protobin-python
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/drmelectronic/protobin-python/issues
|
|
@@ -299,7 +299,7 @@ class FlagsField(FieldBase):
|
|
|
299
299
|
def __init__(self, k, js):
|
|
300
300
|
super().__init__(k, js)
|
|
301
301
|
self.keys = self.key.split(',')
|
|
302
|
-
self.length = len(self.
|
|
302
|
+
self.length = len(self.keys)
|
|
303
303
|
self.bytes = math.ceil(self.length / 8)
|
|
304
304
|
|
|
305
305
|
def __repr__(self):
|
|
@@ -463,7 +463,7 @@ class TimestampField(FieldBase):
|
|
|
463
463
|
|
|
464
464
|
def __init__(self, k, js):
|
|
465
465
|
super().__init__(k, js)
|
|
466
|
-
self.bytes =
|
|
466
|
+
self.bytes = js.get('bytes', 6)
|
|
467
467
|
self.decimals = js.get('decimals', 6)
|
|
468
468
|
|
|
469
469
|
def __repr__(self):
|
|
@@ -475,7 +475,7 @@ class TimestampField(FieldBase):
|
|
|
475
475
|
if val is None:
|
|
476
476
|
return bytes([0] * 8)
|
|
477
477
|
timestamp = val.timestamp() * (10 ** self.decimals)
|
|
478
|
-
return int(timestamp).to_bytes(
|
|
478
|
+
return int(timestamp).to_bytes(self.bytes, 'big', signed=False)
|
|
479
479
|
|
|
480
480
|
def from_binary(self, binary):
|
|
481
481
|
d = int.from_bytes(binary, 'big')
|
|
@@ -64,6 +64,16 @@
|
|
|
64
64
|
"id": {"type": "string"},
|
|
65
65
|
"value": {"type": "string"}
|
|
66
66
|
}
|
|
67
|
+
},
|
|
68
|
+
"timestamp": {
|
|
69
|
+
"header": "#T",
|
|
70
|
+
"server": {
|
|
71
|
+
"faltantes": {"bytes": 4, "type": "unsigned"},
|
|
72
|
+
"tabla": {"bytes": 1, "type": "char"}
|
|
73
|
+
},
|
|
74
|
+
"client": {
|
|
75
|
+
"timestamp":{"bytes": 6, "decimals": 3, "type": "timestamp"}
|
|
76
|
+
}
|
|
67
77
|
}
|
|
68
78
|
}
|
|
69
79
|
}
|
|
@@ -139,6 +139,14 @@
|
|
|
139
139
|
"datero_dif_5": {"type": "unsigned", "bytes": 1}
|
|
140
140
|
}
|
|
141
141
|
},
|
|
142
|
+
"message": {
|
|
143
|
+
"crc": false,
|
|
144
|
+
"crc_size": 2,
|
|
145
|
+
"header": "M",
|
|
146
|
+
"fields": {
|
|
147
|
+
"text": {"type": "string"}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
142
150
|
"command": {
|
|
143
151
|
"codec": 12,
|
|
144
152
|
"fields": {
|
|
@@ -134,6 +134,10 @@ class BasicTest(unittest.TestCase):
|
|
|
134
134
|
"header": "TS",
|
|
135
135
|
"fields": {'test': {'bytes': 8, 'type': 'timestamp'}}
|
|
136
136
|
},
|
|
137
|
+
'timestamp6': {
|
|
138
|
+
"header": "T6",
|
|
139
|
+
"fields": {'test': {'bytes': 6, "decimals": 3, 'type': 'timestamp'}}
|
|
140
|
+
},
|
|
137
141
|
'unsigned': {
|
|
138
142
|
"header": "u",
|
|
139
143
|
"fields": {'test': {'bytes': 3, 'type': 'unsigned'}}
|
|
@@ -290,6 +294,31 @@ class BasicTest(unittest.TestCase):
|
|
|
290
294
|
with self.assertRaises(ValueError) as er:
|
|
291
295
|
self.protocol.encode(data, 'unsigned')
|
|
292
296
|
|
|
297
|
+
protocol = Protocol(js={'formats': {
|
|
298
|
+
'unsigned': {
|
|
299
|
+
"header": "u",
|
|
300
|
+
"fields": {
|
|
301
|
+
"geofence": {"bytes": 2, "type": "unsigned"},
|
|
302
|
+
"orden": {"bytes": 1, "type": "unsigned"},
|
|
303
|
+
"delta": {"bytes": 1, "type": "unsigned"},
|
|
304
|
+
"origin": {"bytes": 2, "type": "unsigned"},
|
|
305
|
+
"id": {"bytes": 0, "type": "string"}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}})
|
|
309
|
+
data = {
|
|
310
|
+
"id": "11",
|
|
311
|
+
"orden": 0,
|
|
312
|
+
"origin": 57,
|
|
313
|
+
"delta": 5,
|
|
314
|
+
"geofence": 200
|
|
315
|
+
}
|
|
316
|
+
binary = protocol.encode(data, 'unsigned')
|
|
317
|
+
print(binary)
|
|
318
|
+
h, recv = protocol.decode(binary)
|
|
319
|
+
print(recv)
|
|
320
|
+
self.assertEqual(data, recv)
|
|
321
|
+
|
|
293
322
|
def test_id(self):
|
|
294
323
|
data = {'test': 254}
|
|
295
324
|
binary = self.protocol.encode(data, 'id')
|
|
@@ -318,6 +347,13 @@ class BasicTest(unittest.TestCase):
|
|
|
318
347
|
h, recv = self.protocol.decode(binary)
|
|
319
348
|
self.assertEqual(data, recv)
|
|
320
349
|
|
|
350
|
+
def test_timestamp6(self):
|
|
351
|
+
data = {'test': datetime.datetime(2025, 1, 24, 9, 18, 24, 896000)}
|
|
352
|
+
binary = self.protocol.encode(data, 'timestamp6')
|
|
353
|
+
print(binary)
|
|
354
|
+
h, recv = self.protocol.decode(binary)
|
|
355
|
+
self.assertEqual(data, recv)
|
|
356
|
+
|
|
321
357
|
def test_timestamp_null(self):
|
|
322
358
|
data = {'test': None}
|
|
323
359
|
binary = self.protocol.encode(data, 'timestamp')
|
|
@@ -635,7 +671,7 @@ report:
|
|
|
635
671
|
data = {'status': 'E', 'direction': 'A', 'next_next_control': '', 'next_next_time': ' ', 'next_control': '', 'next_time': ' ', 'previous_control': '', 'delay': 0, 'front_control': '', 'back_control': '', 'back_back_control': '', 'datero_bus_-1': 0, 'datero_dif_-1': 0, 'datero_bus_0': 0, 'datero_dif_0': 0, 'datero_bus_1': 0, 'datero_dif_1': 0, 'datero_bus_2': 0, 'datero_dif_2': 0, 'datero_bus_3': 256, 'datero_dif_3': 0, 'datero_bus_4': 0, 'datero_dif_4': 0, 'datero_bus_5': 0, 'datero_dif_5': 0}
|
|
636
672
|
client = Protocol(file='codec8.json')
|
|
637
673
|
binary = client.encode(data, 'status3')
|
|
638
|
-
self.assertEqual(b's=EA\x00 \x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\
|
|
674
|
+
self.assertEqual(b's=EA\x00 \x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xb6\xd6', binary)
|
|
639
675
|
header, recv = client.decode(binary)
|
|
640
676
|
self.assertEqual(data, recv)
|
|
641
677
|
|
|
@@ -723,7 +759,7 @@ report:
|
|
|
723
759
|
|
|
724
760
|
def test_teltonika_login(self):
|
|
725
761
|
client = Protocol(file='codec8.json', server=None)
|
|
726
|
-
data = {'
|
|
762
|
+
data = {'padron': '110', 'company': 'roma', 'route': 'IO37'}
|
|
727
763
|
binary = client.encode(data, 'login_status')
|
|
728
764
|
print(binary)
|
|
729
765
|
self.assertEqual(b'P=\x03110\x04roma\x04IO37\x19\x8f', binary)
|
|
@@ -735,3 +771,43 @@ report:
|
|
|
735
771
|
print(binary)
|
|
736
772
|
self.assertEqual(b'P=\x00\x08urbanito\x049802+\xbf', binary)
|
|
737
773
|
|
|
774
|
+
def test_message_teltonika(self):
|
|
775
|
+
data = {'text': 'prueba de mensaje'}
|
|
776
|
+
client = Protocol(file='teltonika.json', server=None)
|
|
777
|
+
binary = client.encode(data, 'message')
|
|
778
|
+
print(binary)
|
|
779
|
+
self.assertEqual(binary, b'M=\x11prueba de mensaje48')
|
|
780
|
+
|
|
781
|
+
def test_history_geofence_ms(self):
|
|
782
|
+
codec = {
|
|
783
|
+
"formats":{
|
|
784
|
+
"history_geofence_ms": {
|
|
785
|
+
"header": "$",
|
|
786
|
+
"fields": {
|
|
787
|
+
"items": {
|
|
788
|
+
"type": "array",
|
|
789
|
+
"array": {
|
|
790
|
+
"id": {"bytes": 2, "type": "unsigned"},
|
|
791
|
+
"orden" : {"bytes": 1, "type": "unsigned"},
|
|
792
|
+
"longitud": {"bytes": 4, "type": "float", "decimals": 6},
|
|
793
|
+
"latitud": {"bytes": 4, "type": "float", "decimals": 6},
|
|
794
|
+
"radio": {"bytes": 2, "type": "unsigned"},
|
|
795
|
+
"ruta": {"bytes": 1, "type": "unsigned"},
|
|
796
|
+
"lado,control,datear,activo": {"type": "flags"},
|
|
797
|
+
"nombre": {"bytes": 15, "type": "char"},
|
|
798
|
+
"timestamp":{"bytes": 6, "decimals": 3, "type": "timestamp"},
|
|
799
|
+
"type": {"bytes": 1, "type": "char"}
|
|
800
|
+
}
|
|
801
|
+
},
|
|
802
|
+
"next": {"bytes": 1, "type": "char"}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
data = {'items': [{'id': 2, 'lado': False, 'ruta': 2, 'audio': 'HU', 'orden': 8, 'radio': 70, 'activo': True, 'datear': True, 'nombre': 'FINAL', 'control': True, 'latitud': -12.0627343, 'retorno': True, 'sagrado': False, 'longitud': -77.0153672, 'terminal': True, 'timestamp': datetime.datetime(2020, 7, 27, 14, 12, 14, 486000), 'refrecuenciar': False, 'type': '+', 'tabla': 'G'}, {'id': 5, 'lado': False, 'ruta': 2, 'audio': 'UN', 'orden': 2, 'radio': 70, 'activo': True, 'datear': True, 'nombre': 'UNIVERITARIA', 'control': True, 'latitud': -12.0500755, 'retorno': False, 'sagrado': False, 'longitud': -77.0772618, 'terminal': False, 'timestamp': datetime.datetime(2020, 7, 27, 14, 12, 14, 518000), 'refrecuenciar': False, 'type': '+', 'tabla': 'G'}, {'id': 6, 'lado': False, 'ruta': 2, 'audio': 'CA', 'orden': 3, 'radio': 70, 'activo': True, 'datear': True, 'nombre': 'CARCAMO', 'control': True, 'latitud': -12.0472635, 'retorno': False, 'sagrado': False, 'longitud': -77.0508689, 'terminal': False, 'timestamp': datetime.datetime(2020, 7, 27, 14, 12, 14, 528000), 'refrecuenciar': False, 'type': '+', 'tabla': 'G'}, {'id': 7, 'lado': False, 'ruta': 2, 'audio': '2 ', 'orden': 4, 'radio': 70, 'activo': True, 'datear': True, 'nombre': '2 DE MAYO', 'control': True, 'latitud': -12.0465238, 'retorno': False, 'sagrado': False, 'longitud': -77.043466, 'terminal': False, 'timestamp': datetime.datetime(2020, 7, 27, 14, 12, 14, 536000), 'refrecuenciar': False, 'type': '+', 'tabla': 'G'}, {'id': 8, 'lado': False, 'ruta': 2, 'audio': 'PL', 'orden': 5, 'radio': 70, 'activo': True, 'datear': True, 'nombre': 'PLAZA SAN MARTIN', 'control': True, 'latitud': -12.0511405, 'retorno': False, 'sagrado': False, 'longitud': -77.0355159, 'terminal': False, 'timestamp': datetime.datetime(2020, 7, 27, 14, 12, 14, 544000), 'refrecuenciar': False, 'type': '+', 'tabla': 'G'}, {'id': 13, 'lado': True, 'ruta': 2, 'audio': 'AB', 'orden': 4, 'radio': 70, 'activo': True, 'datear': True, 'nombre': 'ABANCAY', 'control': True, 'latitud': -12.0547289, 'retorno': False, 'sagrado': False, 'longitud': -77.0298779, 'terminal': False, 'timestamp': datetime.datetime(2020, 7, 27, 14, 12, 14, 585000), 'refrecuenciar': False, 'type': '+', 'tabla': 'G'}, {'id': 14, 'lado': True, 'ruta': 2, 'audio': 'PL', 'orden': 5, 'radio': 70, 'activo': True, 'datear': True, 'nombre': 'PLAZA SAN MARTIN', 'control': True, 'latitud': -12.0520219, 'retorno': False, 'sagrado': False, 'longitud': -77.0339656, 'terminal': False, 'timestamp': datetime.datetime(2020, 7, 27, 14, 12, 14, 593000), 'refrecuenciar': False, 'type': '+', 'tabla': 'G'}, {'id': 15, 'lado': True, 'ruta': 2, 'audio': '2 ', 'orden': 6, 'radio': 70, 'activo': True, 'datear': True, 'nombre': '2 DE MAYO', 'control': True, 'latitud': -12.0467074, 'retorno': False, 'sagrado': False, 'longitud': -77.0421463, 'terminal': False, 'timestamp': datetime.datetime(2020, 7, 27, 14, 12, 14, 601000), 'refrecuenciar': False, 'type': '+', 'tabla': 'G'}, {'id': 17, 'lado': True, 'ruta': 2, 'audio': 'TE', 'orden': 9, 'radio': 70, 'activo': True, 'datear': True, 'nombre': 'TERMINAL', 'control': True, 'latitud': -12.0492046, 'retorno': False, 'sagrado': False, 'longitud': -77.088908, 'terminal': True, 'timestamp': datetime.datetime(2020, 7, 27, 14, 12, 14, 618000), 'refrecuenciar': False, 'type': '+', 'tabla': 'G'}], 'next': 'P'}
|
|
808
|
+
client = Protocol(js=codec, server=None)
|
|
809
|
+
binary = client.encode(data, 'history_geofence_ms')
|
|
810
|
+
rasp = b'$=\t\x00\x02\x08\xfbh\xd6\xb9\xffG\xef\xf2\x00F\x02\x07FINAL \x01s\x91\xb0\x90\x96+\x00\x05\x02\xfbg\xe4\xf2\xffH!d\x00F\x02\x07UNIVERITARIA \x01s\x91\xb0\x90\xb6+\x00\x06\x03\xfbhL\x0b\xffH,`\x00F\x02\x07CARCAMO \x01s\x91\xb0\x90\xc0+\x00\x07\x04\xfbhh\xf6\xffH/D\x00F\x02\x072 DE MAYO \x01s\x91\xb0\x90\xc8+\x00\x08\x05\xfbh\x88\x04\xffH\x1d<\x00F\x02\x07PLAZA SAN MARTI\x01s\x91\xb0\x90\xd0+\x00\r\x04\xfbh\x9e\n\xffH\x0f7\x00F\x02\x0fABANCAY \x01s\x91\xb0\x90\xf9+\x00\x0e\x05\xfbh\x8e\x12\xffH\x19\xca\x00F\x02\x0fPLAZA SAN MARTI\x01s\x91\xb0\x91\x01+\x00\x0f\x06\xfbhn\x1e\xffH.\x8d\x00F\x02\x0f2 DE MAYO \x01s\x91\xb0\x91\t+\x00\x11\t\xfbg\xb7t\xffH$\xcb\x00F\x02\x0fTERMINAL \x01s\x91\xb0\x91\x1a+P'
|
|
811
|
+
self.assertEqual(binary, rasp)
|
|
812
|
+
h, recv = client.decode(binary)
|
|
813
|
+
print(recv)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|