aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Zinoviev <me@ch1p.io>2021-05-16 01:53:04 +0300
committerEvgeny Zinoviev <me@ch1p.io>2021-05-16 01:53:04 +0300
commit21af6e1defe36d0c445b5b924a5c34d584bff02a (patch)
treee648027570147d37d5f9975d10e133ac72c50e95
parent1024cc0b8c65598d5f396179035b1a9352ee467c (diff)
save
-rwxr-xr-xinverter-bot83
-rw-r--r--requirements.txt2
-rw-r--r--test.py35
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
diff --git a/test.py b/test.py
new file mode 100644
index 0000000..79ac277
--- /dev/null
+++ b/test.py
@@ -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