protobin 0.0.30__tar.gz → 0.0.32__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
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: protobin
3
- Version: 0.0.30
3
+ Version: 0.0.32
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
@@ -28,6 +28,7 @@ License: MIT License
28
28
  SOFTWARE. 1
29
29
  1. en.wikipedia.org
30
30
  en.wikipedia.org
31
+ License-File: LICENSE.txt
31
32
  Classifier: License :: OSI Approved :: MIT License
32
33
  Classifier: Operating System :: OS Independent
33
34
  Classifier: Programming Language :: Python :: 3
@@ -433,7 +433,10 @@ class TimeField(FieldBase):
433
433
  return bytes([0] * 2)
434
434
  elif isinstance(val, str):
435
435
  try:
436
- val = datetime.datetime.strptime(val, '%H:%M').time()
436
+ if len(val) > 5:
437
+ val = datetime.datetime.strptime(val, '%Y-%m-%d %H:%M:%S').time()
438
+ else:
439
+ val = datetime.datetime.strptime(val, '%H:%M').time()
437
440
  except:
438
441
  raise ValueError(f'Error in field "{self.key}", a datetime or time is expected but "{val}" is received')
439
442
 
@@ -25,6 +25,8 @@ class Format:
25
25
  input_mode = 'client' if server else 'server'
26
26
  output_mode = 'server' if server else 'client'
27
27
  for k, f in format[input_mode].items():
28
+ if 'type' not in f:
29
+ raise FormatError(f'Not found type in field {k} of format {name}')
28
30
  if f['type'] not in FIELD_MAP:
29
31
  raise FormatError(f'Invalid protobin type {f["type"]}')
30
32
  self.input_fields.append(FIELD_MAP[f['type']](k, f))
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "protobin"
7
- version = "0.0.30"
7
+ version = "0.0.32"
8
8
  authors = [
9
9
  { name="Daniel Robles", email="drm.electronic@gmail.com" },
10
10
  ]
