diff options
-rwxr-xr-x | inverter-bot | 83 | ||||
-rw-r--r-- | requirements.txt | 2 | ||||
-rw-r--r-- | test.py | 35 |
3 files changed, 93 insertions, 27 deletions
diff --git a/inverter-bot b/inverter-bot index a4cac30..bc2b6d7 100755 --- a/inverter-bot +++ b/inverter-bot @@ -1,6 +1,7 @@ #!/usr/bin/env python3 -import logging, re, datetime, json, inverterd +import logging, re, datetime, json +from inverterd import Format, Client as InverterClient, InverterError from typing import Optional from argparse import ArgumentParser from html import escape @@ -21,12 +22,41 @@ from telegram.ext import ( CallbackContext ) -inverter: Optional[inverterd.Client] = None + +class InverterClientWrapper: + def __init__(self, host: str, port: str): + self._host = host + self._port = port + self._inverter = None + + self.create() + + def create(self): + self._inverter = InverterClient(host=self._host, port=self._port) + self._inverter.connect() + + def exec(self, command: str, arguments: tuple, format=Format.JSON): + try: + self._inverter.format(format) + return self._inverter.exec(command, arguments) + except InverterError as e: + raise e + except Exception as e: + try: + self.create() + except Exception: + pass + raise e + + +inverter: Optional[InverterClientWrapper] = None + # # helpers # + def get_markup() -> ReplyKeyboardMarkup: button = [ [ @@ -59,31 +89,32 @@ def start(update: Update, context: CallbackContext) -> None: def msg_status(update: Update, context: CallbackContext) -> None: try: gs = json.loads(inverter.exec('get-status'))['data'] - pprint(gs) # render response power_direction = gs['battery_power_direction'].lower() - power_direction = re.sub(r'ges$', 'ging', power_direction) + power_direction = re.sub(r'ge$', 'ging', power_direction) charging_rate = '' if power_direction == 'charging': - charging_rate = ' @ %s %s' % tuple(gs['battery_charging_current']) + charging_rate = ' @ %s %s' % ( + gs['battery_charging_current']['value'], gs['battery_charging_current']['unit']) elif power_direction == 'discharging': - charging_rate = ' @ %s %s' % tuple(gs['battery_discharge_current']) + charging_rate = ' @ %s %s' % ( + gs['battery_discharging_current']['value'], gs['battery_discharging_current']['unit']) - html = '<b>Battery:</b> %s %s' % tuple(gs['battery_voltage']) - html += ' (%s%s, ' % tuple(gs['battery_capacity']) + html = '<b>Battery:</b> %s %s' % (gs['battery_voltage']['value'], gs['battery_voltage']['unit']) + html += ' (%s%s, ' % (gs['battery_capacity']['value'], gs['battery_capacity']['unit']) html += '%s%s)' % (power_direction, charging_rate) - html += '\n<b>Load:</b> %s %s' % tuple(gs['ac_output_active_power']) - html += ' (%s%%)' % (gs['output_load_percent'][0]) + html += '\n<b>Load:</b> %s %s' % (gs['ac_output_active_power']['value'], gs['ac_output_active_power']['unit']) + html += ' (%s%%)' % (gs['output_load_percent']['value']) - if gs['pv1_input_power'][0] > 0: - html += '\n<b>Input power:</b> %s%s' % tuple(gs['pv1_input_power']) + if gs['pv1_input_power']['value'] > 0: + html += '\n<b>Input power:</b> %s%s' % (gs['pv1_input_power']['value'], gs['pv1_input_power']['unit']) - if gs['grid_voltage'][0] > 0 or gs['grid_freq'][0] > 0: - html += '\n<b>Generator:</b> %s %s' % tuple(gs['grid_voltage']) - html += ', %s %s' % tuple(gs['grid_freq']) + if gs['grid_voltage']['value'] > 0 or gs['grid_freq']['value'] > 0: + html += '\n<b>Generator:</b> %s %s' % (gs['grid_voltage']['unit'], gs['grid_voltage']['value']) + html += ', %s %s' % (gs['grid_freq']['value'], gs['grid_freq']['unit']) # send response reply(update, html) @@ -98,24 +129,24 @@ def msg_generation(update: Update, context: CallbackContext) -> None: yday = today - datetime.timedelta(days=1) yday2 = today - datetime.timedelta(days=2) - gs = isv.general_status() + gs = json.loads(inverter.exec('get-status'))['data'] sleep(0.1) - gen_today = isv.day_generated(today.year, today.month, today.day) + gen_today = json.loads(inverter.exec('get-day-generated', (today.year, today.month, today.day)))['data'] gen_yday = None gen_yday2 = None if yday.month == today.month: sleep(0.1) - gen_yday = isv.day_generated(yday.year, yday.month, yday.day) + gen_yday = json.loads(inverter.exec('get-day-generated', (yday.year, yday.month, yday.day)))['data'] if yday2.month == today.month: sleep(0.1) - gen_yday2 = isv.day_generated(yday2.year, yday2.month, yday2.day) + gen_yday2 = json.loads(inverter.exec('get-day-generated', (yday2.year, yday2.month, yday2.day)))['data'] # render response - html = '<b>Input power:</b> %s %s' % tuple(gs['pv1_input_power']) - html += ' (%s %s)' % tuple(gs['pv1_input_voltage']) + html = '<b>Input power:</b> %s %s' % (gs['pv1_input_power']['value'], gs['pv1_input_power']['unit']) + html += ' (%s %s)' % (gs['pv1_input_voltage']['value'], gs['pv1_input_voltage']['unit']) html += '\n<b>Today:</b> %s Wh' % (gen_today['wh']) @@ -134,7 +165,7 @@ def msg_generation(update: Update, context: CallbackContext) -> None: def msg_gs(update: Update, context: CallbackContext) -> None: try: - status = isv.general_status(as_table=True) + status = inverter.exec('get-status', format=Format.TABLE) reply(update, status) except Exception as e: logging.exception(str(e)) @@ -143,7 +174,7 @@ def msg_gs(update: Update, context: CallbackContext) -> None: def msg_ri(update: Update, context: CallbackContext) -> None: try: - rated = isv.rated_information(as_table=True) + rated = inverter.exec('get-rated', format=Format.TABLE) reply(update, rated) except Exception as e: logging.exception(str(e)) @@ -152,8 +183,8 @@ def msg_ri(update: Update, context: CallbackContext) -> None: def msg_errors(update: Update, context: CallbackContext) -> None: try: - faults = isv.faults(as_table=True) - reply(update, faults) + errors = inverter.exec('get-errors', format=Format.TABLE) + reply(update, errors) except Exception as e: logging.exception(str(e)) reply(update, 'exception: ' + str(e)) @@ -177,7 +208,7 @@ if __name__ == '__main__': whitelist = list(map(lambda x: int(x), args.users_whitelist)) # connect to inverterd - inverter = inverterd.Client(host=args.inverterd_host, port=args.inverterd_port) + inverter = InverterClientWrapper(host=args.inverterd_host, port=args.inverterd_port) # configure logging logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', diff --git a/requirements.txt b/requirements.txt index 1fd4f8a..75495d1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ python-telegram-bot~=13.1 -inverterd
\ No newline at end of file +inverterd~=1.0.1
\ No newline at end of file @@ -0,0 +1,35 @@ +import json, re +from pprint import pprint + + +s = '{"result":"ok","data":{"grid_voltage":{"unit":"V","value":0.0},"grid_freq":{"unit":"Hz","value":0.0},"ac_output_voltage":{"unit":"V","value":230.0},"ac_output_freq":{"unit":"Hz","value":50.0},"ac_output_apparent_power":{"unit":"VA","value":115},"ac_output_active_power":{"unit":"Wh","value":18},"output_load_percent":{"unit":"%","value":2},"battery_voltage":{"unit":"V","value":50.0},"battery_voltage_scc":{"unit":"V","value":0.0},"battery_voltage_scc2":{"unit":"V","value":0.0},"battery_discharging_current":{"unit":"A","value":0},"battery_charging_current":{"unit":"A","value":0},"battery_capacity":{"unit":"%","value":78},"inverter_heat_sink_temp":{"unit":"°C","value":19},"mppt1_charger_temp":{"unit":"°C","value":0},"mppt2_charger_temp":{"unit":"°C","value":0},"pv1_input_power":{"unit":"Wh","value":1000},"pv2_input_power":{"unit":"Wh","value":0},"pv1_input_voltage":{"unit":"V","value":0.0},"pv2_input_voltage":{"unit":"V","value":0.0},"settings_values_changed":"Custom","mppt1_charger_status":"Abnormal","mppt2_charger_status":"Abnormal","load_connected":"Connected","battery_power_direction":"Discharge","dc_ac_power_direction":"DC/AC","line_power_direction":"Do nothing","local_parallel_id":0}}' + +if __name__ == '__main__': + gs = json.loads(s)['data'] + # pprint(gs) + + # render response + power_direction = gs['battery_power_direction'].lower() + power_direction = re.sub(r'ge$', 'ging', power_direction) + + charging_rate = '' + if power_direction == 'charging': + charging_rate = ' @ %s %s' % (gs['battery_charging_current']['value'], gs['battery_charging_current']['unit']) + elif power_direction == 'discharging': + charging_rate = ' @ %s %s' % (gs['battery_discharging_current']['value'], gs['battery_discharging_current']['unit']) + + html = '<b>Battery:</b> %s %s' % (gs['battery_voltage']['value'], gs['battery_voltage']['unit']) + html += ' (%s%s, ' % (gs['battery_capacity']['value'], gs['battery_capacity']['unit']) + html += '%s%s)' % (power_direction, charging_rate) + + html += '\n<b>Load:</b> %s %s' % (gs['ac_output_active_power']['value'], gs['ac_output_active_power']['unit']) + html += ' (%s%%)' % (gs['output_load_percent']['value']) + + if gs['pv1_input_power']['value'] > 0: + html += '\n<b>Input power:</b> %s%s' % (gs['pv1_input_power']['value'], gs['pv1_input_power']['unit']) + + if gs['grid_voltage']['value'] > 0 or gs['grid_freq']['value'] > 0: + html += '\n<b>Generator:</b> %s %s' % (gs['grid_voltage']['unit'], gs['grid_voltage']['value']) + html += ', %s %s' % (gs['grid_freq']['value'], gs['grid_freq']['unit']) + + print(html)
\ No newline at end of file |