Skip to content

Commit 83a2529

Browse files
POLL_INTERVAL work for v2.0.0.
Try to position each loop exactly `POLL_INTERVAL` seconds apart. This is most useful when it's an even division of a minute. If it is a multiple of a minute, start the first loop iteration at the beginning of the next minute.
1 parent c705dad commit 83a2529

1 file changed

Lines changed: 35 additions & 13 deletions

File tree

pwmon.py

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from tesla_powerwall.responses import Meter, Battery
2121

2222

23-
##### environment variables
23+
# environment variables
2424
# load environment variables from a file if they're there
2525
load_dotenv('env.list', override=False)
2626

@@ -47,10 +47,10 @@
4747
POLL_INTERVAL = int(os.environ.get('POLL_INTERVAL', 60))
4848

4949
# powerwall hostname or IP.
50-
# The powerwall's self-signed certificate only responds to
50+
# The powerwall's self-signed certificate only responds to
5151
# hostnamnes "powerwall", "teg", or "powerpack", and of course you have to have DNS set up properly.
5252
# IP addresses work, too.
53-
PW_ADDR = os.environ.get("PW_ADDR", 'powerwall')
53+
PW_ADDR = os.environ.get("PW_ADDR", 'powerwall')
5454

5555
# Optional Metrics
5656
# Reserve Percent (enabled by default)
@@ -64,9 +64,9 @@
6464
OPT_BATTERY_CAPACITY_WH = os.environ.get('OPT_BATTERY_CAPACITY_WH', False)
6565
OPT_GRID_STATUS_GAUGE = os.environ.get('OPT_GRID_STATUS_GAUGE', False)
6666

67-
##### end environment variables
67+
# end environment variables
6868

69-
##### constants
69+
# constants
7070
# URL to post to
7171
URL = 'https://metric-api.newrelic.com/metric/v1'
7272

@@ -75,9 +75,11 @@
7575
'Content-Type': 'application/json',
7676
'Api-Key': INSIGHTS_API_KEY,
7777
}
78-
##### end constants
78+
# end constants
79+
80+
# Grid Status Enum for OPT_GRID_STATUS_GAUGE
81+
7982

80-
##### Grid Status Enum for OPT_GRID_STATUS_GAUGE
8183
class GridStatus(enum.IntEnum):
8284
UNKNOWN = 0
8385
CONNECTED = 1
@@ -88,7 +90,8 @@ class GridStatus(enum.IntEnum):
8890

8991
def _missing(self, value):
9092
return self.UNKNOWN
91-
##### end Grid Status Enum
93+
# end Grid Status Enum
94+
9295

9396
def get_now():
9497
"""Return the current Unix timestamp in msec."""
@@ -111,6 +114,7 @@ def post_metrics(data):
111114
# because the gateway is very slow to respond
112115
# and it has some absurdly low rate limit
113116

117+
114118
@tenacity.retry(stop=tenacity.stop_after_attempt(7),
115119
wait=tenacity.wait_random(min=3, max=7))
116120
def get_pw():
@@ -230,7 +234,7 @@ def get_data():
230234

231235
if OPT_RESERVE_PCT:
232236
reserve = make_gauge('solar.reserve_pct',
233-
pw.get_backup_reserve_percentage())
237+
pw.get_backup_reserve_percentage())
234238
data['metrics'].append(reserve)
235239

236240
if OPT_RESERVE_PCT_AVAIL:
@@ -243,7 +247,7 @@ def get_data():
243247
batteries: list[Battery] = []
244248
if OPT_BATTERY_CHARGE_WH or OPT_BATTERY_CAPACITY_WH:
245249
batteries = pw.get_batteries()
246-
250+
247251
if OPT_BATTERY_CHARGE_WH:
248252
tmp = 0
249253
for battery in batteries:
@@ -261,11 +265,13 @@ def get_data():
261265
data['metrics'].append(capacity)
262266

263267
if OPT_GRID_STATUS_GAUGE:
264-
grid_status = make_gauge('solar.grid_status', GridStatus[pw.get_grid_status().name].value)
268+
grid_status = make_gauge(
269+
'solar.grid_status', GridStatus[pw.get_grid_status().name].value)
265270
data['metrics'].append(grid_status)
266271

267272
return data
268273

274+
269275
def make_meter_gauges(name: str, meter: Meter, invertDirection: bool = False, type: str = 'gauge') -> list[dict]:
270276
"""Return a list of gauges for a supplied Meter"""
271277
gauges = [
@@ -297,11 +303,27 @@ def run_from_cli():
297303

298304

299305
if __name__ == "__main__":
306+
# If POLL_INTERVAL is a multiple of a minute, try to start at the beginning of the next minute
307+
if POLL_INTERVAL % 60 == 0 and AS_SERVICE:
308+
wait_time = 60 - time.localtime().tm_sec
309+
print('Found minute intervals, delaying first iteration',
310+
wait_time, 'seconds until the start of the next minute')
311+
print()
312+
time.sleep(wait_time)
313+
300314
while True:
315+
start = time.time()
301316
data = get_data()
302317
ret = post_metrics(data)
303318

304-
print('submitted at', dt.now(), "return code", ret)
319+
print('Submitted at', dt.now())
320+
305321
if not AS_SERVICE:
306322
run_from_cli()
307-
time.sleep(POLL_INTERVAL)
323+
324+
# Try to position each loop exactly POLL_INTERVAL seconds apart.
325+
# This is most useful when POLL_INTERVAL is an even division of a minute
326+
elapsed = time.time() - start
327+
if elapsed < 0 or elapsed > POLL_INTERVAL:
328+
elapsed = 0
329+
time.sleep(POLL_INTERVAL - elapsed)

0 commit comments

Comments
 (0)