@@ -0,0 +1,150 @@
1
+ {
2
+ "length": 8,
3
+ "crc": {"poly": "0x18005", "init": "0x0000", "reverse": true, "byte_order": "big", "size": 4},
4
+ "formats": {
5
+ "login": {
6
+ "crc": false,
7
+ "fields": {
8
+ "serial": {"type": "string", "length_size": 2}
9
+ }
10
+ },
11
+ "login_status": {
12
+ "crc": false,
13
+ "header": "P",
14
+ "fields": {
15
+ "bus_number": {"type": "string"},
16
+ "company": {"type": "string"},
17
+ "route": {"type": "string"}
18
+ }
19
+ },
20
+ "report": {
21
+ "codec": 8,
22
+ "fields": {
23
+ "positions": {"type": "array", "array": {
24
+ "time": {"type": "timestamp", "decimals": 3},
25
+ "priority": {"type": "unsigned", "bytes": 1},
26
+ "lng": {"type": "float", "bytes": 4, "decimals": 7},
27
+ "lat": {"type": "float", "bytes": 4, "decimals": 7},
28
+ "alt": {"type": "unsigned", "bytes": 2},
29
+ "angle": {"type": "unsigned", "bytes": 2},
30
+ "satellites": {"type": "unsigned", "bytes": 1},
31
+ "speed": {"type": "unsigned", "bytes": 2},
32
+ "event_io": {"type": "unsigned", "bytes": 1},
33
+ "#events": {"type": "unsigned", "bytes": 1},
34
+ "events1b": {"type": "array", "array": {
35
+ "id": {"type": "id", "bytes": 1},
36
+ "value": {"type": "unsigned", "bytes": 1
37
+ }}
38
+ },
39
+ "events2b": {"type": "array", "array": {
40
+ "id": {"type": "id", "bytes": 1},
41
+ "value": {"type": "unsigned", "bytes": 2}
42
+ }},
43
+ "events4b": {"type": "array", "array": {
44
+ "id": {"type": "id", "bytes": 1},
45
+ "value": {"type": "unsigned", "bytes": 4}
46
+ }},
47
+ "events8b": {"type": "array", "array": {
48
+ "id": {"type": "id", "bytes": 1},
49
+ "value": {"type": "unsigned", "bytes": 8}
50
+ }}
51
+ }},
52
+ "#reports": {"type": "unsigned", "bytes": 1}
53
+ }
54
+ },
55
+ "report_ack": {
56
+ "crc": false,
57
+ "fields": {
58
+ "positions": {"bytes": 4, "type": "unsigned"}
59
+ }
60
+ },
61
+ "STATUS": {
62
+ "crc": false,
63
+ "header": "ST",
64
+ "fields": {
65
+ "status": {"type": "char"},
66
+ "direction": {"type": "char"},
67
+ "next_control": {"type": "string"},
68
+ "next_time": {"type": "string", "bytes": 5},
69
+ "previous_control": {"type": "string"},
70
+ "delay": {"type": "signed", "bytes": 1},
71
+ "back_control": {"type": "string"},
72
+ "datero_bus_0": {"type": "unsigned", "bytes": 2},
73
+ "datero_dif_0": {"type": "unsigned", "bytes": 1},
74
+ "datero_bus_1": {"type": "unsigned", "bytes": 2},
75
+ "datero_dif_1": {"type": "unsigned", "bytes": 1},
76
+ "datero_bus_2": {"type": "unsigned", "bytes": 2},
77
+ "datero_dif_2": {"type": "unsigned", "bytes": 1},
78
+ "datero_bus_3": {"type": "unsigned", "bytes": 2},
79
+ "datero_dif_3": {"type": "unsigned", "bytes": 1},
80
+ "datero_bus_4": {"type": "unsigned", "bytes": 2},
81
+ "datero_dif_4": {"type": "unsigned", "bytes": 1},
82
+ "datero_bus_5": {"type": "unsigned", "bytes": 2},
83
+ "datero_dif_5": {"type": "unsigned", "bytes": 1}
84
+ }
85
+ },
86
+ "status1": {
87
+ "header": "S",
88
+ "fields": {
89
+ "status": {"type": "char"},
90
+ "direction": {"type": "char"},
91
+ "next_control": {"type": "string"},
92
+ "next_time": {"type": "string", "bytes": 5},
93
+ "previous_control": {"type": "string"},
94
+ "delay": {"type": "signed", "bytes": 1},
95
+ "back_control": {"type": "string"},
96
+ "datero_bus_0": {"type": "unsigned", "bytes": 2},
97
+ "datero_dif_0": {"type": "unsigned", "bytes": 1},
98
+ "datero_bus_1": {"type": "unsigned", "bytes": 2},
99
+ "datero_dif_1": {"type": "unsigned", "bytes": 1},
100
+ "datero_bus_2": {"type": "unsigned", "bytes": 2},
101
+ "datero_dif_2": {"type": "unsigned", "bytes": 1},
102
+ "datero_bus_3": {"type": "unsigned", "bytes": 2},
103
+ "datero_dif_3": {"type": "unsigned", "bytes": 1},
104
+ "datero_bus_4": {"type": "unsigned", "bytes": 2},
105
+ "datero_dif_4": {"type": "unsigned", "bytes": 1},
106
+ "datero_bus_5": {"type": "unsigned", "bytes": 2},
107
+ "datero_dif_5": {"type": "unsigned", "bytes": 1}
108
+ }
109
+ },
110
+ "status3": {
111
+ "header": "s",
112
+ "fields": {
113
+ "status": {"type": "char"},
114
+ "direction": {"type": "char"},
115
+ "next_next_control": {"type": "string"},
116
+ "next_next_time": {"type": "string", "bytes": 5},
117
+ "next_control": {"type": "string"},
118
+ "next_time": {"type": "string", "bytes": 5},
119
+ "previous_control": {"type": "string"},
120
+ "delay": {"type": "signed", "bytes": 1},
121
+ "front_control": {"type": "string"},
122
+ "back_control": {"type": "string"},
123
+ "back_back_control": {"type": "string"},
124
+ "datero_bus_-1": {"type": "unsigned", "bytes": 2},
125
+ "datero_dif_-1": {"type": "unsigned", "bytes": 1},
126
+ "datero_bus_0": {"type": "unsigned", "bytes": 2},
127
+ "datero_dif_0": {"type": "unsigned", "bytes": 1},
128
+ "datero_bus_1": {"type": "unsigned", "bytes": 2},
129
+ "datero_dif_1": {"type": "unsigned", "bytes": 1},
130
+ "datero_bus_2": {"type": "unsigned", "bytes": 2},
131
+ "datero_dif_2": {"type": "unsigned", "bytes": 1},
132
+ "datero_bus_3": {"type": "unsigned", "bytes": 2},
133
+ "datero_dif_3": {"type": "unsigned", "bytes": 1},
134
+ "datero_bus_4": {"type": "unsigned", "bytes": 2},
135
+ "datero_dif_4": {"type": "unsigned", "bytes": 1},
136
+ "datero_bus_5": {"type": "unsigned", "bytes": 2},
137
+ "datero_dif_5": {"type": "unsigned", "bytes": 1}
138
+ }
139
+ },
140
+ "command": {
141
+ "codec": 12,
142
+ "fields": {
143
+ "commands": {"type": "array", "array": {
144
+ "value": {"type": "string"}
145
+ }},
146
+ "#commands": {"bytes": 1, "type": "unsigned"}
147
+ }
148
+ }
149
+ }
150
+ }
@@ -451,10 +451,10 @@ report:
451
451
  'order': 5,
