113 lines
4.1 KiB
Python
113 lines
4.1 KiB
Python
# Enter your python code.
|
|
import json, time
|
|
from datetime import datetime as dt
|
|
from common.Logger import logger
|
|
from quickfaas.remotebus import publish
|
|
from quickfaas.global_dict import get as get_params
|
|
|
|
def convertDStoJSON(ds):
|
|
j = dict()
|
|
for x in ds:
|
|
j[x["key"]] = x["value"]
|
|
return j
|
|
|
|
def chunk_payload(payload, chunk_size=20, is_attributes_payload=False):
|
|
if is_attributes_payload:
|
|
# For attributes payload, chunk the controllers
|
|
controllers = list(payload.items())
|
|
for i in range(0, len(controllers), chunk_size):
|
|
yield dict(controllers[i:i + chunk_size])
|
|
else:
|
|
# For data payload, chunk the values within each controller
|
|
for controller, data in payload.items():
|
|
for entry in data:
|
|
ts = entry['ts']
|
|
values = entry['values']
|
|
chunked_values = list(values.items())
|
|
for i in range(0, len(chunked_values), chunk_size):
|
|
yield {
|
|
controller: [{
|
|
"ts": ts,
|
|
"values": dict(chunked_values[i:i + chunk_size])
|
|
}]
|
|
}
|
|
|
|
def controlName(name):
|
|
try:
|
|
params = convertDStoJSON(get_params())
|
|
nameMap = json.loads(params.get("name_map"))
|
|
return nameMap.get(name, name)
|
|
except Exception as e:
|
|
logger.error(e)
|
|
return name
|
|
|
|
def sendData(message):
|
|
#logger.debug(message)
|
|
# Extract measures and group by ctrlName
|
|
grouped_data = {}
|
|
grouped_attributes = {}
|
|
valves = {}
|
|
now = (round(dt.timestamp(dt.now())/600)*600)*1000
|
|
for measure in message['measures']:
|
|
ctrlName = controlName(measure['ctrlName'])
|
|
name = measure['name']
|
|
value = measure['value']
|
|
health = measure['health']
|
|
#Add controller for telemetry if it doesn't exist
|
|
if ctrlName not in grouped_data:
|
|
grouped_data[ctrlName] = {}
|
|
#Add controller for attributes if it doesn't exist
|
|
if ctrlName not in grouped_attributes:
|
|
grouped_attributes[ctrlName] = {}
|
|
grouped_attributes[ctrlName]["latestReportTime"] = now
|
|
#Add data to temp payload if datapoint health is good
|
|
if health:
|
|
if any(x in name for x in ["open", "closed"]):
|
|
valve = "_".join(name.split("_")[:-1])
|
|
if valve not in valves:
|
|
valves[valve] = [None,None]
|
|
|
|
if "open" in name:
|
|
valves[valve][1] = value
|
|
elif "closed" in name:
|
|
valves[valve][0] = value
|
|
else:
|
|
print("error")
|
|
grouped_data[ctrlName][name] = value
|
|
|
|
if valves:
|
|
for key, value in valves.items():
|
|
# 0 = In Progress | 1 = Open | 2 = Closed | 3 = Error
|
|
if value[0] == 0 and value[1] == 0: # Not closed and not open thus in progress
|
|
output = 0
|
|
elif value[0] == 0 and value[1] == 1: # Not closed but open thus open
|
|
output = 1
|
|
elif value[0] == 1 and value[1] == 0: # Closed but not open thus closed
|
|
output = 2
|
|
elif value[0] == 1 and value[1] == 1: # Closed and open thus errored not possible
|
|
output = 3
|
|
else:
|
|
output = 4 # Something didn't report
|
|
grouped_data[ctrlName][key + "_status"] = output
|
|
# Transform the grouped data to desired structure
|
|
payload = {}
|
|
|
|
for key, value in grouped_data.items():
|
|
if value:
|
|
payload[key] = [{"ts": now ,"values": value}]
|
|
attributes_payload = {}
|
|
for key, value in grouped_attributes.items():
|
|
if value:
|
|
attributes_payload[key] = value
|
|
|
|
|
|
|
|
#logger.debug(payload)
|
|
for chunk in chunk_payload(payload=payload):
|
|
publish(__topic__, json.dumps(chunk), __qos__)
|
|
time.sleep(2)
|
|
|
|
for chunk in chunk_payload(payload=attributes_payload, is_attributes_payload=True):
|
|
publish("v1/gateway/attributes", json.dumps(attributes_payload), __qos__)
|
|
time.sleep(2)
|
|
|