forked from sillygoose/multisma2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmultisma2.py
104 lines (81 loc) · 3.12 KB
/
multisma2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
"""Code to interface with the SMA inverters and return the results."""
# Robust initialization and shutdown code courtesy of
# https://github.com/wbenny/python-graceful-shutdown.git
import logging
import sys
import os
import signal
from typing import Dict, Any, NoReturn
import asyncio
import aiohttp
from delayedints import DelayedKeyboardInterrupt
from pvsite import PVSite
import version
import logfiles
from exceptions import TerminateSignal, NormalCompletion, AbnormalCompletion, FailedInitialization
from configuration import APPLICATION_LOG_LOGGER_NAME
logger = logging.getLogger(APPLICATION_LOG_LOGGER_NAME)
class Multisma2():
def __init__(self):
"""Initialize the Multisma2 instance."""
self._loop = asyncio.new_event_loop()
self._session = None
self._site = None
signal.signal(signal.SIGTERM, self.catch)
signal.siginterrupt(signal.SIGTERM, False)
def catch(self, signum, frame):
"""Handler for SIGTERM signals."""
logger.info("Received SIGTERM signal, forcing shutdown")
raise TerminateSignal
def run(self):
"""Code to handle the start(), run(), and stop() interfaces."""
try:
try:
with DelayedKeyboardInterrupt():
self._start()
except KeyboardInterrupt:
logger.info("Received KeyboardInterrupt during startup")
raise
self._run()
raise NormalCompletion
except (KeyboardInterrupt, NormalCompletion, AbnormalCompletion, FailedInitialization, TerminateSignal):
try:
with DelayedKeyboardInterrupt():
self._stop()
except KeyboardInterrupt:
logger.info("Received KeyboardInterrupt during shutdown")
async def _astart(self):
"""Asynchronous initialization code."""
logfiles.start(logger)
logger.info(f"multisma2 inverter collection utility {version.get_version()}, PID is {os.getpid()}")
self._session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False))
self._site = PVSite(self._session)
result = await self._site.start()
if not result: raise FailedInitialization
async def _arun(self):
"""Asynchronous run code."""
await self._site.run()
async def _astop(self):
"""Asynchronous closing code."""
logger.info("Closing multisma2 application")
await self._site.stop()
await self._session.close()
def _start(self):
"""Initialize everything prior to running."""
self._loop.run_until_complete(self._astart())
def _run(self):
"""Run the application."""
self._loop.run_until_complete(self._arun())
def _stop(self):
"""Cleanup after running."""
self._loop.run_until_complete(self._astop())
def main():
"""Set up and start multisma2."""
multisma2 = Multisma2()
multisma2.run()
if __name__ == "__main__":
# make sure we can run multisma2
if sys.version_info[0] >= 3 and sys.version_info[1] >= 7:
main()
else:
print("python 3.7 or better required")