From 12d35e9c231e61be4b21bd9b00bee6b8e9aa246c Mon Sep 17 00:00:00 2001 From: Gerrit Beine Date: Mon, 9 Sep 2024 14:39:40 +0200 Subject: [PATCH] Updated readme, minor fixes --- README.md | 47 ++++++++++++++-------- fronius2mqtt | 82 +++++++++++++++++++++++---------------- fronius2mqtt.conf.example | 13 ++++++- 3 files changed, 91 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 3a26ea7..c85438d 100644 --- a/README.md +++ b/README.md @@ -59,22 +59,25 @@ Each configuration option is also available as command line argument. - copy ```fronius2mqtt.conf.example``` - configure as you like -| option | default | arguments | comment | -|--------------------|--------------------------|-------------------------|----------------------------------------------------------------------------------------| -| `mqtt_host` | 'localhost' | `-m`, `--mqtt_host` | The hostname of the MQTT server. | -| `mqtt_port` | 1883 | `--mqtt_port` | The port of the MQTT server. | -| `mqtt_keepalive` | 30 | `--mqtt_keepalive` | The keep alive interval for the MQTT server connection in seconds. | -| `mqtt_clientid` | 'fronius2mqtt' | `--mqtt_clientid` | The clientid to send to the MQTT server. | -| `mqtt_user` | - | `-u`, `--mqtt_user` | The username for the MQTT server connection. | -| `mqtt_password` | - | `-p`, `--mqtt_password` | The password for the MQTT server connection. | -| `mqtt_topic` | 'fronius' | `-t`, `--mqtt_topic` | The topic to publish MQTT message. | -| `mqtt_tls_version` | 'TLSv1.2' | `--mqtt_tls_version` | The TLS version to use for MQTT. One of TLSv1, TLSv1.1, TLSv1.2. | -| `mqtt_verify_mode` | 'CERT_REQUIRED' | `--mqtt_verify_mode` | The SSL certificate verification mode. One of CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED. | -| `http_host` | 'localhost' | `--http_host` | The address of the HTTP server. | -| `http_port` | 8080 | ``--http_port`` | The port of the HTTP server. | -| `timestamp` | - | `-z`, `--timestamp` | Publish timestamps for all topics, e.g. for monitoring purposes. | -| `verbose` | - | `-v`, `--verbose` | Be verbose while running. | -| - | '/etc/fronius2mqtt.conf' | `-c`, `--config` | The path to the config file. | +| option | default | arguments | comment | +|----------------------|--------------------------|-------------------------|----------------------------------------------------------------------------------------| +| `mqtt_host` | 'localhost' | `-m`, `--mqtt_host` | The hostname of the MQTT server. | +| `mqtt_port` | 1883 | `--mqtt_port` | The port of the MQTT server. | +| `mqtt_keepalive` | 30 | `--mqtt_keepalive` | The keep alive interval for the MQTT server connection in seconds. | +| `mqtt_clientid` | 'fronius2mqtt' | `--mqtt_clientid` | The clientid to send to the MQTT server. | +| `mqtt_user` | - | `-u`, `--mqtt_user` | The username for the MQTT server connection. | +| `mqtt_password` | - | `-p`, `--mqtt_password` | The password for the MQTT server connection. | +| `mqtt_topic` | 'fronius' | `-t`, `--mqtt_topic` | The topic to publish MQTT message. | +| `mqtt_tls` | - | `--mqtt_tls` | Use SSL/TLS encryption for MQTT connection. | +| `mqtt_tls_version` | 'TLSv1.2' | `--mqtt_tls_version` | The TLS version to use for MQTT. One of TLSv1, TLSv1.1, TLSv1.2. | +| `mqtt_verify_mode` | 'CERT_REQUIRED' | `--mqtt_verify_mode` | The SSL certificate verification mode. One of CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED. | +| `mqtt_ssl_ca_path` | - | `--mqtt_ssl_ca_path` | The SSL certificate authority file to verify the MQTT server. | +| `mqtt_tls_no_verify` | - | `--mqtt_tls_no_verify` | Do not verify SSL/TLS constraints like hostname. | +| `http_host` | 'localhost' | `--http_host` | The address of the HTTP server. | +| `http_port` | 8080 | ``--http_port`` | The port of the HTTP server. | +| `timestamp` | - | `-z`, `--timestamp` | Publish timestamps for all topics, e.g. for monitoring purposes. | +| `verbose` | - | `-v`, `--verbose` | Be verbose while running. | +| - | '/etc/fronius2mqtt.conf' | `-c`, `--config` | The path to the config file. | ## Disclaimer @@ -88,3 +91,15 @@ Use with care ond only if you know what you're doing. - Authentication support - Support for new Fronius API +## Running fronius2mqtt + +I use [systemd](https://systemd.io/) to manage my local services. + +## Support + +I have not the time (yet) to provide professional support for this project. +But feel free to submit issues and PRs, I'll check for it and honor your contributions. + +## License + +The whole project is licensed under BSD-3-Clause license. Stay fair. diff --git a/fronius2mqtt b/fronius2mqtt index 9679581..7603e8a 100755 --- a/fronius2mqtt +++ b/fronius2mqtt @@ -11,9 +11,6 @@ import paho.mqtt.client as mqtt from bottle import request, route, post, run -mqtt_client = None -daemon_args = None - verify_mode = { 'CERT_NONE': ssl.CERT_NONE, 'CERT_OPTIONAL': ssl.CERT_OPTIONAL, @@ -27,6 +24,10 @@ tls_versions = { } +mqtt_client = None +daemon_args = None + + def extract_request_body(): body = request.body string = body.getvalue().decode('utf-8') @@ -181,19 +182,27 @@ def logdata_data(device): return "OK" -def start_mqtt(): +def init_mqtt(): + logging.debug('Starting MQTT') global daemon_args - mqtt_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) - cert_reqs = verify_mode[daemon_args.mqtt_verify_mode] if daemon_args.mqtt_verify_mode in verify_mode else None - tls_version = tls_versions[daemon_args.mqtt_tls_version] if daemon_args.mqtt_tls_version in tls_versions else None - mqtt_client.tls_set(cert_reqs=cert_reqs, tls_version=tls_version) + mqtt_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, daemon_args.mqtt_clientid) + if daemon_args.mqtt_tls: + cert_reqs = verify_mode[daemon_args.mqtt_verify_mode] if daemon_args.mqtt_verify_mode in verify_mode else None + tls_version = tls_versions[daemon_args.mqtt_tls_version] if daemon_args.mqtt_tls_version in tls_versions else None + if 'mqtt_ssl_ca_path' in daemon_args: + mqtt_client.tls_set(daemon_args.mqtt_ssl_ca_path)#, cert_reqs=cert_reqs, tls_version=tls_version) + elif cert_reqs is not None and tls_version is not None: + print(cert_reqs) + mqtt_client.tls_set(cert_reqs=cert_reqs, tls_version=tls_version) + else: + logging.error("Invalid TLS configuration.") + exit(255) + mqtt_client.tls_insecure_set(daemon_args.mqtt_tls_no_verify) if daemon_args.verbose: - logging.basicConfig(level=logging.DEBUG) mqtt_client.enable_logger() if daemon_args.mqtt_user is not None and daemon_args.mqtt_password is not None: mqtt_client.username_pw_set(daemon_args.mqtt_user, daemon_args.mqtt_password) mqtt_client.connect(daemon_args.mqtt_host, daemon_args.mqtt_port, daemon_args.mqtt_keepalive) - mqtt_client.loop_start() return mqtt_client @@ -226,34 +235,35 @@ def parse_args(): parser.add_argument('-t', '--mqtt_topic', type=str, default='fronius', help='The topic to publish MQTT message. Default is fronius') + parser.add_argument('--mqtt_tls', + default=False, + action='store_true', + help='Use SSL/TLS encryption for MQTT connection.') parser.add_argument('--mqtt_tls_version', type=str, default='TLSv1.2', help='The TLS version to use for MQTT. One of TLSv1, TLSv1.1, TLSv1.2. Default is TLSv1.2') parser.add_argument('--mqtt_verify_mode', type=str, default='CERT_REQUIRED', help='The SSL certificate verification mode. One of CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED. Default is CERT_REQUIRED') - # TODO - # parser.add_argument('--mqtt_ca_cert', type=str, - # help='The path to the SSL CA certificate. Optional, no default') - # parser.add_argument('--mqtt_certfile', type=str, - # help='The path to the SSL certificate file. Optional, no default') - # parser.add_argument('--mqtt_keyfile', type=str, - # help='The path to the SSL key file. Optional, no default') - # parser.add_argument('--mqtt_keyfile_password', type=str, - # help='The path to the SSL key password. Optional, no default') + parser.add_argument('--mqtt_ssl_ca_path', type=str, + help='The SSL certificate authority file to verify the MQTT server.') + parser.add_argument('--mqtt_tls_no_verify', + default=False, + action='store_true', + help='Do not verify SSL/TLS constraints like hostname.') parser.add_argument('--http_host', type=str, default='localhost', help='The address of the HTTP server. Default is localhost') parser.add_argument('--http_port', type=int, default=8080, help='The port of the HTTP server. Default is 8080') - parser.add_argument('-c', '--config', type=str, - default='/etc/fronius2mqtt.conf', - help='The path to the config file. Default is /etc/fronius2mqtt.conf') parser.add_argument('-z', '--timestamp', default=False, action='store_true', help='Publish timestamps for all topics, e.g. for monitoring purposes.') + parser.add_argument('-c', '--config', type=str, + default='/etc/fronius2mqtt.conf', + help='The path to the config file. Default is /etc/fronius2mqtt.conf') parser.add_argument('-v', '--verbose', default=False, action='store_true', @@ -284,19 +294,16 @@ def parse_config(): daemon_args.mqtt_password = data['mqtt_password'] if 'mqtt_topic' in data: daemon_args.mqtt_topic = data['mqtt_topic'] + if 'mqtt_tls' in data: + daemon_args.mqtt_tls = bool(data['mqtt_tls']) if 'mqtt_tls_version' in data: - daemon_args.mqtt_tls_version = data['mqtt_tls_version'] + daemon_args.mqtt_tls = data['mqtt_tls_version'] if 'mqtt_verify_mode' in data: - daemon_args.mqtt_verify_mode = data['mqtt_verify_mode'] - # TODO - # if 'mqtt_ca_cert' in data: - # daemon_args.mqtt_ca_cert = data['mqtt_ca_cert'] - # if 'mqtt_certfile' in data: - # daemon_args.mqtt_certfile = data['mqtt_certfile'] - # if 'mqtt_keyfile' in data: - # daemon_args.mqtt_keyfile = data['mqtt_keyfile'] - # if 'mqtt_keyfile_password' in data: - # daemon_args.mqtt_keyfile_password = data['mqtt_keyfile_password'] + daemon_args.mqtt_tls = data['mqtt_verify_mode'] + if 'mqtt_ssl_ca_path' in data: + daemon_args.mqtt_ssl_ca_path = data['mqtt_ssl_ca_path'] + if 'mqtt_tls_no_verify' in data: + daemon_args.mqtt_tls_no_verify = bool(data['mqtt_tls_no_verify']) if 'http_host' in data: daemon_args.http_host = data['http_host'] if 'http_port' in data: @@ -309,9 +316,16 @@ def parse_config(): def main(): global daemon_args, mqtt_client + # Configuration daemon_args = parse_args() parse_config() - mqtt_client = start_mqtt() + # Verbosity + if daemon_args.verbose: + logging.basicConfig(level=logging.DEBUG) + # MQTT connection + mqtt_client = init_mqtt() + mqtt_client.loop_start() + # HTTP server start_http() diff --git a/fronius2mqtt.conf.example b/fronius2mqtt.conf.example index 837b0f9..2f39a1e 100644 --- a/fronius2mqtt.conf.example +++ b/fronius2mqtt.conf.example @@ -1,6 +1,17 @@ { + "mqtt_host": "localhost", + "mqtt_port": "1883" + "mqtt_port": "keepalive" + "mqtt_clientid": "fronius2mqtt" "mqtt_user": "fronius2mqtt", "mqtt_password": "t0p_s3cr3t", + "mqtt_topic": "fronius", + "mqtt_tls": "false", + "mqtt_tls_version": "TLSv1.2", + "mqtt_verify_mode": "CERT_NONE", + "mqtt_ssl_ca_path": "/etc/ssl/myca.pem", + "mqtt_tls_no_verify": "false", "http_host": "0.0.0.0", - "http_port": 80 + "http_port": 80, + "verbose": "false" }