]> git.sven.stormbind.net Git - sven/scripts.git/blob - home/portalmonitor.py
fdae4ba21e67bd9c84458cf3a570cb7e00877d86
[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=(10, 30))
49
50             r = s.post(
51                 'https://www.envertecportal.com/ApiStations/getStationInfo',
52                 data={
53                     'stationId': stationId
54                 },
55                 timeout=(10, 60)).json()
56             power = r['Data']['Power']
57
58             r = s.post('https://www.envertecportal.com/apiAccount/Logout',
59                        timeout=(10, 30))
60         except requests.exceptions.RequestException as e:
61             raise SystemExit(e)
62
63     return float(power)
64
65
66 # use our stateFile to determine if we have a state change
67 # used to decide if we print something - thus generate a mail - later on
68 def stateCheck(newState, stateFile):
69     try:
70         with open(stateFile, "r") as f:
71             oldState = f.read()
72     except FileNotFoundError:
73         oldState = "NULL"
74
75     if newState == oldState:
76         change = False
77     else:
78         change = True
79         with open(stateFile, "w") as f:
80             f.write(newState)
81
82     return change
83
84
85 # read configuration file
86 conf = configparser.ConfigParser()
87 conf.read('portalmonitor.ini')
88
89 # retrieve current power value as reported by envertecportal
90 if isDaylight(conf['config'].getfloat('lat'), conf['config'].getfloat('lon'),
91               conf['config'].getint('toleranceSeconds')) or args.force:
92     currentPower = getCurrentPower(conf['config']['userName'],
93                                    conf['config']['password'],
94                                    conf['config']['stationId'])
95
96     if args.printStatus:
97         print(f"Current Power: {currentPower}")
98
99     if currentPower == 0:
100         if stateCheck('FAILED', conf['config']['stateFile']):
101             print('Error: Power dropped to 0 but we should have daylight!')
102         sys.exit(1)
103     else:
104         if stateCheck('OK', conf['config']['stateFile']):
105             print(f"Resolved: Inverter reports {currentPower}W")