452
452
  'logged': False,
453
453
  'data': None,
454
- 'schedule': datetime.time(11, 15)
454
+ 'schedule': None
455
455
  }
456
456
  binary = server.encode(data, 'login')
457
- print('server', binary)
457
+ print(f'server ({len(binary)})', binary)
458
458
  header, recv = client.decode(binary)
459
459
  self.assertEqual(header, 'login')
460
460
  self.assertEqual(data, recv)
@@ -645,6 +645,22 @@ report:
645
645
  header, recv = client.decode(binary)
646
646
  print(header, recv)
647
647
 
648
+ def test_decode_sergio(self):
649
+ val = {'id': '675882972c030d7f86188ee9', 'command': 'C', 'value': 'value'}
650
+ client = Protocol(js={"formats": {"command": {
651
+ "header": "$",
652
+ "server": {
653
+ "comando": {"bytes": 1, "type": "char"},
654
+ "id": {"bytes": 0, "type": "string"},
655
+ "value": {"bytes": 0, "type": "string"}
656
+ },
657
+ "client": {
658
+ "id": {"bytes": 0, "type": "string"}
659
+ }
660
+ }}}, server=True)
661
+ binary = client.encode(val, 'command')
662
+ print(binary)
663
+
648
664
  def test_singleton(self):
649
665
  protocol1 = ProtobinLoader('codec8.json')
650
666
  protocol2 = ProtobinLoader('codec8.json')
@@ -654,3 +670,24 @@ report:
654
670
  protocol6 = ProtobinLoader('demo.json', server=True)
655
671
  protocol7 = ProtobinLoader('demo.json', server=True)
656
672
  protocol8 = ProtobinLoader('demo.json', server=True)
673
+
674
+ def test_error_type(self):
675
+ with self.assertRaises(FormatError):
676
+ Protocol(js={"formats": {"command": {
677
+ "header": "$",
678
+ "server": {
679
+ "comando": {"bytes": 1, "type": "char"},
680
+ "id": {"bytes": 0, "type": "string"},
681
+ "value": {"bytes": 0, "type": "string"}
682
+ },
683
+ "client": {
684
+ "id": {"bytes": 0}
685
+ }
686
+ }}}, server=True)
687
+
688
+ def test_teltonika_binary(self):
689
+ binary = b'\x00\x00\x00\x00\x00\x00\x04\x1d\x08#\x00\x00\x01\x93x\xb7T\xc8\x00\xd2\x0f\xa2\xd0\xf8\xdbz\x81\x00s\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xb7\xa2\xe8\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xb7\xf1\x08\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xb8?(\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xb8\x8dH\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xbae\xf0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xbc6\xc8\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xbe\x0fp\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xbf\xe40\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xc1\xb8\xf0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xc3\x91\x98\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xc5bp\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xc7;\x18\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xc9\x13\xc0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xca\xe4\x98\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xcc\xbd@\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xce\x92\x00\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xd0f\xc0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xd2;\x80\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xd4\x10@\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xd5\xe8\xe8\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xd7\xbd\xa8\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xd9\x92h\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xdbg(\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xdd?\xd0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xdf\x14\x90\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xe0\xe9P\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xe2\xbe\x10\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xe4\x92\xd0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xe6kx\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xe8<P\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xea\x14\xf8\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xeb\xed\xa0\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xed\xbex\x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93x\xef\x97 \x00\xd2\x0f\xa5\x06\xf8\xdb{\x06\x00s\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00#\x00\x00v\x92'
690
+ client = Protocol(file='teltonika.json', server=None)
691
+ header, recv = client.decode(binary)
692
+ print(recv)
693
+
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes