From b4a833601fcd59576e76757c94e1542b424472cc Mon Sep 17 00:00:00 2001 From: Gerrit Beine Date: Thu, 27 Jul 2023 17:27:53 +0200 Subject: [PATCH] Complete rewrite, uses Fronius Push API now This commit contains a complete rewrite - HTTP push API server based on bottle - no more dependency to pyfronius --- .gitignore | 8 +- .idea/.gitignore | 8 + .idea/fronius2mqtt.iml | 14 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + README.md | 25 +- bin/fronius2mqtt | 13 - fronius2mqtt | 260 ++++++++++++++++++ fronius2mqtt.conf.example | 19 +- fronius2mqtt.yaml.example | 28 -- fronius2mqtt/fronius2mqtt/__init__.py | 0 fronius2mqtt/fronius2mqtt/config.py | 62 ----- fronius2mqtt/fronius2mqtt/daemon.py | 27 -- fronius2mqtt/fronius2mqtt/device.py | 16 -- fronius2mqtt/fronius2mqtt/flow.py | 14 - fronius2mqtt/fronius2mqtt/froniusfactory.py | 43 --- fronius2mqtt/fronius2mqtt/inverter.py | 19 -- fronius2mqtt/fronius2mqtt/meter.py | 19 -- fronius2mqtt/fronius2mqtt/mqtt.py | 22 -- fronius2mqtt/fronius2mqtt/storage.py | 18 -- fronius2mqtt/setup.py | 17 -- install | 10 +- logging.conf | 21 -- run | 6 +- 26 files changed, 344 insertions(+), 349 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/fronius2mqtt.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml delete mode 100755 bin/fronius2mqtt create mode 100755 fronius2mqtt delete mode 100644 fronius2mqtt.yaml.example delete mode 100644 fronius2mqtt/fronius2mqtt/__init__.py delete mode 100644 fronius2mqtt/fronius2mqtt/config.py delete mode 100644 fronius2mqtt/fronius2mqtt/daemon.py delete mode 100644 fronius2mqtt/fronius2mqtt/device.py delete mode 100644 fronius2mqtt/fronius2mqtt/flow.py delete mode 100644 fronius2mqtt/fronius2mqtt/froniusfactory.py delete mode 100644 fronius2mqtt/fronius2mqtt/inverter.py delete mode 100644 fronius2mqtt/fronius2mqtt/meter.py delete mode 100644 fronius2mqtt/fronius2mqtt/mqtt.py delete mode 100644 fronius2mqtt/fronius2mqtt/storage.py delete mode 100644 fronius2mqtt/setup.py delete mode 100644 logging.conf diff --git a/.gitignore b/.gitignore index 7d7ee1e..9a3462a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,6 @@ -__pycache__ bin +include lib share -fronius2mqtt.bbprojectd -pip-selfcheck.json pyvenv.cfg -pyfronius -fronius2mqtt/fronius2mqtt.egg-info -fronius2mqtt.yaml +.DS_Store diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/fronius2mqtt.iml b/.idea/fronius2mqtt.iml new file mode 100644 index 0000000..9583a06 --- /dev/null +++ b/.idea/fronius2mqtt.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..6bf4098 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..19923a8 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 03d6510..aca690f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,13 @@ # fronius2mqtt + A Fronius HTTP API to MQTT bridge +Attention: This is a complete rewrite of the bridge. +While the old fronius2mqtt brigde used polling the inverters to fetch the data, the new version make use of the push feature provided by Fronius Symo. + +The daemon offers no HTTP endpoints which can be configured in the configuration interface of each inverter. +It forwards the data directly to MQTT. + ## Install - clone the git repository @@ -9,5 +16,21 @@ A Fronius HTTP API to MQTT bridge ## Configuration -- copy ```fronius2mqtt.yaml.example``` +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. | diff --git a/bin/fronius2mqtt b/bin/fronius2mqtt deleted file mode 100755 index 014d068..0000000 --- a/bin/fronius2mqtt +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python3 - -from fronius2mqtt import config -from fronius2mqtt import daemon - -def main(): - cfg = config.Config() - cfg.read() - d = daemon.Daemon(cfg) - d.run() - -main() - diff --git a/fronius2mqtt b/fronius2mqtt new file mode 100755 index 0000000..b4a5859 --- /dev/null +++ b/fronius2mqtt @@ -0,0 +1,260 @@ +#!/usr/bin/env python + +import argparse +import json +import os +import paho.mqtt.client as mqtt + +from bottle import request, route, post, run + + +mqtt_client = None +daemon_args = None + + +def extract_request_body(): + body = request.body + string = body.getvalue().decode('utf-8') + return string + + +def extract_request_data(): + json_string = extract_request_body() + data = json.loads(json_string) + return data + + +@route('/') +def index(): + return "Hello World!" + + +@post('/current_data_inverter/') +def current_data_inverter(device): + data = extract_request_data() + if not 'Body' in data: + return "Empty" + topic_base = "{}/{}/current_data_inverter".format(daemon_args.mqtt_topic, device) + if 'PAC' in data['Body'] and 'Values' in data['Body']['PAC']: + for k, v in data['Body']['PAC']['Values'].items(): + topic = "{}/pac/{}".format(topic_base, k) + mqtt_client.publish(topic, v) + if 'DAY_ENERGY' in data['Body'] and 'Values' in data['Body']['DAY_ENERGY']: + for k, v in data['Body']['DAY_ENERGY']['Values'].items(): + topic = "{}/day_energy/{}".format(topic_base, k) + mqtt_client.publish(topic, v) + if 'YEAR_ENERGY' in data['Body'] and 'Values' in data['Body']['YEAR_ENERGY']: + for k, v in data['Body']['YEAR_ENERGY']['Values'].items(): + topic = "{}/year_energy/{}".format(topic_base, k) + mqtt_client.publish(topic, v) + if 'TOTAL_ENERGY' in data['Body'] and 'Values' in data['Body']['TOTAL_ENERGY']: + for k, v in data['Body']['TOTAL_ENERGY']['Values'].items(): + topic = "{}/total_energy/{}".format(topic_base, k) + mqtt_client.publish(topic, v) + return "OK" + + +@post('/current_data_meter/') +def current_data_meter(device): + data = extract_request_data() + if not 'Body' in data: + return "Empty" + topic_base = "{}/{}/current_data_meter".format(daemon_args.mqtt_topic, device) + for m, d in data['Body'].items(): + for k, v in d.items(): + if v is not None and type(v) in [int, float, str] : + topic = "{}/{}/{}".format(topic_base, m, k.lower()) + mqtt_client.publish(topic, v) + return "OK" + + +@post('/current_data_powerflow/') +def current_data_powerflow(device): + data = extract_request_data() + if not 'Body' in data: + return "Empty" + topic_base = "{}/{}/current_data_powerflow".format(daemon_args.mqtt_topic, device) + if 'Site' in data['Body']: + for k, v in data['Body']['Site'].items(): + if v is not None: + topic = "{}/site/{}".format(topic_base, k.lower()) + mqtt_client.publish(topic, v) + if 'Inverters' in data['Body']: + for i, d in data['Body']['Inverters'].items(): + for k, v in d.items(): + if v is not None: + topic = "{}/{}/{}".format(topic_base, i, k.lower()) + mqtt_client.publish(topic, v) + return "OK" + + +@post('/current_data_storages/') +def current_data_storages(device): + data = extract_request_data() + if not 'Body' in data: + return "Empty" + topic_base = "{}/{}/current_data_storages".format(daemon_args.mqtt_topic, device) + for s, d in data['Body'].items(): + if 'Controller' in d: + for k, v in d['Controller'].items(): + if v is not None and type(v) in [int, float, str] : + topic = "{}/{}/{}".format(topic_base, s, k.lower()) + mqtt_client.publish(topic, v) + if 'Modules' in d: + for m in d['Modules']: + serial = m['Details']['Serial'] + for k, v in m.items(): + if v is not None and type(v) in [int, float, str] : + topic = "{}/{}/{}/{}".format(topic_base, s, serial.lower(), k.lower()) + mqtt_client.publish(topic, v) + return "OK" + + +@post('/current_data_sensorcard/') +def current_data_sensorcard(device): + data = extract_request_data() + if not 'Body' in data: + return "Empty" + topic_base = "{}/{}/current_data_sensorcard".format(daemon_args.mqtt_topic, device) +# TODO not yet implemented + return "OK" + + +@post('/current_data_stringcontrol/') +def current_data_stringcontrol(device): + data = extract_request_data() + if not 'Body' in data: + return "Empty" + topic_base = "{}/{}/current_data_stringcontrol".format(daemon_args.mqtt_topic, device) +# TODO not yet implemented + return "OK" + + +@post('/datamanager_io_states/') +def datamanager_io_states(device): + data = extract_request_data() + topic_base = "{}/{}/datamanager_io_states".format(daemon_args.mqtt_topic, device) + for p, d in data.items(): + for k, v in d.items(): + if v is not None: + topic = "{}/{}/{}".format(topic_base, p.replace(' ', '_'), k.lower()) + mqtt_client.publish(topic, v) + return "OK" + + +@post('/logdata_errors_and_events/') +def logdata_errors_and_events(device): + data = extract_request_data() + if not 'Body' in data: + return "Empty" + topic_base = "{}/{}/logdata_errors_and_events".format(daemon_args.mqtt_topic, device) + return "OK" + + +@post('/logdata_data/') +def logdata_data(device): + data = extract_request_data() + if not 'Body' in data: + return "Empty" + topic_base = "{}/{}/logdata_data".format(daemon_args.mqtt_topic, device) + return "OK" + + +def start_mqtt(): + global daemon_args + mqtt_client = mqtt.Client(daemon_args.mqtt_clientid) + if daemon_args.verbose: + 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 + + +def start_http(): + global daemon_args + run(host=daemon_args.http_host, port=daemon_args.http_port, debug=daemon_args.verbose) + + +def parse_args(): + parser = argparse.ArgumentParser( + prog='fronius2mqtt', + description='Send the data from Fronius HTTP push to MQTT', + epilog='Have a lot of fun!') + parser.add_argument('-m', '--mqtt_host', type=str, + default='localhost', + help='The hostname of the MQTT server. Default is localhost') + parser.add_argument('--mqtt_port', type=int, + default=1883, + help='The port of the MQTT server. Default is 1883') + parser.add_argument('--mqtt_keepalive', type=int, + default=30, + help='The keep alive interval for the MQTT server connection in seconds. Default is 30') + parser.add_argument('--mqtt_clientid', type=str, + default='fronius2mqtt', + help='The clientid to send to the MQTT server. Default is fronius2mqtt') + parser.add_argument('-u', '--mqtt_user', type=str, + help='The username for the MQTT server connection.') + parser.add_argument('-p', '--mqtt_password', type=str, + help='The password for the MQTT server connection.') + parser.add_argument('-t', '--mqtt_topic', type=str, + default='home/fronius', + help='The topic to publish MQTT message. Default is home/fronius') + 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('-v', '--verbose', + default=False, + action='store_true', + help='Be verbose while running.') + args = parser.parse_args() + return args + + +def parse_config(): + global daemon_args + + if not os.path.isfile(daemon_args.config): + return + + with open(daemon_args.config, "r") as config_file: + data = json.load(config_file) + if 'mqtt_host' in data: + daemon_args.mqtt_host = data['mqtt_host'] + if 'mqtt_port' in data: + daemon_args.mqtt_port = data['mqtt_port'] + if 'mqtt_keepalive' in data: + daemon_args.mqtt_keepalive = data['mqtt_keepalive'] + if 'mqtt_clientid' in data: + daemon_args.mqtt_clientid = data['mqtt_clientid'] + if 'mqtt_user' in data: + daemon_args.mqtt_user = data['mqtt_user'] + if 'mqtt_password' in data: + daemon_args.mqtt_password = data['mqtt_password'] + if 'mqtt_topic' in data: + daemon_args.mqtt_topic = data['mqtt_topic'] + if 'http_host' in data: + daemon_args.http_host = data['http_host'] + if 'http_port' in data: + daemon_args.http_port = data['http_port'] + if 'verbose' in data: + daemon_args.verbose = data['verbose'] + + +def main(): + global daemon_args, mqtt_client + daemon_args = parse_args() + parse_config() + mqtt_client = start_mqtt() + start_http() + + +if __name__ == "__main__": + main() diff --git a/fronius2mqtt.conf.example b/fronius2mqtt.conf.example index 21ee3b2..837b0f9 100644 --- a/fronius2mqtt.conf.example +++ b/fronius2mqtt.conf.example @@ -1,13 +1,6 @@ -[program:fronius2mqtt] -command=/opt/service/fronius2mqtt/run -process_name=%(program_name)s -directory=/opt/service/fronius2mqtt -umask=022 -autostart=true -redirect_stderr=true -stdout_logfile=/var/log/fronius2mqtt/main.log -stdout_logfile_maxbytes=2MB -stdout_logfile_backups=1 -stdout_capture_maxbytes=0 -stdout_events_enabled=false -environment=LOGDIR=/var/log/fronius2mqtt +{ + "mqtt_user": "fronius2mqtt", + "mqtt_password": "t0p_s3cr3t", + "http_host": "0.0.0.0", + "http_port": 80 +} diff --git a/fronius2mqtt.yaml.example b/fronius2mqtt.yaml.example deleted file mode 100644 index 0cfb918..0000000 --- a/fronius2mqtt.yaml.example +++ /dev/null @@ -1,28 +0,0 @@ -mqtt: - host: localhost - port: 1883 - user: user - password: secret - topic: "mqtt/topic/for/fronius" - qos: 1 - retain: true -fronius: - - inverter: - host: "inverter.myfroniusfarm" - device: 1 - topic: "inverter_1" - - inverter: - host: "inverter.myfroniusfarm" - device: 2 - topic: "inverter_2" - - storage: - host: "storage.myfroniusfarm" - device: 0 - topic: "battery_1" - - meter: - host: "storage.myfroniusfarm" - device: 0 - topic: "meter" - - flow: - host: "storage.myfroniusfarm" - topic: "flow" diff --git a/fronius2mqtt/fronius2mqtt/__init__.py b/fronius2mqtt/fronius2mqtt/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/fronius2mqtt/fronius2mqtt/config.py b/fronius2mqtt/fronius2mqtt/config.py deleted file mode 100644 index 66886fe..0000000 --- a/fronius2mqtt/fronius2mqtt/config.py +++ /dev/null @@ -1,62 +0,0 @@ -import yaml -import logging -import logging.config - -class Config: - """Class for parsing fronius2mqtt.yaml.""" - - def __init__(self): - """Initialize Config class.""" - logging.config.fileConfig('logging.conf') - self._mqtt = {} - self._fronius = {} - - - def read(self, file='fronius2mqtt.yaml'): - """Read config.""" - logging.debug("Reading %s", file) - try: - with open(file, 'r') as filehandle: - config = yaml.load(filehandle) - self._parse_mqtt(config) - self._parse_fronius(config) - except FileNotFoundError as ex: - logging.error("Error while reading %s: %s", file, ex) - - def _parse_mqtt(self, config): - """Parse the mqtt section of fronius2mqtt.yaml.""" - if "mqtt" in config: - self._mqtt = config["mqtt"] - if not "host" in self._mqtt: - raise ValueError("MQTT host not set") - if not "port" in self._mqtt: - raise ValueError("MQTT port not set") - if not "user" in self._mqtt: - raise ValueError("MQTT user not set") - if not "password" in self._mqtt: - raise ValueError("MQTT password not set") - if not "topic" in self._mqtt: - raise ValueError("MQTT topic not set") - if not "qos" in self._mqtt: - self._mqtt["qos"] = 0 - if not "retain" in self._mqtt: - self._mqtt["retain"] = False - - def _parse_fronius(self, config): - """Parse the fronius section of fronius2mqtt.yaml.""" - if "fronius" in config: - self._fronius = config["fronius"] - for item in self._fronius: - if len(item) != 1: - raise ValueError("Fronius device configuration contains more than one item.") - for (type, properties) in item.items(): - if not "host" in properties: - raise ValueError("Missing host for Fronius device") - if not "topic" in properties: - raise ValueError("Missing topic for Fronius device") - - def mqtt(self): - return self._mqtt - - def fronius(self): - return self._fronius diff --git a/fronius2mqtt/fronius2mqtt/daemon.py b/fronius2mqtt/fronius2mqtt/daemon.py deleted file mode 100644 index 1313c26..0000000 --- a/fronius2mqtt/fronius2mqtt/daemon.py +++ /dev/null @@ -1,27 +0,0 @@ - -import time - -from fronius2mqtt import froniusfactory -from fronius2mqtt import mqtt - -class Daemon: - - def __init__(self, config): - self.config = config - self.devices = [] - self._init_mqtt() - self._init_fronius() - - def run(self): - while True: - for device in self.devices: - device.update_and_publish(self.mqtt) - time.sleep(5) - - def _init_mqtt(self): - self.mqtt = mqtt.Mqtt(self.config.mqtt()) - self.mqtt.connect() - - def _init_fronius(self): - factory = froniusfactory.FroniusFactory(self.config.fronius()) - self.devices = factory.create_devices() diff --git a/fronius2mqtt/fronius2mqtt/device.py b/fronius2mqtt/fronius2mqtt/device.py deleted file mode 100644 index 827d951..0000000 --- a/fronius2mqtt/fronius2mqtt/device.py +++ /dev/null @@ -1,16 +0,0 @@ - -import logging - -class Device: - - def update(self): - raise NotImplementedError("update not implemented") - - def update_and_publish(self, mqtt): - data = self.update() - for (key, value) in data.items(): - if 'value' in value: - mqtt.publish("{}/{}".format(self.topic, key), value['value']) - else: - logging.info("Ignore %s: %s", key, value) - \ No newline at end of file diff --git a/fronius2mqtt/fronius2mqtt/flow.py b/fronius2mqtt/fronius2mqtt/flow.py deleted file mode 100644 index f4d6fce..0000000 --- a/fronius2mqtt/fronius2mqtt/flow.py +++ /dev/null @@ -1,14 +0,0 @@ - -from pyfronius import fronius -from fronius2mqtt import device - -class Flow(device.Device): - - def __init__(self, config): - self.host = config['host'] - self.topic = config['topic'] - self.fronius = fronius.Fronius(self.host) - - def update(self): - data = self.fronius.current_power_flow() - return data diff --git a/fronius2mqtt/fronius2mqtt/froniusfactory.py b/fronius2mqtt/fronius2mqtt/froniusfactory.py deleted file mode 100644 index 1b1da71..0000000 --- a/fronius2mqtt/fronius2mqtt/froniusfactory.py +++ /dev/null @@ -1,43 +0,0 @@ - -from fronius2mqtt import inverter -from fronius2mqtt import storage -from fronius2mqtt import flow -from fronius2mqtt import meter - -class FroniusFactory: - - def __init__(self, config): - self.config = config - - def create_devices(self): - devices = [] - for c in self.config: - (type, properties) = c.popitem() - if not type in factory: - raise ValueError("Not a valid device: {}".format(type)) - device = factory[type](properties) - devices.append(device) - return devices - -def _create_inverter(properties): - device = inverter.Inverter(properties) - return device - -def _create_storage(properties): - device = storage.Storage(properties) - return device - -def _create_meter(properties): - device = meter.Meter(properties) - return device - -def _create_flow(properties): - device = flow.Flow(properties) - return device - -factory = { - "inverter" : _create_inverter, - "storage" : _create_storage, - "meter" : _create_meter, - "flow" : _create_flow -} diff --git a/fronius2mqtt/fronius2mqtt/inverter.py b/fronius2mqtt/fronius2mqtt/inverter.py deleted file mode 100644 index 0847552..0000000 --- a/fronius2mqtt/fronius2mqtt/inverter.py +++ /dev/null @@ -1,19 +0,0 @@ - -from pyfronius import fronius -from fronius2mqtt import device - -class Inverter(device.Device): - - def __init__(self, config): - self.host = config['host'] - if 'device' in config: - self.device = config['device'] - self.topic = config['topic'] - self.fronius = fronius.Fronius(self.host) - - def update(self): - if hasattr(self, 'device'): - data = self.fronius.current_inverter_data(self.device) - else: - data = self.fronius.current_system_inverter_data() - return data diff --git a/fronius2mqtt/fronius2mqtt/meter.py b/fronius2mqtt/fronius2mqtt/meter.py deleted file mode 100644 index 5e9d65c..0000000 --- a/fronius2mqtt/fronius2mqtt/meter.py +++ /dev/null @@ -1,19 +0,0 @@ - -from pyfronius import fronius -from fronius2mqtt import device - -class Meter(device.Device): - - def __init__(self, config): - self.host = config['host'] - if 'device' in config: - self.device = config['device'] - self.topic = config['topic'] - self.fronius = fronius.Fronius(self.host) - - def update(self): - if hasattr(self, 'device'): - data = self.fronius.current_meter_data(self.device) - else: - data = self.fronius.current_system_meter_data() - return data diff --git a/fronius2mqtt/fronius2mqtt/mqtt.py b/fronius2mqtt/fronius2mqtt/mqtt.py deleted file mode 100644 index ca7f48d..0000000 --- a/fronius2mqtt/fronius2mqtt/mqtt.py +++ /dev/null @@ -1,22 +0,0 @@ - -import logging -import paho.mqtt.client as mqtt - -class Mqtt: - - def __init__(self, config): - self._config = config - - def connect(self): - self._client = mqtt.Client() - self._client.username_pw_set(self._config['user'], self._config['password']) - self._client.connect(self._config['host'], self._config['port']) - self._client.loop_start() - - def disconnect(self): - self.client.disconnect() - - def publish(self, topic, payload): - topic = "{}/{}".format(self._config['topic'], topic) - logging.info("Publish %s: %s, %s, %s", topic, payload, self._config["qos"], self._config["retain"]) - self._client.publish(topic, payload, self._config["qos"], self._config["retain"]) diff --git a/fronius2mqtt/fronius2mqtt/storage.py b/fronius2mqtt/fronius2mqtt/storage.py deleted file mode 100644 index 001e0a3..0000000 --- a/fronius2mqtt/fronius2mqtt/storage.py +++ /dev/null @@ -1,18 +0,0 @@ - -from pyfronius import fronius -from fronius2mqtt import device - -class Storage(device.Device): - - def __init__(self, config): - self.host = config['host'] - if 'device' in config: - self.device = config['device'] - else: - self.device = 0 - self.topic = config['topic'] - self.fronius = fronius.Fronius(self.host) - - def update(self): - data = self.fronius.current_storage_data(self.device) - return data diff --git a/fronius2mqtt/setup.py b/fronius2mqtt/setup.py deleted file mode 100644 index 96c5f3c..0000000 --- a/fronius2mqtt/setup.py +++ /dev/null @@ -1,17 +0,0 @@ -from setuptools import setup - -setup(name='fronius2mqtt', - version='0.2', - description='Fronius 2 MQTT bridge', - url='https://github.com/gbeine/fronius2mqtt', - author='Gerrit', - author_email='mail@gerritbeine.de', - license='MIT', - packages=['fronius2mqtt'], - requires=[ - 'logging', - 'paho.mqtt', - 'pyfronius', - 'pyyaml', - ], - zip_safe=False) diff --git a/install b/install index 1951199..e833892 100755 --- a/install +++ b/install @@ -1,10 +1,8 @@ #!/bin/sh -python3 -m venv . +python3 -m venv venv -git clone https://github.com/gbeine/pyfronius.git +. venv/bin/activate -. bin/activate -pip install wheel paho-mqtt pyyaml -pip install -e pyfronius -pip install -e fronius2mqtt +pip install bottle +pip install paho.mqtt diff --git a/logging.conf b/logging.conf deleted file mode 100644 index 207cf49..0000000 --- a/logging.conf +++ /dev/null @@ -1,21 +0,0 @@ -[loggers] -keys=root - -[handlers] -keys=consoleHandler - -[formatters] -keys=simpleFormatter - -[logger_root] -level=DEBUG -handlers=consoleHandler - -[handler_consoleHandler] -class=StreamHandler -level=DEBUG -formatter=simpleFormatter -args=(sys.stdout,) - -[formatter_simpleFormatter] -format=%(asctime)s - %(name)s - %(levelname)s - %(message)s diff --git a/run b/run index cccbb92..3ce446a 100755 --- a/run +++ b/run @@ -1,7 +1,5 @@ #!/bin/sh -touch ${LOGDIR}/.tmpfs +. venv/bin/activate -. bin/activate - -exec bin/fronius2mqtt +exec /usr/bin/env python fronius2mqtt