Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use env variables for config #72

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions SunGather/configreader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import os


class Configreader:

ENV_PREFIX = 'SUNGATHER_'

def __init__(self, config, prefix=None):
self.config = config
self.prefix = prefix

def get(self, key, default):
env = self.ENV_PREFIX + self.prefix.upper() + '_' + key.upper()
return os.getenv(env, self.config.get(key, default))
6 changes: 3 additions & 3 deletions SunGather/exports/influxdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ def configure(self, config, inverter):
'token': config.get('token', None),
'username': config.get('username', None),
'password': config.get('password', None),
'org': config.get('org',None),
'bucket': config.get('bucket',None)
'org': config.get('org', None),
'bucket': config.get('bucket', None)
}
self.influxdb_measurements = [{}]
self.influxdb_measurements.pop() # Remove null value from list
Expand All @@ -31,7 +31,7 @@ def configure(self, config, inverter):
token=self.influxdb_config['token'],
org=self.influxdb_config['org']
)
elif config.get('username',False) and config.get('password',False):
elif config.get('username', False) and config.get('password', False):
self.client = influxdb_client.InfluxDBClient(
url=self.influxdb_config['url'],
token=f"{self.influxdb_config['username']}:{self.influxdb_config['password']}",
Expand Down
3 changes: 1 addition & 2 deletions SunGather/exports/jsonserver.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
import json
from threading import Thread
from version import __version__


import logging
Expand All @@ -14,7 +13,7 @@ def __init__(self):
# Configure Webserver
def configure(self, config, inverter):
try:
self.webServer = HTTPServer(('', config.get('port',8082)), MyServer)
self.webServer = HTTPServer(('', int(config.get('port', 8082))), MyServer)
self.t = Thread(target=self.webServer.serve_forever)
self.t.daemon = True # Make it a deamon, so if main loop ends the webserver dies
self.t.start()
Expand Down
6 changes: 3 additions & 3 deletions SunGather/exports/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ def configure(self, config, inverter):
model = inverter.getInverterModel(True)
self.mqtt_config = {
'host': config.get('host', None),
'port': config.get('port', 1883),
'port': int(config.get('port', 1883)),
'client_id': config.get('client_id', f'SunGather-{model}'),
'topic': config.get('topic', f"inverter/{model}/registers"),
'username': config.get('username', None),
'password': config.get('password',None),
'homeassistant': config.get('homeassistant',False)
'password': config.get('password', None),
'homeassistant': bool(config.get('homeassistant', False))
}

self.ha_sensors = [{}]
Expand Down
6 changes: 3 additions & 3 deletions SunGather/exports/pvoutput.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ def configure(self, config, inverter):
'api': config.get('api', None),
'sid': config.get('sid', None),
'join_team': config.get('join_team', True),
'rate_limit': config.get('rate_limit', 60),
'cumulative_flag': config.get('cumulative_flag',0),
'batch_points': config.get('batch_points',1)
'rate_limit': int(config.get('rate_limit', 60)),
'cumulative_flag': int(config.get('cumulative_flag', 0)),
'batch_points': int(config.get('batch_points', 1))
}
self.pvoutput_parameters = [{}]
self.pvoutput_parameters.pop() # Remove null value from list
Expand Down
2 changes: 1 addition & 1 deletion SunGather/exports/webserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def __init__(self):
# Configure Webserver
def configure(self, config, inverter):
try:
self.webServer = HTTPServer(('', config.get('port',8080)), MyServer)
self.webServer = HTTPServer(('', int(config.get('port', 8080))), MyServer)
self.t = Thread(target=self.webServer.serve_forever)
self.t.daemon = True # Make it a deamon, so if main loop ends the webserver dies
self.t.start()
Expand Down
64 changes: 36 additions & 28 deletions SunGather/sungather.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from SungrowModbusTcpClient import SungrowModbusTcpClient
from SungrowModbusWebClient import SungrowModbusWebClient
from pymodbus.client.sync import ModbusTcpClient

from SunGather.configreader import Configreader
from version import __version__
from datetime import datetime

Expand All @@ -15,7 +17,9 @@
import time
import os

class SungrowInverter():

class Sungather:

def __init__(self, config_inverter):
self.client_config = {
"host": config_inverter.get('host'),
Expand Down Expand Up @@ -113,7 +117,7 @@ def configure_registers(self,registersfile):

# Load register list based on name and value after checking model
for register in registersfile['registers'][0]['read']:
if register.get('level',3) <= self.inverter_config.get('level') or self.inverter_config.get('level') == 3:
if register.get('level', 3) <= self.inverter_config.get('level') or self.inverter_config.get('level') == 3:
register['type'] = "read"
register.pop('level')
if register.get('smart_meter') and self.inverter_config.get('smart_meter'):
Expand All @@ -128,7 +132,7 @@ def configure_registers(self,registersfile):
self.registers.append(register)

for register in registersfile['registers'][1]['hold']:
if register.get('level',3) <= self.inverter_config.get('level') or self.inverter_config.get('level') == 3:
if register.get('level', 3) <= self.inverter_config.get('level') or self.inverter_config.get('level') == 3:
register['type'] = "hold"
register.pop('level')
if register.get('smart_meter') and self.inverter_config.get('smart_meter'):
Expand Down Expand Up @@ -171,9 +175,9 @@ def load_registers(self, register_type, start, count=100):
try:
logging.debug(f'load_registers: {register_type}, {start}:{count}')
if register_type == "read":
rr = self.client.read_input_registers(start,count=count, unit=self.inverter_config['slave'])
rr = self.client.read_input_registers(start, count=count, unit=self.inverter_config['slave'])
elif register_type == "hold":
rr = self.client.read_holding_registers(start,count=count, unit=self.inverter_config['slave'])
rr = self.client.read_holding_registers(start, count=count, unit=self.inverter_config['slave'])
else:
raise RuntimeError(f"Unsupported register type: {type}")
except Exception as err:
Expand Down Expand Up @@ -483,34 +487,36 @@ def main():
except Exception as err:
logging.error(f"Failed: Loading registers: {os.getcwd()}/registers-sungrow.yaml {err}")
sys.exit(f"Failed: Loading registers: {os.getcwd()}/registers-sungrow.yaml {err}")


config = Configreader(configfile['inverter'], 'INVERTER')
config_inverter = {
"host": configfile['inverter'].get('host',None),
"port": configfile['inverter'].get('port',502),
"timeout": configfile['inverter'].get('timeout',10),
"retries": configfile['inverter'].get('retries',3),
"slave": configfile['inverter'].get('slave',0x01),
"scan_interval": configfile['inverter'].get('scan_interval',30),
"connection": configfile['inverter'].get('connection',"modbus"),
"model": configfile['inverter'].get('model',None),
"smart_meter": configfile['inverter'].get('smart_meter',False),
"use_local_time": configfile['inverter'].get('use_local_time',False),
"log_console": configfile['inverter'].get('log_console','WARNING'),
"log_file": configfile['inverter'].get('log_file','OFF'),
"level": configfile['inverter'].get('level',1)
"host": config.get('host', None),
"port": int(config.get('port', 502)),
"timeout": int(config.get('timeout', 10)),
"retries": int(config.get('retries', 3)),
"slave": int(config.get('slave', 0x01)),
"scan_interval": int(config.get('scan_interval', 30)),
"connection": config.get('connection', "modbus"),
"model": config.get('model', None),
"smart_meter": bool(config.get('smart_meter', False)),
"use_local_time": bool(config.get('use_local_time', False)),
"log_console": config.get('log_console', 'WARNING'),
"log_file": config.get('log_file', 'OFF'),
"level": int(config.get('level', 1))
}

if 'loglevel' in locals():
logger.handlers[0].setLevel(loglevel)
else:
logger.handlers[0].setLevel(config_inverter['log_console'])

if not config_inverter['log_file'] == "OFF":
if config_inverter['log_file'] == "DEBUG" or config_inverter['log_file'] == "INFO" or config_inverter['log_file'] == "WARNING" or config_inverter['log_file'] == "ERROR":
config_log_file = config_inverter['log_file']
if not config_log_file == "OFF":
if config_log_file == "DEBUG" or config_log_file == "INFO" or config_log_file == "WARNING" or config_log_file == "ERROR":
logfile = logfolder + "SunGather.log"
fh = logging.handlers.RotatingFileHandler(logfile, mode='w', encoding='utf-8', maxBytes=10485760, backupCount=10) # Log 10mb files, 10 x files = 100mb
fh.formatter = logger.handlers[0].formatter
fh.setLevel(config_inverter['log_file'])
fh.setLevel(config_log_file)
logger.addHandler(fh)
else:
logging.warning(f"log_file: Valid options are: DEBUG, INFO, WARNING, ERROR and OFF")
Expand All @@ -522,7 +528,7 @@ def main():
logging.debug(f'Inverter Config Loaded: {config_inverter}')

if config_inverter.get('host'):
inverter = SungrowInverter(config_inverter)
inverter = Sungather(config_inverter)
else:
logging.error(f"Error: host option in config is required")
sys.exit("Error: host option in config is required")
Expand All @@ -538,15 +544,17 @@ def main():
exports = []
if configfile.get('exports'):
for export in configfile.get('exports'):
exportname = export.get('name')
try:
if export.get('enabled', False):
export_load = importlib.import_module("exports." + export.get('name'))
logging.info(f"Loading Export: exports\{export.get('name')}")
exports.append(getattr(export_load, "export_" + export.get('name'))())
retval = exports[-1].configure(export, inverter)
export_load = importlib.import_module("exports." + exportname)
logging.info(f"Loading Export: {exportname}")
instance = getattr(export_load, "export_" + exportname)()
retval = instance.configure(Configreader(export, exportname), inverter)
exports.append(instance)
except Exception as err:
logging.error(f"Failed loading export: {err}" +
f"\n\t\t\t Please make sure {export.get('name')}.py exists in the exports folder")
f"\n\t\t\t Please make sure {exportname}.py exists in the exports folder")

scan_interval = config_inverter.get('scan_interval')

Expand Down