diff --git a/README.md b/README.md index f4d4c4d..b8821d4 100644 --- a/README.md +++ b/README.md @@ -242,6 +242,35 @@ AT+UPGRADE_Command_Supported: 255 Method_Of_Protocol_Upgrade: 255 ``` +## Running multiple inverter stations + +If you have multiple inverter stations, you can add them to the config file as a list. Make sure to publish to separate MQTT topics per inverter instance, and configure the Home Assistant MQTT sensors accordingly. + +```json +[ + { + "name": "Trannergy-1", + "stationId": 987, + "inverterId": 654, + "loggerId": 321, + "mqtt": { + "topic": "inverter1" + } + }, + { + "name": "Trannergy-2", + "stationId": 123, + "inverterId": 456, + "loggerId": 789, + "mqtt": { + "topic": "inverter2" + } + } +] +``` + +*Minimized example config; see `config.sample.json` for all fields.* + ## Home Assistant ```yaml diff --git a/solarman/__init__.py b/solarman/__init__.py index b9c80fd..78ed4fa 100644 --- a/solarman/__init__.py +++ b/solarman/__init__.py @@ -43,7 +43,7 @@ def main(): args = parser.parse_args() solarman = SolarmanPV(args.file) if args.single: - solarman.single_run(args.file) + solarman.single_run_loop(args.file) elif args.daemon: solarman.daemon(args.file, args.interval) elif args.validate: diff --git a/solarman/helpers.py b/solarman/helpers.py index 543f27c..314bcbb 100644 --- a/solarman/helpers.py +++ b/solarman/helpers.py @@ -63,6 +63,7 @@ If you need any further help, please see: + """ @@ -85,9 +86,7 @@ def __init__(self, config): except SchemaError as err: print(err.message) sys.exit(1) - print(_VALID) - sys.exit(0) class HashPassword: # pylint: disable=too-few-public-methods diff --git a/solarman/solarmanpv.py b/solarman/solarmanpv.py index d6f2439..dff654f 100644 --- a/solarman/solarmanpv.py +++ b/solarman/solarmanpv.py @@ -13,6 +13,7 @@ logging.basicConfig(level=logging.INFO) + class SolarmanPV: """ SolarmanPV data collection and MQTT publishing @@ -20,9 +21,6 @@ class SolarmanPV: def __init__(self, file): self.config = self.load_config(file) - self.api = SolarmanApi(self.config) - self.mqtt = Mqtt(self.config["mqtt"]) - def load_config(self, file): """ @@ -31,25 +29,30 @@ def load_config(self, file): """ with open(file, "r", encoding="utf-8") as config_file: config = json.load(config_file) - return config + if not isinstance(config, list): + config = [config] + + return config - def validate_config(self, file): + def validate_config(self, config): """ Validate config file :param file: Config file :return: """ - config = self.load_config(file) - ConfigCheck(config) - + config = self.load_config(config) + for conf in config: + print( + f"## CONFIG INSTANCE NAME: {conf['name']} [{config.index(conf) + 1}/{len(config)}]" + ) + ConfigCheck(conf) - def single_run(self, file): + def single_run(self, config): """ Output current watts and kilowatts :return: """ - config = self.load_config(file) pvdata = SolarmanApi(config) station_data = pvdata.station_realtime @@ -119,12 +122,10 @@ def single_run(self, file): ) else: mqtt_connection.message( - topic + "/inverter/deviceState", - inverter_data.get("deviceState") + topic + "/inverter/deviceState", inverter_data.get("deviceState") ) mqtt_connection.message( - topic + "/logger/deviceState", - logger_data.get("deviceState") + topic + "/logger/deviceState", logger_data.get("deviceState") ) logging.info( "%s - Inverter DeviceState: %s" @@ -133,6 +134,13 @@ def single_run(self, file): inverter_device_state, ) + def single_run_loop(self, file): + """ + Perform single runs for all config instances + """ + config = self.load_config(file) + for conf in config: + self.single_run(conf) def daemon(self, file, interval): """ @@ -142,10 +150,12 @@ def daemon(self, file, interval): :return: """ interval = int(interval) - logging.info("Starting daemonized with a %s seconds run interval", str(interval)) + logging.info( + "Starting daemonized with a %s seconds run interval", str(interval) + ) while True: try: - SolarmanPV.single_run(self, file) + SolarmanPV.single_run_loop(self, file) time.sleep(interval) except Exception as error: # pylint: disable=broad-except logging.error("Error on start: %s", str(error)) @@ -154,7 +164,6 @@ def daemon(self, file, interval): logging.info("Exiting on keyboard interrupt") sys.exit(0) - def create_passhash(self, password): """ Create passhash from password