Add additional checks when parsing custom field list, add additional divide by 10 and 100 converters

pull/47/head
Mark Jessop 2021-09-11 22:21:02 +09:30
rodzic 6e86c3e559
commit 7a1b174bdf
5 zmienionych plików z 83 dodań i 38 usunięć

Wyświetl plik

@ -19,17 +19,13 @@
]
},
"4FSKTEST-V2": {
"struct": "<BBBBBBBBB",
"struct": "<BfBBH",
"fields": [
["test_field 1", "none"],
["test_field 2", "none"],
["test_field 3", "none"],
["test_field 4", "none"],
["test_field 5", "none"],
["test_field 6", "none"],
["test_field 7", "none"],
["test_field 8", "none"],
["test_field 9", "none"]
["test_field 3", "battery_5v_byte"],
["test_field 4", "divide_by_10"],
["test_field 5", "divide_by_100"]
]
}
}

Wyświetl plik

@ -1 +1 @@
__version__ = "0.2.2"
__version__ = "0.2.3"

Wyświetl plik

@ -141,13 +141,39 @@ def decode_battery_5v_byte(data: int) -> str:
return (_batt, f"{_batt:.2f}")
def decode_divide_by_10(data: int) -> str:
"""
Accepts an fixed-point integer, and returns it as its value divided by 10, as a string.
"""
if type(data) != int:
raise ValueError("divide_by_10 - Invalid input type")
_val = data/10.0
return (_val, f"{_val:.1f}")
def decode_divide_by_100(data: int) -> str:
"""
Accepts an fixed-point integer, and returns it as its value divided by 100, as a string.
"""
if type(data) != int:
raise ValueError("divide_by_100 - Invalid input type")
_val = data/100.0
return (_val, f"{_val:.2f}")
delegate_list = {
'payload_id': decode_payload_id,
'time_hms': decode_time_hms,
'time_biseconds': decode_time_biseconds,
'degree_float': decode_degree_float,
'degree_fixed3': decode_degree_fixed3,
'battery_5v_byte': decode_battery_5v_byte
'battery_5v_byte': decode_battery_5v_byte,
'divide_by_10': decode_divide_by_10,
'divide_by_100': decode_divide_by_100,
}
def decode_field(field_type:str, data):
@ -158,7 +184,9 @@ def decode_field(field_type:str, data):
else:
if (field_type == 'none') or (field_type == 'None') or (field_type == None):
# Basic datatype, just convert to a string using Pythons internal conversions.
if (type(data) == float) or (type(data) == int) or (type(data) == str):
if (type(data) == float):
return (data, f"{data:.6f}")
elif (type(data) == int) or (type(data) == str):
return (data, f"{data}")
else:
raise ValueError(f"Data has unknown type ({str(type(data))}) and could not be decoded.")
@ -227,7 +255,12 @@ if __name__ == "__main__":
['battery_5v_byte', 0, "0.00"],
['battery_5v_byte', 128, "2.51"],
['battery_5v_byte', 255, "5.00"],
['payload_id', 0, '4FSKTEST']
['payload_id', 0, '4FSKTEST'],
['divide_by_10', 123, "12.3"],
['divide_by_10', -456, "-45.6"],
['divide_by_100', 123, "1.23"],
['divide_by_100', -456, "-4.56"],
]
for _test in tests:

Wyświetl plik

@ -4,6 +4,7 @@
import json
import logging
import requests
import struct
# Global payload list - Basic version
HORUS_PAYLOAD_LIST = {0:'4FSKTEST', 1:'HORUSBINARY', 257:'4FSKTEST32', 65535:'HORUSTEST'}
@ -12,6 +13,7 @@ HORUS_PAYLOAD_LIST = {0:'4FSKTEST', 1:'HORUSBINARY', 257:'4FSKTEST32', 65535:'HO
PAYLOAD_ID_LIST_URL = "https://raw.githubusercontent.com/projecthorus/horusdemodlib/master/payload_id_list.txt"
# Custom field data.
HORUS_CUSTOM_FIELD_LENGTH = 9
HORUS_CUSTOM_FIELDS = {
"HORUSTEST": {
"struct": "<BbBfH",
@ -191,11 +193,21 @@ def read_custom_field_list(filename="custom_field_list.json"):
_data = _field_data[_payload]
if ("struct" in _data) and ("fields" in _data):
_custom_field_list[_payload] = {
"struct": _data["struct"],
"fields": _data["fields"]
}
logging.debug(f"Loaded custom field data for {_payload}.")
# Check the struct value has the right length
try:
_structsize = struct.calcsize(_data["struct"])
if _structsize == HORUS_CUSTOM_FIELD_LENGTH:
_custom_field_list[_payload] = {
"struct": _data["struct"],
"fields": _data["fields"]
}
logging.debug(f"Loaded custom field data for {_payload}.")
else:
logging.error(f"Struct field for {_payload} has incorrect length ({_structsize}).")
except Exception as e:
logging.error(f"Could not parse custom field data for {_payload}: {str(e)}")
return _custom_field_list
@ -264,11 +276,23 @@ def download_latest_custom_field_list(url=HORUS_CUSTOM_FIELD_URL, filename=None,
_data = _field_data[_payload]
if ("struct" in _data) and ("fields" in _data):
_custom_field_list[_payload] = {
"struct": _data["struct"],
"fields": _data["fields"]
}
logging.debug(f"Loaded custom field data for {_payload}.")
# Check the struct value has the right length
try:
_structsize = struct.calcsize(_data["struct"])
if _structsize == HORUS_CUSTOM_FIELD_LENGTH:
_custom_field_list[_payload] = {
"struct": _data["struct"],
"fields": _data["fields"]
}
logging.debug(f"Loaded custom field data for {_payload}.")
else:
logging.error(f"Struct field for {_payload} has incorrect length ({_structsize}).")
except Exception as e:
logging.error(f"Could not parse custom field data for {_payload}: {str(e)}")
except Exception as e:
logging.error(f"Could not parse downloaded custom field list - {str(e)}")

Wyświetl plik

@ -58,14 +58,10 @@ struct TBinaryPacket1
int8_t Temp; // Twos Complement Temp value.
uint8_t BattVoltage; // 0 = 0.5v, 255 = 2.0V, linear steps in-between.
uint8_t dummy1; // Dummy values for user-configurable section.
uint8_t dummy2;
uint8_t dummy3;
uint8_t dummy4;
uint8_t dummy5;
uint8_t dummy6;
uint8_t dummy7;
uint8_t dummy8;
uint8_t dummy9;
float dummy2; // Float
uint8_t dummy3; // battery voltage test
uint8_t dummy4; // divide by 10
uint16_t dummy5; // divide by 100
uint16_t Checksum; // CRC16-CCITT Checksum.
} __attribute__ ((packed));
@ -150,14 +146,10 @@ int main(int argc,char *argv[]) {
input_payload.Minutes = 34;
input_payload.Seconds = 56;
input_payload.dummy1 = 1;
input_payload.dummy2 = 2;
input_payload.dummy3 = 3;
input_payload.dummy4 = 4;
input_payload.dummy5 = 5;
input_payload.dummy6 = 6;
input_payload.dummy7 = 7;
input_payload.dummy8 = 8;
input_payload.dummy9 = 9;
input_payload.dummy2 = 1.23456789;
input_payload.dummy3 = 200;
input_payload.dummy4 = 123;
input_payload.dummy5 = 1234;
input_payload.Counter = counter;
input_payload.Checksum = horus_l2_gen_crc16((unsigned char*)&input_payload, nbytes-2);