Added support for Docker build

This commit is contained in:
Gerrit Beine 2024-06-23 19:58:13 +02:00
parent 8470e830a7
commit b3dea6acfd
4 changed files with 106 additions and 15 deletions

27
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,27 @@
name: ci
on:
push:
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64,linux/arm/v6
push: true
tags: gbeine/fronius2mqtt:latest

10
Dockerfile Normal file
View file

@ -0,0 +1,10 @@
FROM python:3-alpine
WORKDIR /fronius2mqtt
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY fronius2mqtt .
CMD [ "python", "./fronius2mqtt" ]

View file

@ -10,6 +10,12 @@ It forwards the data directly to MQTT.
## Install ## Install
### Installation using Docker
docker run -it --rm --name fronius2mqtt -v fronius2mqtt.conf:/etc/fronius2mqtt.conf docker.io/gbeine/fronius2mqtt
### Native installation with Python venv
- clone the git repository - clone the git repository
- ensure to have Python 3 with venv installed - ensure to have Python 3 with venv installed
- run the ```install``` script in the local directory - run the ```install``` script in the local directory
@ -21,16 +27,18 @@ Each configuration option is also available as command line argument.
- copy ```fronius2mqtt.conf.example``` - copy ```fronius2mqtt.conf.example```
- configure as you like - configure as you like
| option | default | arguments | comment | | option | default | arguments | comment |
|----------------|--------------------------|---------------------|--------------------------------------------------------------------| |------------------|--------------------------|---------------------|----------------------------------------------------------------------------------------|
| mqtt_host | 'localhost' | -m, --mqtt_host | The hostname of the MQTT server. | | mqtt_host | 'localhost' | -m, --mqtt_host | The hostname of the MQTT server. |
| mqtt_port | 1883 | --mqtt_port | The port 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_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_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_user | - | -u, --mqtt_user | The username for the MQTT server connection. |
| mqtt_password | - | -p, --mqtt_password | The password 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_topic | 'fronius' | -t, --mqtt_topic | The topic to publish MQTT message. |
| http_host | 'localhost' | --http_host | The address of the HTTP server. | | mqtt_tls_version | 'TLSv1.2' | --mqtt_tls_version | The TLS version to use for MQTT. One of TLSv1, TLSv1.1, TLSv1.2. |
| http_port | 8080 | --http_port | The port of the HTTP server. | | mqtt_verify_mode | 'CERT_REQUIRED' | --mqtt_verify_mode | The SSL certificate verification mode. One of CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED. |
| verbose | - | -v, --verbose | Be verbose while running. | | http_host | 'localhost' | --http_host | The address of the HTTP server. |
| - | '/etc/fronius2mqtt.conf' | -c, --config | The path to the config file. | | http_port | 8080 | --http_port | The port of the HTTP server. |
| verbose | - | -v, --verbose | Be verbose while running. |
| - | '/etc/fronius2mqtt.conf' | -c, --config | The path to the config file. |

View file

@ -2,7 +2,9 @@
import argparse import argparse
import json import json
import logging
import os import os
import ssl
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
from bottle import request, route, post, run from bottle import request, route, post, run
@ -11,6 +13,18 @@ from bottle import request, route, post, run
mqtt_client = None mqtt_client = None
daemon_args = None daemon_args = None
verify_mode = {
'CERT_NONE': ssl.CERT_NONE,
'CERT_OPTIONAL': ssl.CERT_OPTIONAL,
'CERT_REQUIRED': ssl.CERT_REQUIRED
}
tls_versions = {
'TLSv1': ssl.PROTOCOL_TLSv1,
'TLSv1.1': ssl.PROTOCOL_TLSv1_1,
'TLSv1.2': ssl.PROTOCOL_TLSv1_2
}
def extract_request_body(): def extract_request_body():
body = request.body body = request.body
@ -26,7 +40,7 @@ def extract_request_data():
@route('/') @route('/')
def index(): def index():
return "Hello World!" return "Hello World!<br/>This is the fronius2mqtt daemon by Gerrit Beine"
@post('/current_data_inverter/<device>') @post('/current_data_inverter/<device>')
@ -162,8 +176,12 @@ def logdata_data(device):
def start_mqtt(): def start_mqtt():
global daemon_args global daemon_args
mqtt_client = mqtt.Client(daemon_args.mqtt_clientid) 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)
if daemon_args.verbose: if daemon_args.verbose:
logging.basicConfig(level=logging.DEBUG)
mqtt_client.enable_logger() mqtt_client.enable_logger()
if daemon_args.mqtt_user is not None and daemon_args.mqtt_password is not None: 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.username_pw_set(daemon_args.mqtt_user, daemon_args.mqtt_password)
@ -201,6 +219,21 @@ def parse_args():
parser.add_argument('-t', '--mqtt_topic', type=str, parser.add_argument('-t', '--mqtt_topic', type=str,
default='fronius', default='fronius',
help='The topic to publish MQTT message. Default is fronius') help='The topic to publish MQTT message. Default is fronius')
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('--http_host', type=str, parser.add_argument('--http_host', type=str,
default='localhost', default='localhost',
help='The address of the HTTP server. Default is localhost') help='The address of the HTTP server. Default is localhost')
@ -240,6 +273,19 @@ def parse_config():
daemon_args.mqtt_password = data['mqtt_password'] daemon_args.mqtt_password = data['mqtt_password']
if 'mqtt_topic' in data: if 'mqtt_topic' in data:
daemon_args.mqtt_topic = data['mqtt_topic'] daemon_args.mqtt_topic = data['mqtt_topic']
if 'mqtt_tls_version' in data:
daemon_args.mqtt_tls_version = 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']
if 'http_host' in data: if 'http_host' in data:
daemon_args.http_host = data['http_host'] daemon_args.http_host = data['http_host']
if 'http_port' in data: if 'http_port' in data: