BNA8/.resources/0c2a29d0397e66b993c721f0c222fd021b07a36849070c8950a9bcf0de3510fe

156 lines
6.1 KiB
Plaintext

################################################################
################################################################
## Version: 1.0 / Author: Dillon Uzar
##
## DESC: For use in FMS in recording Flow Management data
## WARN: Modifying code may cause system to function incorrectly
################################################################
################################################################
import json
import system
import time
#######################################################
#######################################################
#######################################################
#### Constants
#######################################################
# Logger:
LOG = system.util.logger("FMS Handler")
# For inserting data into database:
INSERT_QUERY = "INSERT INTO fms_history (conveyor, segment, data) VALUES (?,?,?)"
#######################################################
#######################################################
#######################################################
#### Parsing Utils
#######################################################
def extractNibble(val, nibble):
if val is not None:
return (val >> (nibble*4)) & 0x0F
def logTime(title, conv, seg, data, start_time):
millisec = round((time.time() - start_time) * 1000, 1)
LOG.info("%s[CONV=%s][SEG=%s][DATA=%s] took %sms to process" % (title, conv, seg, data, millisec))
#######################################################
#######################################################
#######################################################
#### Tag Event Handling
#######################################################
def logSegment(conveyor, segment, data):
# Log event in SQL:
# Insert into FMS History:
start_time = time.time()
INSERT_QUERY = "INSERT INTO fms_history (conveyor, segment, data) VALUES (?,?,?)"
system.db.runPrepUpdate(INSERT_QUERY, [conveyor, segment, data])
#logTime("FMS[DB_INSERT]", conveyor, segment, data, start_time)
def dintOnChange(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
# Don't execute on startup, or if new value is bad quality:
if currentValue.quality.isGood():
# Only consider it a change if the value is different:
if currentValue.value <> previousValue.value:
id = int(tagPath.split("/")[-1].replace("DINT", ""))
conveyor = tag['parameters']['LabelFull']
# ID=0 is unique where the first nibble is the average of all segments, the 7 other segments are normal segments:
if id == 0:
# Ignore first nibble, which is the average of all segments:
for i in range(1, 8):
# Check if segment changed:
curVal = extractNibble(currentValue.value, i)
prevVal = extractNibble(previousValue.value, i)
if curVal <> prevVal:
segment = i - 1
logSegment(conveyor, segment, curVal)
else:
for i in range(0, 8):
# Check if segment changed:
curVal = extractNibble(currentValue.value, i)
prevVal = extractNibble(previousValue.value, i)
if curVal <> prevVal:
segment = i + (id-1)*8 + 7
logSegment(conveyor, segment, curVal)
#######################################################
#######################################################
#######################################################
#### Graphics Tag Scripts
#######################################################
"""
radial-gradient(circle at 30%,
#f5bff5 calc((var(--conv-width) - 4px)/2*0.25),
#000 calc((var(--conv-width) - 4px)/2*0.25),
#000 calc((var(--conv-width) - 4px)/2*0.25 + 1px),
transparent calc((var(--conv-width) - 4px)/2*0.25 + 1px)),
radial-gradient(circle at 50%, #d900d9 calc((var(--conv-width) - 4px)/2*1), #000 calc((var(--conv-width) - 4px)/2*1), #000 calc((var(--conv-width) - 4px)/2*1 + 1px), transparent calc((var(--conv-width) - 4px)/2*0.25 + 1px)), radial-gradient(circle at 70%, #ec7fec 7px, #000 7px, #000 8px, transparent 8px), radial-gradient(circle at 90%, #e23fe2 10px, #000 10px, #000 11px, transparent 11px), #00D900
"""
def genSegmentsTable(obj):
segments = []
if obj is not None and obj["Count"] is not None:
for i in range(1, obj["Count"]+1):
dint = "DINT"+str(int(i/8))
if obj[dint] is not None:
percent = extractNibble(obj[dint], i % 8) / 15.0
segments.append([i, percent])
return system.dataset.toDataSet(["segment", "fill"], segments)
def genSegmentColor(data):
perc = (data/15.0)
c1 = 255 - (255 - 217)*perc
c2 = 255 - (255 - 0)*perc
return "rgb(%s, %s, %s)" % (c1, c2, c1)
def genSegmentsPattern(obj):
if obj["Count"] is not None and obj["Count"] > 0:
percUnit = 100 / float(obj["Count"])
gradients = []
for i in range(1, obj["Count"]+1):
dint = "DINT"+str(int(i/8))
if obj[dint] is not None:
data = extractNibble(obj[dint], i % 8)
color = genSegmentColor(data)
circlePos = ((obj["Count"]-i))*percUnit + percUnit/2.0
perc = (data/15.0*0.5+0.5) if data > 0 else 0.0 # Make circle size between 50%-100%
if perc > 0.0:
output = "radial-gradient(circle at %s%%" % (circlePos)
output += ", %s calc((var(--conv-width) - 8px)/2*%s)" % (color, perc)
output += ", #000 calc((var(--conv-width) - 8px)/2*%s)" % (perc)
output += ", #000 calc((var(--conv-width) - 8px)/2*%s + 1px)" % (perc)
output += ", transparent calc((var(--conv-width) - 8px)/2*%s + 1px)" % (perc)
output += ")"
gradients.append(output)
if len(gradients) > 0:
return ", ".join(gradients)+","
return ""
def genSegmentsTooltip(obj):
if obj["Count"] is not None and obj["Count"] > 0:
data = extractNibble(obj["DINT0"], 0)
output = "<br><br>SegmentAVG: %s%%" % (int(round(100 * data / 15.0)))
for i in range(1, obj["Count"]+1):
dint = "DINT"+str(int(i/8))
if obj[dint] is not None:
data = extractNibble(obj[dint], i % 8)
output += "<br>Segment%s: %s%%" % (i, int(round(100 * data / 15.0)))
return output
return ""
def genSegmentHeatmap(obj):
segments = []
if obj["Count"] is not None and obj["Count"] > 0:
for i in range(1, obj["Count"]+1):
dint = "DINT"+str(int(i/8))
if obj[dint] is not None:
data = extractNibble(obj[dint], i % 8)
color = 255 * data / 15
segments.append("rgb(255, %s, %s)" % (color, color))
return json.dumps(segments)