add meter object

master
vuko 2018-10-12 17:32:59 +02:00
parent 08857b6bc6
commit ee4e67667c
1 changed files with 21 additions and 27 deletions

View File

@ -6,23 +6,20 @@ import copy
con = mqtt.Client() con = mqtt.Client()
con.connect('10.8.1.16') con.connect('10.8.1.16')
lock = threading.Lock()
measurements = {}
con.subscribe('iot/+/+/energy') con.subscribe('iot/+/+/energy')
class Measurements: class Meters:
class Meter: class Meter:
def __init__(self, _id): def __init__(self, _id, history_size = 10):
self.id = _id self.id = _id
self.energy = [] self.energy = []
self.history_size = 10
def add_energy_measurement(energy): def add_energy_measurement(self, energy):
self.energy.append((datetime.datetime.now(), energy)) self.energy.append((datetime.datetime.now(), energy))
self.energy = self.energy[-10:] self.energy = self.energy[-self.history_size:]
def get_metrics(): def get_metrics(self):
if len(self.energy) > 0: if len(self.energy) > 0:
last = self.energy[-1] last = self.energy[-1]
s = ('energy{{node="esp8266-{mid:s}"}} {energy:f} ' s = ('energy{{node="esp8266-{mid:s}"}} {energy:f} '
@ -32,18 +29,27 @@ class Measurements:
else: else:
return '' return ''
def __init__(self): def __init__(self):
self._meters = [] self._meters = {}
self._lock = threading.Lock() self._lock = threading.Lock()
def _get_meter_by_id(self, _id): def _get_meter_by_id(self, _id):
if _id not in self._meters: if _id not in self._meters:
self._meters[_id] = Meter(_id) self._meters[_id] = self.Meter(_id)
return self._meters[_id] return self._meters[_id]
def add_energy_measurement(meter_id, energy): def add_energy_measurement(self, meter_id, energy):
with self._lock: with self._lock:
meter = self._get_meter_by_id(meter_id) meter = self._get_meter_by_id(meter_id)
meter.energy.append((datetime.datetime.now(), energy)) meter.add_energy_measurement(energy)
def get_metrics(self):
with self._lock:
s = ''
for meter in self._meters.values():
s += meter.get_metrics()
return s
meters = Meters()
def on_message(client, userdata, message): def on_message(client, userdata, message):
m = re.match('iot/(?P<id>[^/]+)/[^/]+/energy', message.topic) m = re.match('iot/(?P<id>[^/]+)/[^/]+/energy', message.topic)
@ -55,12 +61,7 @@ def on_message(client, userdata, message):
else: else:
if message.retain == 0: if message.retain == 0:
mid = m.group('id') mid = m.group('id')
with lock: meters.add_energy_measurement(mid, energy)
if mid not in measurements:
measurements[mid] = []
ms = measurements[mid]
ms.append((datetime.datetime.now(), energy))
measurements[mid] = ms[-10:]
con.on_message = on_message con.on_message = on_message
con.loop_start() con.loop_start()
@ -73,14 +74,7 @@ def metrics():
r = "" r = ""
r += "# HELP energy energy in joules\n" r += "# HELP energy energy in joules\n"
r += "# TYPE energy counter\n" r += "# TYPE energy counter\n"
with lock: r += meters.get_metrics()
m = copy.deepcopy(measurements)
for mid in m:
ms = [m[mid][-1]]
for s in ms:
r += 'energy{{node="esp8266-{mid:s}"}} {energy:f} {epoch:d}\n'.format(mid=mid, energy=s[1], epoch=int(s[0].timestamp() * 1000) )
return flask.Response(r, mimetype='text/plain; version=0.0.4') return flask.Response(r, mimetype='text/plain; version=0.0.4')
app.run('0.0.0.0') app.run('0.0.0.0')