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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: protobin
3
- Version: 0.0.39
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.key)
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 = 8
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(8, 'big', signed=False)
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')
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "protobin"
7
- version = "0.0.39"
7
+ version = "0.0.41"
8
8
  authors = [
9
9
  { name="Daniel Robles", email="drm.electronic@gmail.com" },
10
10
  ]
@@ -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\x00\x00\xb6\xd6', binary)
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 = {'bus_number': '110', 'company': 'roma', 'route': 'IO37'}
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