215 lines
6.9 KiB
Plaintext
215 lines
6.9 KiB
Plaintext
def calculateFocus(self, child, scale=1.7):
|
|
"""
|
|
Hybrid focusing:
|
|
- MCM01: precise per-rotation affine for (dx, dy) (unchanged)
|
|
- MCM02: search-style mapping:
|
|
* 0°/180°: strong horizontal (dx from x,y), dy very gentle (clamped)
|
|
* 90°/270°: dx = 0, dy from x (fits your left/right anchors)
|
|
"""
|
|
|
|
# --- rotation ---
|
|
try:
|
|
rot = int(str(self.session.custom.rotation).replace("deg", "")) % 360
|
|
except:
|
|
rot = 0
|
|
|
|
# --- child coords ---
|
|
try:
|
|
x = float(child.position.x)
|
|
y = float(child.position.y)
|
|
w = float(child.position.width)
|
|
except:
|
|
system.perspective.print("Invalid position data on child component.")
|
|
return {"x": 0, "y": 0, "scale": scale}
|
|
|
|
# --- zone ---
|
|
try:
|
|
zone = child.props.params.tagProps[0].split("/")[1]
|
|
except:
|
|
zone = "MCM01"
|
|
|
|
# ======== MCM01 (your proven mapping, unchanged) ========
|
|
COEFFS_MCM01 = {
|
|
0: dict(ax= 956.86984, bx=-1853.94329, cx= -17.57191,
|
|
ay= 124.82245, by= -191.28916, cy= 227.58568),
|
|
90: dict(ax=-601.58230, bx= -218.90739, cx=1466.46475,
|
|
ay= 284.67701, by=-1528.43884, cy= 54.37458),
|
|
180: dict(ax=-728.83646, bx= 1521.61995, cx= 16.04437,
|
|
ay=-434.03405, by= -32.67146, cy=1071.85472),
|
|
270: dict(ax= 385.53372, bx= -44.67850, cx=-768.65879,
|
|
ay=-1341.88064, by= 1615.55073, cy= 142.77638),
|
|
}
|
|
|
|
# ======== MCM02 (fit from your new table) ========
|
|
|
|
# 0°: dx ≈ a + b*x + c*y (LS fit on: left/right/center/top/bottom)
|
|
_M2_DX_0 = dict(a= 691.72633028, b=-1788.01433165, c= 295.57517840)
|
|
# dy kept light & clamped around center (use a small gain around 0.5)
|
|
def _m2_dy0(y):
|
|
dy = 320.0 * (0.5 - y) # gentle bias
|
|
return max(min(dy, 120.0), -120.0)
|
|
|
|
# 180°: dx ≈ a + b*x + c*y
|
|
_M2_DX_180 = dict(a=-730.66959977, b= 1680.89494266, c= -70.52210472)
|
|
def _m2_dy180(y):
|
|
dy = 200.0 * (y - 0.5) # tiny bias
|
|
return max(min(dy, 80.0), -80.0)
|
|
|
|
# 90°: dx = 0, dy ≈ A + B*x (two-point fit from left/right; matches your sheet well)
|
|
_M2_DY_90_A = 278.8
|
|
_M2_DY_90_B = -1663.6 # ~ from (left 215.88) → (right -1213.52)
|
|
# 270°: dx = 0, dy ≈ A + B*x
|
|
_M2_DY_270_A = -1284.8
|
|
_M2_DY_270_B = 1686.1 # ~ from (left -1221.17) → (right 227.06)
|
|
|
|
# ======== compute (dx, dy) ========
|
|
if zone == "MCM01":
|
|
c = COEFFS_MCM01.get(rot, COEFFS_MCM01[0])
|
|
dx = c["ax"] + c["bx"] * x + c["cx"] * y
|
|
dy = c["ay"] + c["by"] * x + c["cy"] * y
|
|
|
|
else: # ------- MCM02 (search-style) -------
|
|
if rot == 0:
|
|
dx = _M2_DX_0["a"] + _M2_DX_0["b"] * x + _M2_DX_0["c"] * y
|
|
dy = _m2_dy0(y)
|
|
elif rot == 180:
|
|
dx = _M2_DX_180["a"] + _M2_DX_180["b"] * x + _M2_DX_180["c"] * y
|
|
dy = _m2_dy180(y)
|
|
elif rot == 90:
|
|
dx = 0.0
|
|
dy = _M2_DY_90_A + _M2_DY_90_B * x
|
|
elif rot == 270:
|
|
dx = 0.0
|
|
dy = _M2_DY_270_A + _M2_DY_270_B * x
|
|
else:
|
|
dx, dy = 0.0, 0.0
|
|
|
|
# --- slight downward shift for flat rotations ---
|
|
if rot in (0, 180):
|
|
dy -=50
|
|
|
|
# ======== wide device tweak (unchanged) ========
|
|
try:
|
|
deviceWidthPixels = float(w) * 1850.0
|
|
if deviceWidthPixels > 1200:
|
|
scale = max(scale, 1.8)
|
|
dy -= 100
|
|
except:
|
|
pass
|
|
|
|
return {"x": dx, "y": dy, "scale": scale}
|
|
|
|
def deviceType(self, path, props):
|
|
try:
|
|
docked_view = "Docked-East-"
|
|
section = "all"
|
|
devices = []
|
|
tags = []
|
|
prop = props[0]
|
|
|
|
# --- VFD ---
|
|
if "VFD" in path:
|
|
docked_view += "VFD"
|
|
section = "vfd"
|
|
|
|
# --- Conveyor ---
|
|
elif "Conv" in path or "Conveyor" in path:
|
|
docked_view += "Conv"
|
|
autStand.devices.build_device_mapping(prop)
|
|
devices = autStand.devices.build_device_table(self)
|
|
section = "conveyor"
|
|
|
|
# --- Generic devices ---
|
|
else:
|
|
docked_view += "Device"
|
|
|
|
tags = autStand.devices.getAllTags(self, prop, section=section)
|
|
|
|
return [docked_view, tags, devices]
|
|
|
|
except Exception as e:
|
|
import traceback
|
|
msg = "Error in deviceType: {}\n{}".format(str(e), traceback.format_exc())
|
|
system.perspective.print(msg)
|
|
return None
|
|
|
|
|
|
def handleTagHighlight(view, currentValue):
|
|
tagAndPriority = str(currentValue.value or "")
|
|
container = view.rootContainer.getChildren()[0]
|
|
|
|
# --- CASE 1: Remove all highlights by applying CLEAR class ---
|
|
if tagAndPriority.upper() == "CLEAR":
|
|
for child in container.getChildren():
|
|
try:
|
|
currentClasses = child.props.style['classes'].split(" ")
|
|
filtered = [c for c in currentClasses if not c.startswith("Highlight/")]
|
|
child.props.style.classes = " ".join(filtered)
|
|
child.props.params.highlight = ""
|
|
|
|
except:
|
|
pass
|
|
return
|
|
|
|
if "||" not in tagAndPriority:
|
|
return
|
|
|
|
parts = tagAndPriority.split("||")
|
|
|
|
tag = parts[0]
|
|
|
|
splitedTag = tag.split("/")
|
|
deviceName = splitedTag[-1]
|
|
|
|
# --- CASE 2: Open camera popup
|
|
if "Camera" in deviceName:
|
|
cameraView = container.getChild(deviceName)
|
|
ipAddress = cameraView.props.get("params", {}).get("ipaddress", "")
|
|
system.perspective.openPopup("kxYYzZ2O", "autStand/PopUp-Views/Camera", params = {"ipaddress": ipAddress}, title = deviceName)
|
|
return
|
|
|
|
components = container.getChildren()
|
|
|
|
priority = parts[1]
|
|
|
|
foundMatch = False
|
|
|
|
# clear all highlights and apply new one when found
|
|
for child in components:
|
|
props = child.meta.name
|
|
params = child.props.get("params", {})
|
|
tagProps = params.get("tagProps", {})
|
|
tagsList = list(tagProps)
|
|
|
|
if len(tagsList) == 0:
|
|
continue
|
|
|
|
# child.props.style.classes = ""
|
|
currentClasses = child.props.style.get('classes', '').split(" ")
|
|
|
|
# strip only highlight-related classes
|
|
filtered = [c for c in currentClasses if not c.startswith("Highlight/")]
|
|
|
|
child.props.style.classes = " ".join(filtered)
|
|
child.props.params.highlight = ""
|
|
|
|
tagPath = tagsList[0]
|
|
|
|
if tag == tagPath:
|
|
path = child.props.get("path")
|
|
device = str(path).split("/")[-1].lower()
|
|
child.props.params.highlight = priority
|
|
if "photoeye" not in device and not device.startswith("conveyor_"):
|
|
child.props.style.classes += " Highlight/Pulse-" + priority
|
|
docked_view = deviceType(view, path, tagProps)
|
|
system.perspective.openDock(docked_view[0], params = {'tagProps':tagProps, 'tags': docked_view[1], 'devices':docked_view[2], 'name':props})
|
|
system.perspective.sendMessage(
|
|
"focusDevice",
|
|
payload = calculateFocus(view, child),
|
|
scope="session"
|
|
)
|
|
foundMatch = True
|
|
|
|
return foundMatch
|
|
|