Fix formatting

This commit is contained in:
2026-05-02 14:48:58 +02:00
parent ad58fc8bc2
commit 973dc9bc96
3 changed files with 237 additions and 89 deletions
+106 -29
View File
@@ -10,33 +10,107 @@ from bmspy.utilities import debugger
def parse_args(): def parse_args():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='Query JBD BMS and report status', description="Query JBD BMS and report status",
add_help=True, add_help=True,
)
parser.add_argument(
"--socket",
"-s",
dest="socket",
action="store",
default="/run/bmspy/bms",
help="Socket to communicate with daemon",
)
parser.add_argument(
"--ups",
dest="ups",
action="store",
default=None,
help="Only show data for this UPS name (default: all)",
)
parser.add_argument(
"--json",
"-j",
dest="report_json",
action="store_true",
default=False,
help="Report data as JSON",
)
parser.add_argument(
"--prometheus",
"-p",
dest="report_prometheus",
action="store_true",
default=False,
help="Daemonize and report data to Prometheus",
)
parser.add_argument(
"--file",
"-f",
dest="report_textfile",
type=str,
action="store",
default=False,
help="Report data to Prometheus using textfile <file>",
)
parser.add_argument(
"--print",
dest="report_print",
action="store_true",
default=True,
help="Report data as text",
)
parser.add_argument(
"--influxdb",
"-i",
dest="report_influxdb",
action="store_true",
default=False,
help="Daemonize and report data to InfluxDB using INFLUXDB_V2_URL, INFLUXDB_V2_ORG and INFLUXDB_V2_TOKEN environment variables",
)
parser.add_argument(
"--bucket",
"-b",
dest="influx_bucket",
type=str,
action="store",
default="ups",
help='Set the bucket name when sending data to influxdb (defaults to "ups")',
)
parser.add_argument(
"--url",
"-u",
dest="influx_url",
type=str,
action="store",
default=False,
help="Set the URL when sending data to influxdb (overrides INFLUXDB environment variables)",
)
parser.add_argument(
"--org",
"-o",
dest="influx_org",
type=str,
action="store",
default=False,
help="Set the influx organization when sending data to influxdb (overrides INFLUXDB environment variables)",
)
parser.add_argument(
"--token",
"-t",
dest="influx_token",
type=str,
action="store",
default=False,
help="Set the influx token when sending data to influxdb (overrides INFLUXDB environment variables)",
)
parser.add_argument(
"--verbose",
"-v",
action="count",
default=0,
help="Print more verbose information (can be specified multiple times)",
) )
parser.add_argument('--socket', '-s', dest='socket', action='store',
default='/run/bmspy/bms', help='Socket to communicate with daemon')
parser.add_argument('--ups', dest='ups', action='store', default=None,
help='Only show data for this UPS name (default: all)')
parser.add_argument('--json', '-j', dest='report_json', action='store_true',
default=False, help='Report data as JSON')
parser.add_argument('--prometheus', '-p', dest='report_prometheus', action='store_true',
default=False, help='Daemonize and report data to Prometheus')
parser.add_argument('--file', '-f', dest='report_textfile', type=str, action='store',
default=False, help='Report data to Prometheus using textfile <file>')
parser.add_argument('--influxdb', '-i', dest='report_influxdb', action='store_true',
default=False, help='Daemonize and report data to InfluxDB using INFLUXDB_V2_URL, INFLUXDB_V2_ORG and INFLUXDB_V2_TOKEN environment variables')
parser.add_argument('--bucket', '-b', dest='influx_bucket', type=str, action='store',
default="ups", help='Set the bucket name when sending data to influxdb (defaults to "ups")')
parser.add_argument('--url', '-u', dest='influx_url', type=str, action='store',
default=False, help='Set the URL when sending data to influxdb (overrides INFLUXDB environment variables)')
parser.add_argument('--org', '-o', dest='influx_org', type=str, action='store',
default=False, help='Set the influx organization when sending data to influxdb (overrides INFLUXDB environment variables)')
parser.add_argument('--token', '-t', dest='influx_token', type=str, action='store',
default=False, help='Set the influx token when sending data to influxdb (overrides INFLUXDB environment variables)')
parser.add_argument('--print', dest='report_print', action='store_true',
default=True, help='Report data as text')
parser.add_argument('--verbose', '-v', action='count',
default=0, help='Print more verbose information (can be specified multiple times)')
args = parser.parse_args() args = parser.parse_args()
return args return args
@@ -53,10 +127,13 @@ def main():
if arg is not False: if arg is not False:
num_args += 1 num_args += 1
if num_args != 0 and num_args != 3: if num_args != 0 and num_args != 3:
raise argparse.ArgumentTypeError('Missing value for --url, --org or --token') raise argparse.ArgumentTypeError(
"Missing value for --url, --org or --token"
)
if args.report_prometheus: if args.report_prometheus:
from bmspy import prometheus from bmspy import prometheus
prometheus.prometheus_export(daemonize=True, debug=debug) prometheus.prometheus_export(daemonize=True, debug=debug)
if args.report_influxdb: if args.report_influxdb:
@@ -87,7 +164,7 @@ def main():
atexit.register(client.handle_registration, args.socket, "bmspy", debug) atexit.register(client.handle_registration, args.socket, "bmspy", debug)
# {ups_name: JBDUPS} # {ups_name: JBDUPS}
data = client.read_data(args.socket, 'bmspy', ups=args.ups, debug=debug) data = client.read_data(args.socket, "bmspy", ups=args.ups, debug=debug)
if args.report_json: if args.report_json:
import json import json
@@ -107,5 +184,5 @@ def main():
debugger(e) debugger(e)
if __name__ == '__main__': if __name__ == "__main__":
main() main()
+119 -56
View File
@@ -1,4 +1,8 @@
import atexit, datetime, os, sys, time import atexit
import datetime
import os
import sys
import time
from influxdb_client_3 import InfluxDBClient3, Point from influxdb_client_3 import InfluxDBClient3, Point
from bmspy import client from bmspy import client
from bmspy.utilities import debugger from bmspy.utilities import debugger
@@ -11,10 +15,19 @@ def influx_shutdown(influxclient):
influxclient.close() influxclient.close()
def influxdb_export(bucket, url=None, org=None, token=None, socket_path=None, ups=None, daemonize=True, debug=0): def influxdb_export(
bucket,
url=None,
org=None,
token=None,
socket_path=None,
ups=None,
daemonize=True,
debug=0,
):
if not url: if not url:
url = os.environ["INFLUXDB_V2_URL"] url = os.environ["INFLUXDB_V2_URL"]
org = os.environ.get("INFLUXDB_V2_ORG") org = os.environ.get("INFLUXDB_V2_ORG")
token = os.environ["INFLUXDB_V2_TOKEN"] token = os.environ["INFLUXDB_V2_TOKEN"]
influxclient = InfluxDBClient3(host=url, org=org, database=bucket, token=token) influxclient = InfluxDBClient3(host=url, org=org, database=bucket, token=token)
@@ -22,11 +35,11 @@ def influxdb_export(bucket, url=None, org=None, token=None, socket_path=None, up
if daemonize: if daemonize:
while True: while True:
data = client.read_data(socket_path, 'influxdb', ups=ups) data = client.read_data(socket_path, "influxdb", ups=ups)
influxdb_write_snapshot(influxclient, bucket, data, debug) influxdb_write_snapshot(influxclient, bucket, data, debug)
time.sleep(DAEMON_UPDATE_PERIOD) time.sleep(DAEMON_UPDATE_PERIOD)
else: else:
data = client.read_data(socket_path, 'influxdb', ups=ups) data = client.read_data(socket_path, "influxdb", ups=ups)
influxdb_write_snapshot(influxclient, bucket, data, debug) influxdb_write_snapshot(influxclient, bucket, data, debug)
influxclient.close() influxclient.close()
@@ -52,48 +65,54 @@ def influxdb_create_snapshot(ups_data, debug=0):
for ups_name, data in ups_data.items(): for ups_name, data in ups_data.items():
for kind, contains in data.items(): for kind, contains in data.items():
helpmsg = contains.get('help') or '' helpmsg = contains.get("help") or ""
units = contains.get('units') units = contains.get("units")
if contains.get('raw_value') is not None: if contains.get("raw_value") is not None:
value = contains.get('raw_value') value = contains.get("raw_value")
if debug > 2: if debug > 2:
debugger("value: {} [{}] : {}".format(kind, ups_name, value)) debugger("value: {} [{}] : {}".format(kind, ups_name, value))
points.append( points.append(
Point(kind) Point(kind)
.tag("ups", ups_name) .tag("ups", ups_name)
.tag("units", units) .tag("units", units)
.tag("help", helpmsg) .tag("help", helpmsg)
.field("value", value) .field("value", value)
.time(now) .time(now)
) )
if contains.get('raw_values') is not None and isinstance(contains.get('raw_values'), dict): if contains.get("raw_values") is not None and isinstance(
label = contains.get('label') contains.get("raw_values"), dict
for idx, label_value in contains.get('raw_values').items(): ):
label = contains.get("label")
for idx, label_value in contains.get("raw_values").items():
if debug > 2: if debug > 2:
debugger("labels: {} [{}][{}] : {}".format(kind, ups_name, idx, label_value)) debugger(
"labels: {} [{}][{}] : {}".format(
kind, ups_name, idx, label_value
)
)
points.append( points.append(
Point(kind) Point(kind)
.tag("ups", ups_name) .tag("ups", ups_name)
.tag(label, idx) .tag(label, idx)
.tag("units", units) .tag("units", units)
.tag("help", helpmsg) .tag("help", helpmsg)
.field("value", label_value) .field("value", label_value)
.time(now) .time(now)
) )
if contains.get('info') is not None: if contains.get("info") is not None:
value = contains.get('info') value = contains.get("info")
if debug > 2: if debug > 2:
debugger("info: {} [{}] : {}".format(kind, ups_name, value)) debugger("info: {} [{}] : {}".format(kind, ups_name, value))
points.append( points.append(
Point(kind) Point(kind)
.tag("ups", ups_name) .tag("ups", ups_name)
.tag("units", units) .tag("units", units)
.tag("help", helpmsg) .tag("help", helpmsg)
.field("value", value) .field("value", value)
.time(now) .time(now)
) )
return points return points
@@ -103,42 +122,86 @@ def main():
import argparse import argparse
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='Query JBD BMS and report status', description="Query JBD BMS and report status",
add_help=True, add_help=True,
)
parser.add_argument(
"--bucket",
"-b",
dest="influx_bucket",
type=str,
action="store",
default="ups",
help='Set the bucket name when sending data to influxdb (defaults to "ups")',
)
parser.add_argument(
"--url",
"-u",
dest="influx_url",
type=str,
action="store",
default=False,
help="Set the URL when sending data to influxdb (overrides INFLUXDB environment variables)",
)
parser.add_argument(
"--org",
"-o",
dest="influx_org",
type=str,
action="store",
default=False,
help="Set the influx organization when sending data to influxdb (overrides INFLUXDB environment variables)",
)
parser.add_argument(
"--token",
"-t",
dest="influx_token",
type=str,
action="store",
default=False,
help="Set the influx token when sending data to influxdb (overrides INFLUXDB environment variables)",
)
parser.add_argument(
"--socket",
"-s",
dest="socket",
action="store",
default="/run/bmspy/bms",
help="Socket to communicate with daemon",
)
parser.add_argument(
"--ups",
dest="ups",
action="store",
default=None,
help="Only export data for this UPS name (default: all)",
)
parser.add_argument(
"--verbose",
"-v",
action="count",
default=0,
help="Print more verbose information (can be specified multiple times)",
) )
parser.add_argument('--bucket', '-b', dest='influx_bucket', type=str, action='store',
default="ups", help='Set the bucket name when sending data to influxdb (defaults to "ups")')
parser.add_argument('--url', '-u', dest='influx_url', type=str, action='store',
default=False, help='Set the URL when sending data to influxdb (overrides INFLUXDB environment variables)')
parser.add_argument('--org', '-o', dest='influx_org', type=str, action='store',
default=False, help='Set the influx organization when sending data to influxdb (overrides INFLUXDB environment variables)')
parser.add_argument('--token', '-t', dest='influx_token', type=str, action='store',
default=False, help='Set the influx token when sending data to influxdb (overrides INFLUXDB environment variables)')
parser.add_argument('--socket', '-s', dest='socket', action='store',
default='/run/bmspy/bms', help='Socket to communicate with daemon')
parser.add_argument('--ups', dest='ups', action='store', default=None,
help='Only export data for this UPS name (default: all)')
parser.add_argument('--verbose', '-v', action='count',
default=0, help='Print more verbose information (can be specified multiple times)')
args = parser.parse_args() args = parser.parse_args()
debug = args.verbose debug = args.verbose
try: try:
if not os.getenv('INFLUXDB_V2_URL') and not args.influx_url: if not os.getenv("INFLUXDB_V2_URL") and not args.influx_url:
raise argparse.ArgumentTypeError('Missing value for --url') raise argparse.ArgumentTypeError("Missing value for --url")
if not os.getenv('INFLUXDB_V2_ORG') and not args.influx_org: if not os.getenv("INFLUXDB_V2_ORG") and not args.influx_org:
raise argparse.ArgumentTypeError('Missing value for --org') raise argparse.ArgumentTypeError("Missing value for --org")
if not os.getenv('INFLUXDB_V2_TOKEN') and not args.influx_token: if not os.getenv("INFLUXDB_V2_TOKEN") and not args.influx_token:
raise argparse.ArgumentTypeError('Missing value for --token') raise argparse.ArgumentTypeError("Missing value for --token")
except Exception as e: except Exception as e:
debugger("bmspy-influxdb: {}".format(e)) debugger("bmspy-influxdb: {}".format(e))
sys.exit(1) sys.exit(1)
debugger("Running BMS influxdb daemon on socket {}".format(args.socket)) debugger("Running BMS influxdb daemon on socket {}".format(args.socket))
client.handle_registration(args.socket, 'influxdb', debug) client.handle_registration(args.socket, "influxdb", debug)
atexit.register(client.handle_registration, args.socket, 'influxdb', debug) atexit.register(client.handle_registration, args.socket, "influxdb", debug)
influxdb_export( influxdb_export(
bucket=args.influx_bucket, bucket=args.influx_bucket,
+12 -4
View File
@@ -184,7 +184,9 @@ def parse_03_response(response, debug=0):
# length+5 checksum # length+5 checksum
# length+6 end \x77 # length+6 end \x77
if bytes([response[0]]) != b"\xdd": if bytes([response[0]]) != b"\xdd":
debugger("parse_03_response ERROR: first byte not found: {0}".format(response[0])) debugger(
"parse_03_response ERROR: first byte not found: {0}".format(response[0])
)
return False return False
if bytes([response[2]]) == b"\x80": if bytes([response[2]]) == b"\x80":
@@ -197,7 +199,9 @@ def parse_03_response(response, debug=0):
data_len = response[3] data_len = response[3]
if debug > 2: if debug > 2:
debugger("parse_03_response: data length (trimming 4 bytes): {0}".format(data_len)) debugger(
"parse_03_response: data length (trimming 4 bytes): {0}".format(data_len)
)
# The checksum is two bytes, offset by data_len + 4 # The checksum is two bytes, offset by data_len + 4
# Five bytes at the front of data: begin; rw; status, command; length # Five bytes at the front of data: begin; rw; status, command; length
@@ -395,7 +399,9 @@ def parse_03_response(response, debug=0):
value="{0}".format(int(bool((control_status >> 1) & 1))), value="{0}".format(int(bool((control_status >> 1) & 1))),
) )
if debug > 1: if debug > 1:
debugger(" MOSFET charging: {0}".format("yes" if (control_status & 1) else "no")) debugger(
" MOSFET charging: {0}".format("yes" if (control_status & 1) else "no")
)
debugger( debugger(
" MOSFET discharging: {0}".format( " MOSFET discharging: {0}".format(
"yes" if ((control_status >> 1) & 1) else "no" "yes" if ((control_status >> 1) & 1) else "no"
@@ -437,7 +443,9 @@ def parse_04_response(response, debug=0):
# length+5 checksum # length+5 checksum
# length+6 end \x77 # length+6 end \x77
if bytes([response[0]]) != b"\xdd": if bytes([response[0]]) != b"\xdd":
debugger("parse_04_response ERROR: first byte not found: {0}".format(response[0])) debugger(
"parse_04_response ERROR: first byte not found: {0}".format(response[0])
)
return False return False
if bytes([response[2]]) == b"\x80": if bytes([response[2]]) == b"\x80":