2
0
mirror of https://github.com/xcat2/confluent.git synced 2024-11-28 20:39:40 +00:00

Add limited sensor support for Eaton PDUs

This commit is contained in:
Jarrod Johnson 2023-08-22 12:28:07 -04:00
parent f3e7d4ab67
commit b14b34bdbd

View File

@ -25,6 +25,10 @@ import hashlib
import json
import time
def simplify_name(name):
return name.lower().replace(' ', '_').replace('/', '-').replace(
'_-_', '-')
#eaton uses 'eval' rather than json, massage it to be valid json
def sanitize_json(data):
if not isinstance(data, str):
@ -131,6 +135,43 @@ class WebConnection(wc.SecureHTTPConnection):
body = rsp.read()
return body, rsp.status
_sensors_by_node = {}
def get_sensor_data(element, node, configmanager):
category, name = element[-2:]
justnames = False
readings = []
if len(element) == 3:
# just get names
category = name
name = 'all'
justnames = True
if category in ('leds, fans', 'temperature'):
return
sn = _sensors_by_node.get(node, None)
if not sn or sn[1] < time.time():
gc = PDUClient(node, configmanager)
try:
sdata = gc.get_sensor_data()
finally:
gc.logout()
_sensors_by_node[node] = [sdata, time.time() + 1]
sn = _sensors_by_node.get(node, None)
for outlet in sn[0]:
for sensename in sn[0][outlet]:
myname = 'Outlet {0} {1}'.format(outlet, sensename)
measurement = sn[0][outlet][sensename]
if name == 'all' or simplify_name(myname) == name:
readings.append({
'name': myname,
'value': float(measurement['value']),
'units': measurement['units'],
'type': measurement['type'],
})
if justnames:
for reading in readings:
yield msg.ChildCollection(simplify_name(reading['name']))
else:
yield msg.SensorReadings(readings, name=node)
class PDUClient(object):
@ -231,6 +272,28 @@ class PDUClient(object):
if outdata[0] == outlet:
return 'on' if outdata[3] else 'off'
return
def get_sensor_data(self):
rsp = self.do_request('cgi_pdu_outlets')
data = sanitize_json(rsp[0])
data = json.loads(data)
data = data['data'][0]
sdata = {}
for outdata in data:
outsense = {}
outletname = outdata[0][0]
outsense['Energy'] = {
'value': float(outdata[11] / 1000),
'units': 'kwh',
'type': 'Energy'
}
outsense['Power'] = {
'value': float(outdata[4]),
'units': 'w',
'type': 'Power',
}
sdata[outletname] = outsense
return sdata
def set_outlet(self, outlet, state):
rsp = self.do_request('cgi_pdu_outlets')
@ -247,7 +310,12 @@ class PDUClient(object):
idx += 1
def retrieve(nodes, element, configmanager, inputdata):
if 'outlets' not in element:
if element[0] == 'sensors':
for node in nodes:
for res in get_sensor_data(element, node, configmanager):
yield res
return
elif 'outlets' not in element:
for node in nodes:
yield msg.ConfluentResourceUnavailable(node, 'Not implemented')
return