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
### 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
- ensure to have Python 3 with venv installed
- 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```
- 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. |
| http_host | 'localhost' | --http_host | The address of the HTTP server. |
| 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. |
| 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. |
| 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 json
import logging
import os
import ssl
import paho.mqtt.client as mqtt
from bottle import request, route, post, run
@ -11,6 +13,18 @@ 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,
'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():
body = request.body
@ -26,7 +40,7 @@ def extract_request_data():
@route('/')
def index():
return "Hello World!"
return "Hello World!<br/>This is the fronius2mqtt daemon by Gerrit Beine"
@post('/current_data_inverter/<device>')
@ -162,8 +176,12 @@ def logdata_data(device):
def start_mqtt():
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:
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)
@ -201,6 +219,21 @@ 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_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,
default='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']
if 'mqtt_topic' in data:
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:
daemon_args.http_host = data['http_host']
if 'http_port' in data: