]> git.sven.stormbind.net Git - sven/scripts.git/blob - home/portalmonitor.py
c8b732b46afb64181df4c0cc7cefed2e16747209
[sven/scripts.git] / home / portalmonitor.py
1 #!/usr/bin/env python3
2
3 import argparse
4 import requests
5 import time
6 import sys
7 import configparser
8 from suntime import Sun
9
10 parser = argparse.ArgumentParser()
11 parser.add_argument("-s",
12                   "--status",
13                   action="store_true",
14                   dest="printStatus",
15                   help="Print Status Information",
16                   default=False)
17 parser.add_argument("-f",
18                   "--force",
19                   action="store_true",
20                   dest="force",
21                   help="Force retrieval of Power value",
22                   default=False)
23 args = parser.parse_args()
24
25
26 def isDaylight(lat, lon, toleranceSeconds):
27     daylight = False
28     sun = Sun(lat, lon)
29     sunriseTimestamp = int(sun.get_local_sunrise_time().timestamp())
30     sunsetTimestamp = int(sun.get_local_sunset_time().timestamp())
31     nowTimestamp = int(time.time())
32
33     if ((sunriseTimestamp + toleranceSeconds) < nowTimestamp) and (
34         (sunsetTimestamp - toleranceSeconds) > nowTimestamp):
35         daylight = True
36
37     return daylight
38
39
40 def getCurrentPower(userName, password, stationId):
41     with requests.Session() as s:
42         try:
43             r = s.post('https://www.envertecportal.com/apiaccount/login',
44                        data={
45                            'userName': userName,
46                            'pwd': password
47                        },
48                        timeout=(20, 40))
49
50             r = s.post(
51                 'https://www.envertecportal.com/ApiStations/getStationInfo',
52                 data={
53                     'stationId': stationId
54                 },
55                 timeout=(20, 60)).json()
56             power = r['Data']['Power']
57
58             r = s.post('https://www.envertecportal.com/apiAccount/Logout',
59                        timeout=(20, 40))
60
61         # connect timeouts occur so frequently since the portal relaunch,
62         # ignore them for the time beeing completely
63         except requests.exceptions.ConnectTimeout as eTimeout:
64             sys.exit(1)
65         except requests.exceptions.RequestException as e:
66             print(e)
67             raise SystemExit(e)
68
69     return float(power)
70
71
72 # use our stateFile to determine if we have a state change
73 # used to decide if we print something - thus generate a mail - later on
74 def stateCheck(newState, stateFile):
75     try:
76         with open(stateFile, "r") as f:
77             oldState = f.read()
78     except FileNotFoundError:
79         oldState = "NULL"
80
81     if newState == oldState:
82         change = False
83     else:
84         change = True
85         with open(stateFile, "w") as f:
86             f.write(newState)
87
88     return change
89
90
91 # read configuration file
92 conf = configparser.ConfigParser()
93 conf.read('portalmonitor.ini')
94
95 # retrieve current power value as reported by envertecportal
96 if isDaylight(conf['config'].getfloat('lat'), conf['config'].getfloat('lon'),
97               conf['config'].getint('toleranceSeconds')) or args.force:
98     currentPower = getCurrentPower(conf['config']['userName'],
99                                    conf['config']['password'],
100                                    conf['config']['stationId'])
101
102     if args.printStatus:
103         print(f"Current Power: {currentPower}")
104
105     if currentPower == 0:
106         if stateCheck('FAILED', conf['config']['stateFile']):
107             print('Error: Power dropped to 0 but we should have daylight!')
108         sys.exit(1)
109     else:
110         if stateCheck('OK', conf['config']['stateFile']):
111             print(f"Resolved: Inverter reports {currentPower}W")