bigclown-gateway: backport pending patch to fix JSON dumps

Pull request:
https://redirect.github.com/hardwario/bch-gateway/pull/20

Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
This commit is contained in:
Josef Schlehofer
2025-10-22 02:49:54 +02:00
parent 15121d222b
commit 5a9763deab

View File

@@ -0,0 +1,65 @@
From df50e792cbc0c6e03fde2397e9802c81bca1c89b Mon Sep 17 00:00:00 2001
From: Martin Pecka <peci1@seznam.cz>
Date: Wed, 22 Oct 2025 02:15:04 +0200
Subject: [PATCH] Fix support for Decimals
---
bcg/gateway.py | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
--- a/bcg/gateway.py
+++ b/bcg/gateway.py
@@ -11,11 +11,26 @@ import yaml
import serial
import paho.mqtt.client
import appdirs
+from collections.abc import Mapping, Iterable
if platform.system() == 'Linux':
import fcntl
+# https://stackoverflow.com/a/60243503/1076564
+class DecimalJSONEncoder(json.JSONEncoder):
+ """Add support for encoding Decimal"""
+ def encode(self, obj):
+ if isinstance(obj, Mapping):
+ return '{' + ', '.join(f'{self.encode(k)}: {self.encode(v)}' for (k, v) in obj.items()) + '}'
+ if isinstance(obj, Iterable) and (not isinstance(obj, str)):
+ return '[' + ', '.join(map(self.encode, obj)) + ']'
+ if isinstance(obj, decimal.Decimal):
+ # using normalize() gets rid of trailing 0s, using ':f' prevents scientific notation
+ return f'{obj.normalize():f}'
+ return super().encode(obj)
+
+
class Gateway:
def __init__(self, config):
@@ -218,7 +233,7 @@ class Gateway:
node_id = self._node_rename_name.get(node_name, None)
if node_id:
topic = node_id + topic[i:]
- line = json.dumps([topic, payload], use_decimal=True) + '\n'
+ line = json.dumps([topic, payload], cls=DecimalJSONEncoder) + '\n'
line = line.encode('utf-8')
logging.debug("write %s", line)
self.ser.write(line)
@@ -226,7 +241,7 @@ class Gateway:
def publish(self, topic, payload):
if isinstance(topic, list):
topic = '/'.join(topic)
- self.mqttc.publish(self._config['base_topic_prefix'] + topic, json.dumps(payload, use_decimal=True), qos=1)
+ self.mqttc.publish(self._config['base_topic_prefix'] + topic, json.dumps(payload, cls=DecimalJSONEncoder), qos=1)
def log_message(self, line):
logging.debug('log_message %s', line)
@@ -324,7 +339,7 @@ class Gateway:
if node_name:
subtopic = node_name + '/' + topic
- self.mqttc.publish(self._config['base_topic_prefix'] + "node/" + subtopic, json.dumps(payload, use_decimal=True), qos=self._msg_qos, retain=self._msg_retain)
+ self.mqttc.publish(self._config['base_topic_prefix'] + "node/" + subtopic, json.dumps(payload, cls=DecimalJSONEncoder), qos=self._msg_qos, retain=self._msg_retain)
except Exception:
raise