changed: data-logging configuration to rotate more frequently

fixed: database connection retry interval and storing in local SQLite when DB is down
This commit is contained in:
2025-12-28 07:35:50 +00:00
parent 09c003964d
commit 5b4340fab2
3 changed files with 540 additions and 212 deletions

154
test_pool_decode.py Normal file
View File

@@ -0,0 +1,154 @@
#!/usr/bin/env python3
"""Test pool payload decoding with the new MQTT message format"""
import json
import struct
from typing import Optional
PAYLOAD_SIZE = 15
MAGIC1 = 0x42
MAGIC2 = 0x99
def crc8_xor(data: bytes) -> int:
"""Simple XOR checksum used by the pool payload."""
c = 0
for b in data:
c ^= b
return c
def decode_pool_payload(candidate_bytes: bytes, expected_seq: Optional[int] = None):
"""Scan a byte stream for a plausible pool payload.
Slides a 15-byte window, validates with CRC, version/nodeId, and range checks,
and scores candidates. Returns the best decoded dict or None.
"""
# Drop leading preamble (0xAA) if present
while candidate_bytes.startswith(b"\xaa"):
candidate_bytes = candidate_bytes[1:]
best = None
best_score = -1
for offset in range(0, len(candidate_bytes) - PAYLOAD_SIZE + 1):
chunk = candidate_bytes[offset:offset + PAYLOAD_SIZE]
try:
magic1, magic2, version, nodeId, seq, t_ds10, t_bme10, hum10, pres1, crc_received = struct.unpack(
'<BBBBHhhHHB', chunk
)
except struct.error:
continue
crc_calculated = crc8_xor(chunk[:-1])
if crc_calculated != crc_received:
continue
if version != 1 or nodeId != 1:
continue
# Plausibility checks (unit scaled)
if not (-300 <= t_ds10 <= 600): # -30.0 to 60.0°C
continue
if not (-300 <= t_bme10 <= 600):
continue
if not (0 <= hum10 <= 1000): # 0.0100.0%
continue
if not (8000 <= pres1 <= 11000): # 800.01100.0 hPa
continue
score = 0
if magic1 == MAGIC1 and magic2 == MAGIC2:
score += 2
if expected_seq is not None and seq == expected_seq:
score += 1
# CRC already validated; reward shorter offset to prefer first valid
score -= offset * 0.001
if score > best_score:
best_score = score
best = {
"offset": offset,
"magic_ok": magic1 == MAGIC1 and magic2 == MAGIC2,
"version": version,
"nodeId": nodeId,
"sequence": seq,
"t_ds_c": t_ds10 / 10.0,
"t_bme_c": t_bme10 / 10.0,
"humidity": hum10 / 10.0,
"pressure_hpa": pres1 / 10.0,
"crc_valid": True,
}
return best
# Test with the actual MQTT message
mqtt_message = {
"time": "2025-12-27T13:26:47",
"model": "pool",
"count": 1,
"num_rows": 1,
"rows": [
{
"len": 143,
"data": "429901013400a801f6002b0294272a000000"
}
],
"codes": ["{143}429901013400a801f6002b0294272a000000"]
}
print("Testing pool payload decode with new MQTT format:")
print(f"MQTT message: {json.dumps(mqtt_message, indent=2)}")
print()
hex_data = mqtt_message['rows'][0]['data']
print(f"Hex data from rows[0]['data']: {hex_data}")
print(f"Hex data length: {len(hex_data)} chars ({len(hex_data)//2} bytes)")
# Strip 'aaaaaa' prefix if present
if hex_data.startswith('aaaaaa'):
hex_data = hex_data[6:]
print(f"Stripped 'aaaaaa' prefix, remaining: {hex_data}")
byte_data = bytes.fromhex(hex_data)
print(f"Byte data: {byte_data.hex()}")
print()
# Decode with sliding window
decoded = decode_pool_payload(byte_data)
if decoded:
print("✓ Payload decoded successfully!")
print(json.dumps(decoded, indent=2))
print()
print("Generated sensor messages:")
bme_msg = {
'time': mqtt_message['time'],
'model': 'pool',
'id': decoded['nodeId'] * 10 + 1,
'battery_ok': 1,
'temperature_C': decoded['t_bme_c'],
'humidity': decoded['humidity'],
'pressure_rel': decoded['pressure_hpa'],
'mic': 'CRC'
}
ds_msg = {
'time': mqtt_message['time'],
'model': 'pool',
'id': decoded['nodeId'] * 10 + 2,
'battery_ok': 1,
'temperature_C': decoded['t_ds_c'],
'mic': 'CRC'
}
print("BME280 message:")
print(json.dumps(bme_msg, indent=2))
print()
print("DS18B20 message:")
print(json.dumps(ds_msg, indent=2))
else:
print("✗ Failed to decode payload!")