-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsubmitter.py
95 lines (79 loc) · 2.39 KB
/
submitter.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
import atexit
import argparse
import datetime
import logging
import os
import os.path
import sys
import time
import attr
import environ
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS
import yaml
import objects
import client
def now():
zone = datetime.datetime.now(datetime.timezone.utc).astimezone()
return datetime.datetime.now().replace(tzinfo=zone.tzinfo)
def convLoglevel(s):
levels = ['CRITICAL', 'FATAL', 'ERROR', 'WARNING', 'WARN', 'INFO', 'DEBUG']
if not s in levels:
raise ValueError(f'{s} is not a valid log level. Valid are {"".join(choices)}')
return s
@environ.config(prefix="SMAPY")
class Config:
url = environ.var()
group = environ.var('usr')
password = environ.var('sun1sgr3at')
interval = environ.var(30, converter=int)
loglevel = environ.var("INFO", converter=convLoglevel)
influxdb_bucket = environ.var('solar', name='INFLUXDB_V2_BUCKET')
@attr.s
class Submitter(object):
config = attr.ib()
log = attr.ib(converter=lambda l: l.getChild('submitter'))
sma = attr.ib()
def __attrs_post_init__(self):
self.log = logging.getLogger('smapy.submitter')
self.influx_client = InfluxDBClient.from_env_properties()
self.influx_write_api = self.influx_client.write_api(write_options=SYNCHRONOUS)
self.sma.login()
def work(self):
self.log.info('Polling and submitting')
t = now()
data = self.sma.read()
p = Point('sma').time(t)
for field, value, unit in objects.fields(data):
if value is not None:
p.field(field, value)
self.log.debug(f'Result: {p.to_line_protocol()}')
self.influx_write_api.write(
bucket = self.config.influxdb_bucket,
record = p,
)
def loop(self):
self.log.info('Looping indefinately')
while True:
t0 = time.time()
s.work()
nap = t0 + self.config.interval - time.time()
self.log.debug(f'Sleeping {nap:.1f} seconds')
time.sleep(nap)
def cleanup(self):
self.log.debug('Clean up in aisle 5')
self.sma.logout()
if __name__ == '__main__':
config = Config.from_environ()
ch = logging.StreamHandler(sys.stderr)
ch.setFormatter(logging.Formatter("%(asctime)s %(levelname)8s:%(name)s: %(message)s"))
log = logging.getLogger('smapy')
log.addHandler(ch)
log.setLevel(config.loglevel)
sma = client.SMAClient(config, log)
s = Submitter(config, log, sma)
# register exit hook. Needed to not overflow sessions
@atexit.register
def cleanup():
s.cleanup()
s.loop()