Newer
Older
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
import asyncio
import time
def init(monitor):
return PluginCollectd(monitor)
class PluginCollectd:
"""
Implements a super simple collectd interface for only sending temperature data
"""
def __init__(self, monitor):
self.loop = asyncio.get_event_loop()
self.config = monitor.config
self.path = self.config['collectd']['socketpath']
self._reader, self._writer = (None, None)
self.loop.run_until_complete(self.reconnect())
self.monitor = monitor
self.last_store = 0
async def reconnect(self):
"""
optionally close and then reconnect to the unix socket
"""
if self._writer:
self._writer.close()
self._reader, self._writer = await asyncio.open_unix_connection(
path=self.path,
loop=self.loop)
async def _send(self, identifier, interval, timestamp, value):
"""
The collectd naming convention is:
host "/" plugin ["-" plugin instance] "/" type ["-" type instance]
Whereby:
- host: local host name
- plugin: the tab in CGP
- plugin-instance: the graph
- type the line in the graph
- type instance : if there are more than one "temperature"s
"""
data = "PUTVAL \"{}/{}\" interval={} {}:{}\n".format(
self.config['collectd']['hostname'],
identifier,
interval,
timestamp,
value)
#print("Sending data:", data.strip())
self._writer.write(data.encode('utf-8'))
await self._writer.drain()
try:
line = await asyncio.wait_for(self._reader.readline(), 1)
except asyncio.TimeoutError:
print("Collectd did not respond.")
return
line = line.decode('utf-8').strip()
if not line:
print("Connection reset. reconnecting")
await self.reconnect()
else:
pass
#print("recv:", line)
async def send_sensor_values(self, sensor):
"""
Store the temperature to collectd for fancy graphs
"""
await self._send("tail-temperature/temperature-{}".format(sensor.name),
int(self.config['collectd']['interval']),
int(sensor.last_update),
sensor.temperature)
## Plugin Callbacks ##
async def send_stats_graph(self, graph, stattype, stattime, statval):
"""
to be called as a plugin callback to store stuff into collectd
"""
await self._send("tail-{}/{}".format(graph, stattype),
int(self.config['collectd']['interval']),
stattime,
statval)
async def sensor_update(self):
"""
Receive sensor data to store them regularely into collectd
"""
for sensor in self.monitor.sensors.values():
if sensor.valid:
await self.send_sensor_values(sensor)
self.last_store = time.time()