R-ION meeting room panel: Sedona app, page images and simulator package
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@@ -0,0 +1,3 @@
|
|||||||
|
out/sim/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# R-ION meeting room panel
|
||||||
|
|
||||||
|
Sedona app and screen images for an R-ION 320x240 meeting room panel. It has four pages:
|
||||||
|
|
||||||
|
- **Room free / Meeting in progress:** start a meeting, extend it by 15 or 30 minutes, end it
|
||||||
|
- **Lights:** choose one of four lighting scenes
|
||||||
|
- **Climate:** change the setpoint and see room temperature and humidity
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python build_meeting_room.py <unzipped meeting_panel_assets> "<sedona home>/ontrol/fontBank"
|
||||||
|
python make_sim.py
|
||||||
|
```
|
||||||
|
|
||||||
|
- `build_meeting_room.py` writes `out/app-Rion-MeetingRoom.sax` and `out/imageBank/MR_*.png`.
|
||||||
|
Copy the images into `<sedona home>/ontrol/imageBank`.
|
||||||
|
- `make_sim.py` writes `out/app-Rion-MeetingRoom-sim.zip`. Open it in ontrol_VM's simulatorLauncher.
|
||||||
|
The simulator uses Sox port 1876; log in as admin / 1234.
|
||||||
|
|
||||||
|
Both scripts need Pillow. `make_sim.py` also uses Py_sab2sax and the kits.scode from ontrol_VM's ExampleApp.
|
||||||
|
|
||||||
|
## Outputs to link to your drivers
|
||||||
|
|
||||||
|
| Output | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| `/lights/Scene.out` | Lighting scene: 1 Presentation, 2 Meeting, 3 Video call, 4 All off |
|
||||||
|
| `/climate/SpUD.out` | Temperature setpoint, saved in platform register01 |
|
||||||
|
| `/meeting/Timer.out` | True while a meeting is running |
|
||||||
@@ -0,0 +1,427 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""R-ION meeting room panel: builds the page images and the Sedona app (.sax).
|
||||||
|
|
||||||
|
python build_meeting_room.py <assets dir> <fontBank dir> [out dir]
|
||||||
|
|
||||||
|
<assets dir> the unzipped meeting_panel_assets.zip (uses bin/*_a8.bin icon masks)
|
||||||
|
<fontBank dir> <sedona home>/ontrol/fontBank - static captions are drawn with the
|
||||||
|
device's own bitmap fonts so they match the runtime labels exactly
|
||||||
|
out dir default ./out -> out/imageBank/MR_*.png + out/app-Rion-MeetingRoom.sax
|
||||||
|
|
||||||
|
Static captions are baked into the images; only values that change at runtime
|
||||||
|
(room temperature, remaining time, setpoint, humidity) are Ox labels.
|
||||||
|
"""
|
||||||
|
import base64, os, sys
|
||||||
|
from xml.sax.saxutils import quoteattr
|
||||||
|
from PIL import Image, ImageDraw
|
||||||
|
|
||||||
|
ASSETS, FONTS = sys.argv[1], sys.argv[2]
|
||||||
|
OUT = sys.argv[3] if len(sys.argv) > 3 else os.path.join(os.path.dirname(os.path.abspath(__file__)), "out")
|
||||||
|
IMG_OUT = os.path.join(OUT, "imageBank")
|
||||||
|
os.makedirs(IMG_OUT, exist_ok=True)
|
||||||
|
|
||||||
|
# ---- palette (ui_assets.h) -----------------------------------------------------------
|
||||||
|
HEX = {"BG": "#101418", "SURFACE": "#202830", "RAISED": "#303C48", "DISABLED": "#586470",
|
||||||
|
"MUTED": "#A0ACB8", "TEXT": "#FFFFFF", "INUSE": "#C83C10", "INUSE_EDGE": "#E85020",
|
||||||
|
"AVAILABLE": "#30C060", "PRIMARY": "#F8B830", "COOLING": "#3890F0"}
|
||||||
|
RGB = {k: tuple(int(v[i:i + 2], 16) for i in (1, 3, 5)) for k, v in HEX.items()}
|
||||||
|
C565 = {k: ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3) for k, (r, g, b) in RGB.items()}
|
||||||
|
|
||||||
|
# ---- device bitmap fonts (same layout the Sedona editor reads) -----------------------
|
||||||
|
class BitmapFont:
|
||||||
|
def __init__(self, path):
|
||||||
|
d = self.data = open(path, "rb").read()
|
||||||
|
self.height = d[34]
|
||||||
|
self.glyphs = {}
|
||||||
|
for i in range(d[32] | d[33] << 8):
|
||||||
|
e = d[64 + i * 10:74 + i * 10]
|
||||||
|
code = e[0] if e[0] < 192 and e[1] == 0 else e[0] | e[1] << 8
|
||||||
|
self.glyphs[code] = (e[2] | e[3] << 8 | e[4] << 16, e[5], e[6],
|
||||||
|
e[7] - 256 if e[7] > 127 else e[7], e[8], e[9])
|
||||||
|
|
||||||
|
def layout(self, text):
|
||||||
|
out, x = [], 0
|
||||||
|
for ch in text:
|
||||||
|
g = self.glyphs.get(ord(ch))
|
||||||
|
if not g:
|
||||||
|
continue
|
||||||
|
_, w, _, xo, _, adv = g
|
||||||
|
xoff = 1 if xo < 0 else xo + 1
|
||||||
|
out.append((ord(ch), x + xoff))
|
||||||
|
x += max(adv, w, xoff + w)
|
||||||
|
return out, x
|
||||||
|
|
||||||
|
def width(self, text):
|
||||||
|
return self.layout(text)[1]
|
||||||
|
|
||||||
|
def mask(self, code):
|
||||||
|
off, w, h, _, yo, _ = self.glyphs[code]
|
||||||
|
m = Image.new("L", (max(1, w), max(1, h)))
|
||||||
|
px = bytearray(w * h)
|
||||||
|
for i in range(w * h):
|
||||||
|
b = self.data[off + (i >> 1)]
|
||||||
|
px[i] = ((b >> 4) if i % 2 == 0 else (b & 0x0F)) * 17
|
||||||
|
if w and h:
|
||||||
|
m.putdata(px)
|
||||||
|
return m, yo
|
||||||
|
|
||||||
|
|
||||||
|
_fonts = {}
|
||||||
|
def font(size, bold=False):
|
||||||
|
key = (size, bold)
|
||||||
|
if key not in _fonts:
|
||||||
|
_fonts[key] = BitmapFont(os.path.join(FONTS, f"{'bold ' if bold else ''}{size}pt Tahoma.bin"))
|
||||||
|
return _fonts[key]
|
||||||
|
|
||||||
|
|
||||||
|
def text(im, s, x, y, h, f, colour, align="left", w=0):
|
||||||
|
"""Draw s in a box (x, y, w, h), vertically centred like Draw_Text_Box."""
|
||||||
|
glyphs, tw = f.layout(s)
|
||||||
|
if align == "center":
|
||||||
|
x += (w - tw) // 2
|
||||||
|
elif align == "right":
|
||||||
|
x += w - tw
|
||||||
|
top = y + (h - f.height) // 2
|
||||||
|
solid = Image.new("RGB", (1, 1), RGB[colour])
|
||||||
|
for code, gx in glyphs:
|
||||||
|
m, yo = f.mask(code)
|
||||||
|
im.paste(solid.resize(m.size), (x + gx, top + yo), m)
|
||||||
|
return tw
|
||||||
|
|
||||||
|
|
||||||
|
def icon(im, name, x, y, colour):
|
||||||
|
size = {"play": 20, "minus": 32, "plus": 32}.get(name, 18 if name.startswith("tab_") else 26)
|
||||||
|
raw = open(os.path.join(ASSETS, "bin", f"ico_{name}_a8.bin"), "rb").read()
|
||||||
|
m = Image.frombytes("L", (size, size), raw)
|
||||||
|
im.paste(Image.new("RGB", (size, size), RGB[colour]), (x, y), m)
|
||||||
|
return size
|
||||||
|
|
||||||
|
|
||||||
|
def rect(d, x0, y0, x1, y1, fill, border=None, bw=0):
|
||||||
|
if border:
|
||||||
|
d.rectangle([x0, y0, x1, y1], fill=RGB[border])
|
||||||
|
d.rectangle([x0 + bw, y0 + bw, x1 - bw, y1 - bw], fill=RGB[fill])
|
||||||
|
else:
|
||||||
|
d.rectangle([x0, y0, x1, y1], fill=RGB[fill])
|
||||||
|
|
||||||
|
|
||||||
|
def save(im, name):
|
||||||
|
assert len(name) <= 12, name
|
||||||
|
im.save(os.path.join(IMG_OUT, name + ".png"))
|
||||||
|
|
||||||
|
|
||||||
|
# ---- layout ---------------------------------------------------------------------------
|
||||||
|
ROOM_NAME = "Meeting Room"
|
||||||
|
TABS = [(0, 106, "tab_calendar", "Meeting"), (107, 212, "tab_bulb", "Lights"), (213, 319, "tab_thermo", "Climate")]
|
||||||
|
EXT_X = [8, 112, 216]
|
||||||
|
TILES = [(8, 32), (164, 32), (8, 116), (164, 116)] # 148 x 76
|
||||||
|
SCENES = [("presentation", "Presentation"), ("meeting", "Meeting"), ("video", "Video call"), ("power", "All off")]
|
||||||
|
|
||||||
|
|
||||||
|
def page(active_tab):
|
||||||
|
im = Image.new("RGB", (320, 240), RGB["BG"])
|
||||||
|
d = ImageDraw.Draw(im)
|
||||||
|
rect(d, 0, 23, 319, 23, "RAISED")
|
||||||
|
rect(d, 0, 192, 319, 192, "RAISED")
|
||||||
|
text(im, ROOM_NAME, 8, 0, 23, font(16, True), "TEXT")
|
||||||
|
for i, (x0, x1, ico, label) in enumerate(TABS):
|
||||||
|
on = i == active_tab
|
||||||
|
if on:
|
||||||
|
rect(d, x0, 193, x1, 239, "SURFACE")
|
||||||
|
rect(d, x0, 193, x1, 195, "PRIMARY")
|
||||||
|
col = "TEXT" if on else "MUTED"
|
||||||
|
f = font(16, on)
|
||||||
|
gw = 18 + 6 + f.width(label)
|
||||||
|
gx = x0 + (x1 - x0 + 1 - gw) // 2
|
||||||
|
icon(im, ico, gx, 196 + (44 - 18) // 2, col)
|
||||||
|
text(im, label, gx + 24, 196, 44, f, col)
|
||||||
|
return im, d
|
||||||
|
|
||||||
|
|
||||||
|
# Meeting - room free
|
||||||
|
im, d = page(0)
|
||||||
|
rect(d, 8, 32, 311, 127, "AVAILABLE")
|
||||||
|
text(im, "Available", 20, 38, 44, font(32, True), "BG")
|
||||||
|
text(im, "Tap below to start a meeting", 20, 84, 24, font(16), "BG")
|
||||||
|
rect(d, 8, 136, 311, 191, "PRIMARY")
|
||||||
|
f = font(18, True)
|
||||||
|
gw = 20 + 8 + f.width("Start meeting")
|
||||||
|
gx = 8 + (304 - gw) // 2
|
||||||
|
icon(im, "play", gx, 136 + 18, "BG")
|
||||||
|
text(im, "Start meeting", gx + 28, 136, 56, f, "BG")
|
||||||
|
save(im, "MR_free")
|
||||||
|
|
||||||
|
# Meeting - in progress (extend buttons are BooleanImages drawn on top)
|
||||||
|
im, d = page(0)
|
||||||
|
rect(d, 8, 32, 311, 127, "INUSE")
|
||||||
|
text(im, "Meeting in progress", 20, 36, 32, font(24, True), "TEXT")
|
||||||
|
x = 216
|
||||||
|
rect(d, x, 136, x + 95, 191, "SURFACE", "INUSE_EDGE", 2)
|
||||||
|
f = font(18, True)
|
||||||
|
gw = 26 + 4 + f.width("End")
|
||||||
|
gx = x + (96 - gw) // 2
|
||||||
|
icon(im, "power", gx, 136 + 15, "INUSE_EDGE")
|
||||||
|
text(im, "End", gx + 30, 136, 56, f, "TEXT")
|
||||||
|
save(im, "MR_inuse")
|
||||||
|
|
||||||
|
for mins in (15, 30):
|
||||||
|
for on in (True, False):
|
||||||
|
b = Image.new("RGB", (96, 56)); bd = ImageDraw.Draw(b)
|
||||||
|
rect(bd, 0, 0, 95, 55, "RAISED" if on else "SURFACE")
|
||||||
|
text(b, f"+{mins} min", 0, 0, 56, font(18, True), "TEXT" if on else "DISABLED", "center", 96)
|
||||||
|
save(b, f"MR_e{mins}{'on' if on else 'off'}")
|
||||||
|
|
||||||
|
# Lights
|
||||||
|
im, d = page(1)
|
||||||
|
save(im, "MR_light")
|
||||||
|
for n, (ico, label) in enumerate(SCENES, 1):
|
||||||
|
for on in (True, False):
|
||||||
|
t = Image.new("RGB", (148, 76)); td = ImageDraw.Draw(t)
|
||||||
|
if on:
|
||||||
|
rect(td, 0, 0, 147, 75, "PRIMARY")
|
||||||
|
else:
|
||||||
|
rect(td, 0, 0, 147, 75, "SURFACE", "RAISED", 2)
|
||||||
|
col = "BG" if on else "TEXT"
|
||||||
|
icon(t, ico, 12, 25, col)
|
||||||
|
f = font(16, True)
|
||||||
|
if f.width(label) > 148 - 46 - 6:
|
||||||
|
f = font(16)
|
||||||
|
text(t, label, 46, 0, 76, f, col)
|
||||||
|
save(t, f"MR_s{n}{'on' if on else 'off'}")
|
||||||
|
|
||||||
|
# Climate
|
||||||
|
im, d = page(2)
|
||||||
|
rect(d, 8, 32, 71, 135, "RAISED")
|
||||||
|
rect(d, 80, 32, 231, 135, "SURFACE")
|
||||||
|
rect(d, 240, 32, 311, 135, "RAISED")
|
||||||
|
rect(d, 8, 144, 311, 191, "SURFACE")
|
||||||
|
icon(im, "minus", 24, 68, "TEXT")
|
||||||
|
icon(im, "plus", 260, 68, "TEXT")
|
||||||
|
text(im, "Setpoint", 80, 36, 18, font(12), "MUTED", "center", 152)
|
||||||
|
text(im, "Room", 20, 146, 18, font(12), "MUTED")
|
||||||
|
text(im, "Humidity", 168, 146, 18, font(12), "MUTED")
|
||||||
|
save(im, "MR_clim")
|
||||||
|
|
||||||
|
|
||||||
|
# ---- Sedona app ---------------------------------------------------------------------
|
||||||
|
def buf(s):
|
||||||
|
"""Non-@asStr Buf props are stored base64 with the terminating NUL."""
|
||||||
|
return base64.b64encode(s.encode("utf-8") + b"\0").decode()
|
||||||
|
|
||||||
|
|
||||||
|
class Comp:
|
||||||
|
_next = 1
|
||||||
|
|
||||||
|
def __init__(self, name, type_, props=None, ws=None, parent=None):
|
||||||
|
assert len(name) <= 7, name
|
||||||
|
self.name, self.type, self.children = name, type_, []
|
||||||
|
self.props = dict(props or {})
|
||||||
|
self.id = Comp._next
|
||||||
|
Comp._next += 1
|
||||||
|
if ws: # wiresheet position: meta = y<<24 | x<<16 | 1
|
||||||
|
self.props = {"meta": (ws[1] << 24) | (ws[0] << 16) | 1, **self.props}
|
||||||
|
self.parent = parent
|
||||||
|
if parent:
|
||||||
|
parent.children.append(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def path(self):
|
||||||
|
return (self.parent.path if self.parent else "") + "/" + self.name
|
||||||
|
|
||||||
|
|
||||||
|
links = []
|
||||||
|
def link(a, slot_a, b, slot_b):
|
||||||
|
links.append((f"{a.path}.{slot_a}", f"{b.path}.{slot_b}"))
|
||||||
|
|
||||||
|
|
||||||
|
root = []
|
||||||
|
def top(name, type_="sys::Folder", props=None, ws=None):
|
||||||
|
c = Comp(name, type_, props, ws)
|
||||||
|
root.append(c)
|
||||||
|
return c
|
||||||
|
|
||||||
|
|
||||||
|
# services
|
||||||
|
service = top("service", ws=(2, 2))
|
||||||
|
plat = Comp("RionPlt", "ontrolRion::RionPlatformService", {"register01": "22.0"}, (2, 2), service)
|
||||||
|
oxbase = Comp("OxBase", "ontrolOx::OxBase", {"lcdSleepBrightness": 10, "lcdSleepTimeout": 60}, (2, 2), plat)
|
||||||
|
users = Comp("users", "sys::UserService", {}, (2, 8), service)
|
||||||
|
Comp("admin", "sys::User", {"cred": "wHy/iCHUdXWkccFgala3nl9uamg=", "perm": 2147483647, "prov": 255}, (2, 2), users)
|
||||||
|
Comp("guest", "sys::User", {"cred": "jVShQjDWIkrr+o3lYLcAPPvNVio=", "perm": 63}, (2, 8), users)
|
||||||
|
Comp("sox", "sox::SoxService", {}, (2, 14), service)
|
||||||
|
|
||||||
|
# pages
|
||||||
|
ui = top("ui", ws=(16, 2))
|
||||||
|
W = lambda x, y, w, h: {"x": x, "y": y, "width": w, "height": h}
|
||||||
|
TOUCH = {"backgroundColor": C565["BG"], "transparent": "true"}
|
||||||
|
|
||||||
|
|
||||||
|
def header_temp(p):
|
||||||
|
return Comp("RoomT", "ontrolOx::NumericLabel", {
|
||||||
|
**W(232, 1, 80, 21), "fontSize": 16, "attributes": 0x28, # right aligned, background
|
||||||
|
"text": buf("%.1f°C"), "textColor": C565["MUTED"], "backgroundColor": C565["BG"]}, parent=p)
|
||||||
|
|
||||||
|
|
||||||
|
def tab_touch(name, p, tab):
|
||||||
|
x0, x1 = TABS[tab][0], TABS[tab][1]
|
||||||
|
return Comp(name, "ontrolOx::Geometry", {**W(x0, 193, x1 - x0 + 1, 47), **TOUCH}, parent=p)
|
||||||
|
|
||||||
|
|
||||||
|
def page_comp(name, image, timeout, ws):
|
||||||
|
return Comp(name, "ontrolOx::OxPage", {"backgroundColor": C565["BG"], "imageFileName": image,
|
||||||
|
"touchTimeout": timeout}, ws, ui)
|
||||||
|
|
||||||
|
|
||||||
|
pFree = page_comp("Free", "MR_free", 0, (2, 2))
|
||||||
|
tFreeT = header_temp(pFree)
|
||||||
|
start = Comp("Start", "ontrolOx::Geometry", {**W(8, 136, 304, 56), **TOUCH}, parent=pFree)
|
||||||
|
fTabL, fTabC = tab_touch("TabLt", pFree, 1), tab_touch("TabCl", pFree, 2)
|
||||||
|
|
||||||
|
pUse = page_comp("InUse", "MR_inuse", 0, (2, 10))
|
||||||
|
tUseT = header_temp(pUse)
|
||||||
|
left = Comp("Left", "ontrolOx::NumericLabel", {
|
||||||
|
**W(20, 72, 280, 48), "fontSize": 32, "fontAttributes": 1, "attributes": 0x08,
|
||||||
|
"text": buf("%.0f min left"), "textColor": C565["TEXT"], "backgroundColor": C565["INUSE"]}, parent=pUse)
|
||||||
|
ext = {}
|
||||||
|
for n, mins in enumerate((15, 30)):
|
||||||
|
ext[mins] = Comp(f"Ext{mins}", "ontrolOx::BooleanImage", {
|
||||||
|
**W(EXT_X[n], 136, 96, 56), "falseImageFileName": f"MR_e{mins}off",
|
||||||
|
"trueImageFileName": f"MR_e{mins}on"}, parent=pUse)
|
||||||
|
end = Comp("End", "ontrolOx::Geometry", {**W(216, 136, 96, 56), **TOUCH}, parent=pUse)
|
||||||
|
uTabL, uTabC = tab_touch("TabLt", pUse, 1), tab_touch("TabCl", pUse, 2)
|
||||||
|
|
||||||
|
pLight = page_comp("Lights", "MR_light", 60, (2, 18))
|
||||||
|
tLightT = header_temp(pLight)
|
||||||
|
tiles = [Comp(f"Scene{n}", "ontrolOx::BooleanImage", {
|
||||||
|
**W(x, y, 148, 76), "falseImageFileName": f"MR_s{n}off", "trueImageFileName": f"MR_s{n}on"},
|
||||||
|
parent=pLight) for n, (x, y) in enumerate(TILES, 1)]
|
||||||
|
lTabM, lTabC = tab_touch("TabMt", pLight, 0), tab_touch("TabCl", pLight, 2)
|
||||||
|
|
||||||
|
pClim = page_comp("Climate", "MR_clim", 60, (2, 26))
|
||||||
|
tClimT = header_temp(pClim)
|
||||||
|
setpt = Comp("SetPt", "ontrolOx::NumericLabel", {
|
||||||
|
**W(80, 56, 152, 64), "fontSize": 48, "fontAttributes": 1, "attributes": 0x18,
|
||||||
|
"text": buf("%.1f°"), "textColor": C565["TEXT"], "backgroundColor": C565["SURFACE"]}, parent=pClim)
|
||||||
|
roomV = Comp("RoomV", "ontrolOx::NumericLabel", {
|
||||||
|
**W(20, 164, 136, 24), "fontSize": 18, "fontAttributes": 1, "attributes": 0x08,
|
||||||
|
"text": buf("%.1f°C"), "textColor": C565["TEXT"], "backgroundColor": C565["SURFACE"]}, parent=pClim)
|
||||||
|
humV = Comp("HumV", "ontrolOx::NumericLabel", {
|
||||||
|
**W(168, 164, 136, 24), "fontSize": 18, "fontAttributes": 1, "attributes": 0x08,
|
||||||
|
"text": buf("%.0f %%"), "textColor": C565["TEXT"], "backgroundColor": C565["SURFACE"]}, parent=pClim)
|
||||||
|
down = Comp("Down", "ontrolOx::Geometry", {**W(8, 32, 64, 104), **TOUCH}, parent=pClim)
|
||||||
|
up = Comp("Up", "ontrolOx::Geometry", {**W(240, 32, 72, 104), **TOUCH}, parent=pClim)
|
||||||
|
cTabM, cTabL = tab_touch("TabMt", pClim, 0), tab_touch("TabLt", pClim, 1)
|
||||||
|
|
||||||
|
# meeting logic
|
||||||
|
mtg = top("meeting", ws=(30, 2))
|
||||||
|
timer = Comp("Timer", "ontrolControl::CountDown", {}, (2, 2), mtg) # seconds left; out = meeting on (BootA clears it)
|
||||||
|
defDur = Comp("DefDur", "control::ConstInt", {"out": 3600}, (2, 10), mtg) # Start = 60 min
|
||||||
|
maxDur = Comp("MaxDur", "control::ConstFloat", {"out": "14400.0"}, (2, 16), mtg) # max 4 h
|
||||||
|
k = {v: Comp(f"K{v}", "control::ConstFloat", {"out": f"{v}.0"}, (2, 22 + 6 * i), mtg)
|
||||||
|
for i, v in enumerate((59, 60, 900, 1800))}
|
||||||
|
bootOn = Comp("BootOn", "control::ConstBool", {"out": "true"}, (2, 46), mtg)
|
||||||
|
|
||||||
|
TRIG = {"componentId": timer.id, "slotId": 1, "trigger": "true"} # CountDown.count
|
||||||
|
startA = Comp("StartA", "ontrolTrigger::TrigActionInt", TRIG, (14, 2), mtg)
|
||||||
|
endA = Comp("EndA", "ontrolTrigger::TrigActionInt", TRIG, (14, 10), mtg)
|
||||||
|
bootA = Comp("BootA", "ontrolTrigger::TrigActionInt", TRIG, (14, 18), mtg)
|
||||||
|
link(start, "touch", startA, "in"); link(defDur, "out", startA, "value")
|
||||||
|
link(end, "touch", endA, "in")
|
||||||
|
link(bootOn, "out", bootA, "in")
|
||||||
|
|
||||||
|
cntF = Comp("CntF", "control::I2F", {}, (14, 26), mtg)
|
||||||
|
link(timer, "count", cntF, "in")
|
||||||
|
# minutes left, rounded up: (count + 59) / 60
|
||||||
|
add59 = Comp("Add59", "control::Add2", {}, (26, 26), mtg)
|
||||||
|
div60 = Comp("Div60", "control::Div2", {}, (38, 26), mtg)
|
||||||
|
minI = Comp("MinI", "control::F2I", {}, (50, 26), mtg)
|
||||||
|
minF = Comp("MinF", "control::I2F", {}, (62, 26), mtg)
|
||||||
|
link(cntF, "out", add59, "in1"); link(k[59], "out", add59, "in2")
|
||||||
|
link(add59, "out", div60, "in1"); link(k[60], "out", div60, "in2")
|
||||||
|
link(div60, "out", minI, "in"); link(minI, "out", minF, "in")
|
||||||
|
link(minF, "out", left, "in")
|
||||||
|
|
||||||
|
# extend: count += 900 / 1800, only while the result stays under MaxDur
|
||||||
|
for row, mins in enumerate((15, 30)):
|
||||||
|
y = 34 + row * 16
|
||||||
|
sec = mins * 60
|
||||||
|
add = Comp(f"Add{mins}", "control::Add2", {}, (26, y), mtg)
|
||||||
|
toI = Comp(f"Ext{mins}I", "control::F2I", {}, (38, y), mtg)
|
||||||
|
act = Comp(f"Ext{mins}A", "ontrolTrigger::TrigActionInt", TRIG, (62, y), mtg)
|
||||||
|
lim = Comp(f"Lim{mins}", "control::Sub2", {}, (26, y + 8), mtg)
|
||||||
|
cmp_ = Comp(f"Cmp{mins}", "control::Cmpr", {}, (38, y + 8), mtg)
|
||||||
|
gate = Comp(f"And{mins}", "control::And2", {}, (50, y + 8), mtg)
|
||||||
|
link(cntF, "out", add, "in1"); link(k[sec], "out", add, "in2")
|
||||||
|
link(add, "out", toI, "in"); link(toI, "out", act, "value")
|
||||||
|
link(maxDur, "out", lim, "in1"); link(k[sec], "out", lim, "in2")
|
||||||
|
link(cntF, "out", cmp_, "x"); link(lim, "out", cmp_, "y")
|
||||||
|
link(cmp_, "xly", ext[mins], "in")
|
||||||
|
link(ext[mins], "touch", gate, "in1"); link(cmp_, "xly", gate, "in2")
|
||||||
|
link(gate, "out", act, "in")
|
||||||
|
|
||||||
|
# home page follows the meeting state; idle pages fall back to it
|
||||||
|
pageSw = Comp("PageSw", "control::ISW", {}, (26, 2), mtg)
|
||||||
|
link(pFree, "pageId", pageSw, "in1"); link(pUse, "pageId", pageSw, "in2")
|
||||||
|
link(timer, "out", pageSw, "s1"); link(pageSw, "out", oxbase, "homePageId")
|
||||||
|
|
||||||
|
# lighting scenes: Scene.out = 1 Presentation, 2 Meeting, 3 Video call, 4 All off
|
||||||
|
lights = top("lights", ws=(30, 10))
|
||||||
|
scene = Comp("Scene", "ontrolTrigger::TrigNumericSelect12",
|
||||||
|
{"value1": "1.0", "value2": "2.0", "value3": "3.0", "value4": "4.0"}, (14, 2), lights)
|
||||||
|
startSc = Comp("StartSc", "control::Or2", {}, (2, 2), lights) # Start meeting -> Meeting scene
|
||||||
|
link(tiles[1], "touch", startSc, "in1"); link(start, "touch", startSc, "in2")
|
||||||
|
for n, tile in enumerate(tiles, 1):
|
||||||
|
kc = Comp(f"S{n}", "control::ConstFloat", {"out": f"{n}.0"}, (2, 6 + 6 * n), lights)
|
||||||
|
cm = Comp(f"Is{n}", "control::Cmpr", {}, (26, 6 + 6 * n), lights)
|
||||||
|
link(scene, "out", cm, "x"); link(kc, "out", cm, "y"); link(cm, "xey", tile, "in")
|
||||||
|
if n == 2:
|
||||||
|
link(startSc, "out", scene, "trigIn2")
|
||||||
|
else:
|
||||||
|
link(tile, "touch", scene, f"trigIn{n}")
|
||||||
|
|
||||||
|
# climate: setpoint kept in platform register01 across restarts
|
||||||
|
clim = top("climate", ws=(30, 18))
|
||||||
|
spReg = Comp("SpReg", "ontrolControl::RegFloat", {"address": 1}, (2, 2), clim)
|
||||||
|
spUd = Comp("SpUD", "ontrolTrigger::TrigNumericUpDown",
|
||||||
|
{"delta": "0.5", "min": "16.0", "max": "30.0"}, (14, 2), clim)
|
||||||
|
link(spReg, "value", spUd, "value"); link(spUd, "out", spReg, "in")
|
||||||
|
link(up, "touch", spUd, "trigUp"); link(down, "touch", spUd, "trigDown")
|
||||||
|
link(spUd, "out", setpt, "in")
|
||||||
|
for lab in (tFreeT, tUseT, tLightT, tClimT, roomV):
|
||||||
|
link(plat, "roomTemperature", lab, "in")
|
||||||
|
link(plat, "roomRh", humV, "in")
|
||||||
|
|
||||||
|
# tab navigation
|
||||||
|
link(fTabL, "touch", pLight, "trigThisPage"); link(fTabC, "touch", pClim, "trigThisPage")
|
||||||
|
link(uTabL, "touch", pLight, "trigThisPage"); link(uTabC, "touch", pClim, "trigThisPage")
|
||||||
|
link(lTabM, "touch", pLight, "trigHome"); link(lTabC, "touch", pClim, "trigThisPage")
|
||||||
|
link(cTabM, "touch", pClim, "trigHome"); link(cTabL, "touch", pLight, "trigThisPage")
|
||||||
|
|
||||||
|
# ---- write .sax ----------------------------------------------------------------------
|
||||||
|
KITS = ["sys", "control", "inet", "sox", "ontrolPlatform", "ontrolRion", "ontrolOx",
|
||||||
|
"ontrolControl", "ontrolTrigger"]
|
||||||
|
lines = ["<?xml version='1.0'?>", "<sedonaApp>", "<schema>"]
|
||||||
|
lines += [f' <kit name="{k}" />' for k in KITS]
|
||||||
|
lines += ["</schema>", "<app>", ' <prop name="deviceName" val="Rion"/>',
|
||||||
|
' <prop name="appName" val="MeetRoom"/>', ' <prop name="scanPeriod" val="100"/>']
|
||||||
|
|
||||||
|
|
||||||
|
def emit(c, depth):
|
||||||
|
ind = " " * depth
|
||||||
|
lines.append(f"{ind}<!-- {c.path} -->")
|
||||||
|
lines.append(f'{ind}<comp name="{c.name}" id="{c.id}" type="{c.type}">')
|
||||||
|
for k_, v in c.props.items():
|
||||||
|
lines.append(f'{ind} <prop name="{k_}" val={quoteattr(str(v))}/>')
|
||||||
|
for ch in c.children:
|
||||||
|
emit(ch, depth + 1)
|
||||||
|
lines.append(f"{ind}</comp>")
|
||||||
|
|
||||||
|
|
||||||
|
for c in root:
|
||||||
|
emit(c, 1)
|
||||||
|
lines += ["</app>", "<links>"]
|
||||||
|
lines += [f' <link from="{a}" to="{b}"/>' for a, b in links]
|
||||||
|
lines += ["</links>", "</sedonaApp>", ""]
|
||||||
|
with open(os.path.join(OUT, "app-Rion-MeetingRoom.sax"), "w", encoding="utf-8", newline="\n") as fp:
|
||||||
|
fp.write("\n".join(lines))
|
||||||
|
print(f"{len(os.listdir(IMG_OUT))} images, {Comp._next - 1} components, {len(links)} links -> {OUT}")
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Packs out/app-Rion-MeetingRoom.sax for the Ontrol Rion simulator (ontrol_VM).
|
||||||
|
|
||||||
|
python make_sim.py
|
||||||
|
|
||||||
|
Writes out/sim/device/ (app.sab, kits.scode, images/, fonts/, system/) and
|
||||||
|
out/app-Rion-MeetingRoom-sim.zip, the backup layout simulatorLauncher opens.
|
||||||
|
kits.scode and the boot logo are taken from ontrol_VM's ExampleApp Rion backup, so
|
||||||
|
the app's schema is rewritten to that scode's kits and checksums.
|
||||||
|
"""
|
||||||
|
import os, re, shutil, sys, zipfile
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
SEDONA_HOME = r"C:\Users\aa\OneDrive - Ontrol\Documents\_is\NiagaraAXSedona\sedona"
|
||||||
|
VM = r"C:\Users\aa\_aaSourceCodes\ontrol_VM"
|
||||||
|
EXAMPLE = os.path.join(VM, "ExampleApp", "app-RION-VM_mini.zip")
|
||||||
|
SAB2SAX = r"C:\Users\aa\_aaSourceCodes\Py_sab2sax"
|
||||||
|
FONTS = ["16pt Tahoma.bin", "32pt Tahoma.bin", "72pt Tahoma.bin",
|
||||||
|
"bold 18pt Tahoma.bin", "bold 32pt Tahoma.bin", "bold 48pt Tahoma.bin"]
|
||||||
|
|
||||||
|
OUT = os.path.join(HERE, "out")
|
||||||
|
SAX = os.path.join(OUT, "app-Rion-MeetingRoom.sax")
|
||||||
|
SIM = os.path.join(OUT, "sim")
|
||||||
|
DEV = os.path.join(SIM, "device")
|
||||||
|
shutil.rmtree(SIM, ignore_errors=True)
|
||||||
|
for d in ("images", "fonts", "system"):
|
||||||
|
os.makedirs(os.path.join(DEV, d))
|
||||||
|
|
||||||
|
# app.sax with the example scode's schema (kit set and checksums must match kits.scode)
|
||||||
|
with zipfile.ZipFile(EXAMPLE) as z:
|
||||||
|
ex_sax = z.read("app.sax").decode("utf-8")
|
||||||
|
open(os.path.join(DEV, "kits.scode"), "wb").write(z.read("device/kits.scode"))
|
||||||
|
open(os.path.join(DEV, "system", "logo.bin"), "wb").write(z.read("device/system/logo.bin"))
|
||||||
|
schema = re.search(r"<schema>.*?</schema>", ex_sax, re.S).group(0)
|
||||||
|
sim_sax = re.sub(r"<schema>.*?</schema>", lambda m: schema, open(SAX, encoding="utf-8").read(), flags=re.S)
|
||||||
|
open(os.path.join(SIM, "app.sax"), "w", encoding="utf-8", newline="\n").write(sim_sax)
|
||||||
|
|
||||||
|
sys.path.insert(0, SAB2SAX)
|
||||||
|
import sab # Py_sab2sax's SAX -> SAB encoder
|
||||||
|
sab.encode(os.path.join(SIM, "app.sax"), SEDONA_HOME, os.path.join(DEV, "app.sab"))
|
||||||
|
|
||||||
|
|
||||||
|
def native_image(path, name):
|
||||||
|
"""Rion image file: 32-byte name, flags, u16 LE width/height, 27 pad, RGB565 LE."""
|
||||||
|
img = Image.open(path).convert("RGB")
|
||||||
|
w, h = img.size
|
||||||
|
out = bytearray(name.encode("ascii")) + bytes(32 - len(name))
|
||||||
|
out += bytes([0, w & 0xFF, w >> 8, h & 0xFF, h >> 8]) + bytes(27)
|
||||||
|
for r, g, b in img.getdata():
|
||||||
|
v = (r >> 3) << 11 | (g >> 2) << 5 | (b >> 3)
|
||||||
|
out += bytes((v & 0xFF, v >> 8))
|
||||||
|
return bytes(out)
|
||||||
|
|
||||||
|
|
||||||
|
bank = os.path.join(OUT, "imageBank")
|
||||||
|
for f in sorted(os.listdir(bank)):
|
||||||
|
name = os.path.splitext(f)[0]
|
||||||
|
open(os.path.join(DEV, "images", name + ".bin"), "wb").write(native_image(os.path.join(bank, f), name))
|
||||||
|
for f in FONTS:
|
||||||
|
shutil.copy2(os.path.join(SEDONA_HOME, "ontrol", "fontBank", f), os.path.join(DEV, "fonts", f))
|
||||||
|
|
||||||
|
zpath = os.path.join(OUT, "app-Rion-MeetingRoom-sim.zip")
|
||||||
|
with zipfile.ZipFile(zpath, "w", zipfile.ZIP_DEFLATED) as z:
|
||||||
|
for root, _, files in os.walk(SIM):
|
||||||
|
for f in files:
|
||||||
|
full = os.path.join(root, f)
|
||||||
|
z.write(full, os.path.relpath(full, SIM).replace(os.sep, "/"))
|
||||||
|
for f in os.listdir(bank):
|
||||||
|
z.write(os.path.join(bank, f), "imageBank/" + f)
|
||||||
|
for f in FONTS:
|
||||||
|
z.write(os.path.join(DEV, "fonts", f), "fontBank/" + f)
|
||||||
|
print("device folder:", DEV)
|
||||||
|
print("backup zip: ", zpath)
|
||||||
@@ -0,0 +1,638 @@
|
|||||||
|
<?xml version='1.0'?>
|
||||||
|
<sedonaApp>
|
||||||
|
<schema>
|
||||||
|
<kit name="sys" />
|
||||||
|
<kit name="control" />
|
||||||
|
<kit name="inet" />
|
||||||
|
<kit name="sox" />
|
||||||
|
<kit name="ontrolPlatform" />
|
||||||
|
<kit name="ontrolRion" />
|
||||||
|
<kit name="ontrolOx" />
|
||||||
|
<kit name="ontrolControl" />
|
||||||
|
<kit name="ontrolTrigger" />
|
||||||
|
</schema>
|
||||||
|
<app>
|
||||||
|
<prop name="deviceName" val="Rion"/>
|
||||||
|
<prop name="appName" val="MeetRoom"/>
|
||||||
|
<prop name="scanPeriod" val="100"/>
|
||||||
|
<!-- /service -->
|
||||||
|
<comp name="service" id="1" type="sys::Folder">
|
||||||
|
<prop name="meta" val="33685505"/>
|
||||||
|
<!-- /service/RionPlt -->
|
||||||
|
<comp name="RionPlt" id="2" type="ontrolRion::RionPlatformService">
|
||||||
|
<prop name="meta" val="33685505"/>
|
||||||
|
<prop name="register01" val="22.0"/>
|
||||||
|
<!-- /service/RionPlt/OxBase -->
|
||||||
|
<comp name="OxBase" id="3" type="ontrolOx::OxBase">
|
||||||
|
<prop name="meta" val="33685505"/>
|
||||||
|
<prop name="lcdSleepBrightness" val="10"/>
|
||||||
|
<prop name="lcdSleepTimeout" val="60"/>
|
||||||
|
</comp>
|
||||||
|
</comp>
|
||||||
|
<!-- /service/users -->
|
||||||
|
<comp name="users" id="4" type="sys::UserService">
|
||||||
|
<prop name="meta" val="134348801"/>
|
||||||
|
<!-- /service/users/admin -->
|
||||||
|
<comp name="admin" id="5" type="sys::User">
|
||||||
|
<prop name="meta" val="33685505"/>
|
||||||
|
<prop name="cred" val="wHy/iCHUdXWkccFgala3nl9uamg="/>
|
||||||
|
<prop name="perm" val="2147483647"/>
|
||||||
|
<prop name="prov" val="255"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /service/users/guest -->
|
||||||
|
<comp name="guest" id="6" type="sys::User">
|
||||||
|
<prop name="meta" val="134348801"/>
|
||||||
|
<prop name="cred" val="jVShQjDWIkrr+o3lYLcAPPvNVio="/>
|
||||||
|
<prop name="perm" val="63"/>
|
||||||
|
</comp>
|
||||||
|
</comp>
|
||||||
|
<!-- /service/sox -->
|
||||||
|
<comp name="sox" id="7" type="sox::SoxService">
|
||||||
|
<prop name="meta" val="235012097"/>
|
||||||
|
</comp>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui -->
|
||||||
|
<comp name="ui" id="8" type="sys::Folder">
|
||||||
|
<prop name="meta" val="34603009"/>
|
||||||
|
<!-- /ui/Free -->
|
||||||
|
<comp name="Free" id="9" type="ontrolOx::OxPage">
|
||||||
|
<prop name="meta" val="33685505"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="imageFileName" val="MR_free"/>
|
||||||
|
<prop name="touchTimeout" val="0"/>
|
||||||
|
<!-- /ui/Free/RoomT -->
|
||||||
|
<comp name="RoomT" id="10" type="ontrolOx::NumericLabel">
|
||||||
|
<prop name="x" val="232"/>
|
||||||
|
<prop name="y" val="1"/>
|
||||||
|
<prop name="width" val="80"/>
|
||||||
|
<prop name="height" val="21"/>
|
||||||
|
<prop name="fontSize" val="16"/>
|
||||||
|
<prop name="attributes" val="40"/>
|
||||||
|
<prop name="text" val="JS4xZsKwQwA="/>
|
||||||
|
<prop name="textColor" val="42359"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Free/Start -->
|
||||||
|
<comp name="Start" id="11" type="ontrolOx::Geometry">
|
||||||
|
<prop name="x" val="8"/>
|
||||||
|
<prop name="y" val="136"/>
|
||||||
|
<prop name="width" val="304"/>
|
||||||
|
<prop name="height" val="56"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="transparent" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Free/TabLt -->
|
||||||
|
<comp name="TabLt" id="12" type="ontrolOx::Geometry">
|
||||||
|
<prop name="x" val="107"/>
|
||||||
|
<prop name="y" val="193"/>
|
||||||
|
<prop name="width" val="106"/>
|
||||||
|
<prop name="height" val="47"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="transparent" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Free/TabCl -->
|
||||||
|
<comp name="TabCl" id="13" type="ontrolOx::Geometry">
|
||||||
|
<prop name="x" val="213"/>
|
||||||
|
<prop name="y" val="193"/>
|
||||||
|
<prop name="width" val="107"/>
|
||||||
|
<prop name="height" val="47"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="transparent" val="true"/>
|
||||||
|
</comp>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/InUse -->
|
||||||
|
<comp name="InUse" id="14" type="ontrolOx::OxPage">
|
||||||
|
<prop name="meta" val="167903233"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="imageFileName" val="MR_inuse"/>
|
||||||
|
<prop name="touchTimeout" val="0"/>
|
||||||
|
<!-- /ui/InUse/RoomT -->
|
||||||
|
<comp name="RoomT" id="15" type="ontrolOx::NumericLabel">
|
||||||
|
<prop name="x" val="232"/>
|
||||||
|
<prop name="y" val="1"/>
|
||||||
|
<prop name="width" val="80"/>
|
||||||
|
<prop name="height" val="21"/>
|
||||||
|
<prop name="fontSize" val="16"/>
|
||||||
|
<prop name="attributes" val="40"/>
|
||||||
|
<prop name="text" val="JS4xZsKwQwA="/>
|
||||||
|
<prop name="textColor" val="42359"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/InUse/Left -->
|
||||||
|
<comp name="Left" id="16" type="ontrolOx::NumericLabel">
|
||||||
|
<prop name="x" val="20"/>
|
||||||
|
<prop name="y" val="72"/>
|
||||||
|
<prop name="width" val="280"/>
|
||||||
|
<prop name="height" val="48"/>
|
||||||
|
<prop name="fontSize" val="32"/>
|
||||||
|
<prop name="fontAttributes" val="1"/>
|
||||||
|
<prop name="attributes" val="8"/>
|
||||||
|
<prop name="text" val="JS4wZiBtaW4gbGVmdAA="/>
|
||||||
|
<prop name="textColor" val="65535"/>
|
||||||
|
<prop name="backgroundColor" val="51682"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/InUse/Ext15 -->
|
||||||
|
<comp name="Ext15" id="17" type="ontrolOx::BooleanImage">
|
||||||
|
<prop name="x" val="8"/>
|
||||||
|
<prop name="y" val="136"/>
|
||||||
|
<prop name="width" val="96"/>
|
||||||
|
<prop name="height" val="56"/>
|
||||||
|
<prop name="falseImageFileName" val="MR_e15off"/>
|
||||||
|
<prop name="trueImageFileName" val="MR_e15on"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/InUse/Ext30 -->
|
||||||
|
<comp name="Ext30" id="18" type="ontrolOx::BooleanImage">
|
||||||
|
<prop name="x" val="112"/>
|
||||||
|
<prop name="y" val="136"/>
|
||||||
|
<prop name="width" val="96"/>
|
||||||
|
<prop name="height" val="56"/>
|
||||||
|
<prop name="falseImageFileName" val="MR_e30off"/>
|
||||||
|
<prop name="trueImageFileName" val="MR_e30on"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/InUse/End -->
|
||||||
|
<comp name="End" id="19" type="ontrolOx::Geometry">
|
||||||
|
<prop name="x" val="216"/>
|
||||||
|
<prop name="y" val="136"/>
|
||||||
|
<prop name="width" val="96"/>
|
||||||
|
<prop name="height" val="56"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="transparent" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/InUse/TabLt -->
|
||||||
|
<comp name="TabLt" id="20" type="ontrolOx::Geometry">
|
||||||
|
<prop name="x" val="107"/>
|
||||||
|
<prop name="y" val="193"/>
|
||||||
|
<prop name="width" val="106"/>
|
||||||
|
<prop name="height" val="47"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="transparent" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/InUse/TabCl -->
|
||||||
|
<comp name="TabCl" id="21" type="ontrolOx::Geometry">
|
||||||
|
<prop name="x" val="213"/>
|
||||||
|
<prop name="y" val="193"/>
|
||||||
|
<prop name="width" val="107"/>
|
||||||
|
<prop name="height" val="47"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="transparent" val="true"/>
|
||||||
|
</comp>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Lights -->
|
||||||
|
<comp name="Lights" id="22" type="ontrolOx::OxPage">
|
||||||
|
<prop name="meta" val="302120961"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="imageFileName" val="MR_light"/>
|
||||||
|
<prop name="touchTimeout" val="60"/>
|
||||||
|
<!-- /ui/Lights/RoomT -->
|
||||||
|
<comp name="RoomT" id="23" type="ontrolOx::NumericLabel">
|
||||||
|
<prop name="x" val="232"/>
|
||||||
|
<prop name="y" val="1"/>
|
||||||
|
<prop name="width" val="80"/>
|
||||||
|
<prop name="height" val="21"/>
|
||||||
|
<prop name="fontSize" val="16"/>
|
||||||
|
<prop name="attributes" val="40"/>
|
||||||
|
<prop name="text" val="JS4xZsKwQwA="/>
|
||||||
|
<prop name="textColor" val="42359"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Lights/Scene1 -->
|
||||||
|
<comp name="Scene1" id="24" type="ontrolOx::BooleanImage">
|
||||||
|
<prop name="x" val="8"/>
|
||||||
|
<prop name="y" val="32"/>
|
||||||
|
<prop name="width" val="148"/>
|
||||||
|
<prop name="height" val="76"/>
|
||||||
|
<prop name="falseImageFileName" val="MR_s1off"/>
|
||||||
|
<prop name="trueImageFileName" val="MR_s1on"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Lights/Scene2 -->
|
||||||
|
<comp name="Scene2" id="25" type="ontrolOx::BooleanImage">
|
||||||
|
<prop name="x" val="164"/>
|
||||||
|
<prop name="y" val="32"/>
|
||||||
|
<prop name="width" val="148"/>
|
||||||
|
<prop name="height" val="76"/>
|
||||||
|
<prop name="falseImageFileName" val="MR_s2off"/>
|
||||||
|
<prop name="trueImageFileName" val="MR_s2on"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Lights/Scene3 -->
|
||||||
|
<comp name="Scene3" id="26" type="ontrolOx::BooleanImage">
|
||||||
|
<prop name="x" val="8"/>
|
||||||
|
<prop name="y" val="116"/>
|
||||||
|
<prop name="width" val="148"/>
|
||||||
|
<prop name="height" val="76"/>
|
||||||
|
<prop name="falseImageFileName" val="MR_s3off"/>
|
||||||
|
<prop name="trueImageFileName" val="MR_s3on"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Lights/Scene4 -->
|
||||||
|
<comp name="Scene4" id="27" type="ontrolOx::BooleanImage">
|
||||||
|
<prop name="x" val="164"/>
|
||||||
|
<prop name="y" val="116"/>
|
||||||
|
<prop name="width" val="148"/>
|
||||||
|
<prop name="height" val="76"/>
|
||||||
|
<prop name="falseImageFileName" val="MR_s4off"/>
|
||||||
|
<prop name="trueImageFileName" val="MR_s4on"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Lights/TabMt -->
|
||||||
|
<comp name="TabMt" id="28" type="ontrolOx::Geometry">
|
||||||
|
<prop name="x" val="0"/>
|
||||||
|
<prop name="y" val="193"/>
|
||||||
|
<prop name="width" val="107"/>
|
||||||
|
<prop name="height" val="47"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="transparent" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Lights/TabCl -->
|
||||||
|
<comp name="TabCl" id="29" type="ontrolOx::Geometry">
|
||||||
|
<prop name="x" val="213"/>
|
||||||
|
<prop name="y" val="193"/>
|
||||||
|
<prop name="width" val="107"/>
|
||||||
|
<prop name="height" val="47"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="transparent" val="true"/>
|
||||||
|
</comp>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Climate -->
|
||||||
|
<comp name="Climate" id="30" type="ontrolOx::OxPage">
|
||||||
|
<prop name="meta" val="436338689"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="imageFileName" val="MR_clim"/>
|
||||||
|
<prop name="touchTimeout" val="60"/>
|
||||||
|
<!-- /ui/Climate/RoomT -->
|
||||||
|
<comp name="RoomT" id="31" type="ontrolOx::NumericLabel">
|
||||||
|
<prop name="x" val="232"/>
|
||||||
|
<prop name="y" val="1"/>
|
||||||
|
<prop name="width" val="80"/>
|
||||||
|
<prop name="height" val="21"/>
|
||||||
|
<prop name="fontSize" val="16"/>
|
||||||
|
<prop name="attributes" val="40"/>
|
||||||
|
<prop name="text" val="JS4xZsKwQwA="/>
|
||||||
|
<prop name="textColor" val="42359"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Climate/SetPt -->
|
||||||
|
<comp name="SetPt" id="32" type="ontrolOx::NumericLabel">
|
||||||
|
<prop name="x" val="80"/>
|
||||||
|
<prop name="y" val="56"/>
|
||||||
|
<prop name="width" val="152"/>
|
||||||
|
<prop name="height" val="64"/>
|
||||||
|
<prop name="fontSize" val="48"/>
|
||||||
|
<prop name="fontAttributes" val="1"/>
|
||||||
|
<prop name="attributes" val="24"/>
|
||||||
|
<prop name="text" val="JS4xZsKwAA=="/>
|
||||||
|
<prop name="textColor" val="65535"/>
|
||||||
|
<prop name="backgroundColor" val="8518"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Climate/RoomV -->
|
||||||
|
<comp name="RoomV" id="33" type="ontrolOx::NumericLabel">
|
||||||
|
<prop name="x" val="20"/>
|
||||||
|
<prop name="y" val="164"/>
|
||||||
|
<prop name="width" val="136"/>
|
||||||
|
<prop name="height" val="24"/>
|
||||||
|
<prop name="fontSize" val="18"/>
|
||||||
|
<prop name="fontAttributes" val="1"/>
|
||||||
|
<prop name="attributes" val="8"/>
|
||||||
|
<prop name="text" val="JS4xZsKwQwA="/>
|
||||||
|
<prop name="textColor" val="65535"/>
|
||||||
|
<prop name="backgroundColor" val="8518"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Climate/HumV -->
|
||||||
|
<comp name="HumV" id="34" type="ontrolOx::NumericLabel">
|
||||||
|
<prop name="x" val="168"/>
|
||||||
|
<prop name="y" val="164"/>
|
||||||
|
<prop name="width" val="136"/>
|
||||||
|
<prop name="height" val="24"/>
|
||||||
|
<prop name="fontSize" val="18"/>
|
||||||
|
<prop name="fontAttributes" val="1"/>
|
||||||
|
<prop name="attributes" val="8"/>
|
||||||
|
<prop name="text" val="JS4wZiAlJQA="/>
|
||||||
|
<prop name="textColor" val="65535"/>
|
||||||
|
<prop name="backgroundColor" val="8518"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Climate/Down -->
|
||||||
|
<comp name="Down" id="35" type="ontrolOx::Geometry">
|
||||||
|
<prop name="x" val="8"/>
|
||||||
|
<prop name="y" val="32"/>
|
||||||
|
<prop name="width" val="64"/>
|
||||||
|
<prop name="height" val="104"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="transparent" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Climate/Up -->
|
||||||
|
<comp name="Up" id="36" type="ontrolOx::Geometry">
|
||||||
|
<prop name="x" val="240"/>
|
||||||
|
<prop name="y" val="32"/>
|
||||||
|
<prop name="width" val="72"/>
|
||||||
|
<prop name="height" val="104"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="transparent" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Climate/TabMt -->
|
||||||
|
<comp name="TabMt" id="37" type="ontrolOx::Geometry">
|
||||||
|
<prop name="x" val="0"/>
|
||||||
|
<prop name="y" val="193"/>
|
||||||
|
<prop name="width" val="107"/>
|
||||||
|
<prop name="height" val="47"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="transparent" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /ui/Climate/TabLt -->
|
||||||
|
<comp name="TabLt" id="38" type="ontrolOx::Geometry">
|
||||||
|
<prop name="x" val="107"/>
|
||||||
|
<prop name="y" val="193"/>
|
||||||
|
<prop name="width" val="106"/>
|
||||||
|
<prop name="height" val="47"/>
|
||||||
|
<prop name="backgroundColor" val="4259"/>
|
||||||
|
<prop name="transparent" val="true"/>
|
||||||
|
</comp>
|
||||||
|
</comp>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting -->
|
||||||
|
<comp name="meeting" id="39" type="sys::Folder">
|
||||||
|
<prop name="meta" val="35520513"/>
|
||||||
|
<!-- /meeting/Timer -->
|
||||||
|
<comp name="Timer" id="40" type="ontrolControl::CountDown">
|
||||||
|
<prop name="meta" val="33685505"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/DefDur -->
|
||||||
|
<comp name="DefDur" id="41" type="control::ConstInt">
|
||||||
|
<prop name="meta" val="167903233"/>
|
||||||
|
<prop name="out" val="3600"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/MaxDur -->
|
||||||
|
<comp name="MaxDur" id="42" type="control::ConstFloat">
|
||||||
|
<prop name="meta" val="268566529"/>
|
||||||
|
<prop name="out" val="14400.0"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/K59 -->
|
||||||
|
<comp name="K59" id="43" type="control::ConstFloat">
|
||||||
|
<prop name="meta" val="369229825"/>
|
||||||
|
<prop name="out" val="59.0"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/K60 -->
|
||||||
|
<comp name="K60" id="44" type="control::ConstFloat">
|
||||||
|
<prop name="meta" val="469893121"/>
|
||||||
|
<prop name="out" val="60.0"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/K900 -->
|
||||||
|
<comp name="K900" id="45" type="control::ConstFloat">
|
||||||
|
<prop name="meta" val="570556417"/>
|
||||||
|
<prop name="out" val="900.0"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/K1800 -->
|
||||||
|
<comp name="K1800" id="46" type="control::ConstFloat">
|
||||||
|
<prop name="meta" val="671219713"/>
|
||||||
|
<prop name="out" val="1800.0"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/BootOn -->
|
||||||
|
<comp name="BootOn" id="47" type="control::ConstBool">
|
||||||
|
<prop name="meta" val="771883009"/>
|
||||||
|
<prop name="out" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/StartA -->
|
||||||
|
<comp name="StartA" id="48" type="ontrolTrigger::TrigActionInt">
|
||||||
|
<prop name="meta" val="34471937"/>
|
||||||
|
<prop name="componentId" val="40"/>
|
||||||
|
<prop name="slotId" val="1"/>
|
||||||
|
<prop name="trigger" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/EndA -->
|
||||||
|
<comp name="EndA" id="49" type="ontrolTrigger::TrigActionInt">
|
||||||
|
<prop name="meta" val="168689665"/>
|
||||||
|
<prop name="componentId" val="40"/>
|
||||||
|
<prop name="slotId" val="1"/>
|
||||||
|
<prop name="trigger" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/BootA -->
|
||||||
|
<comp name="BootA" id="50" type="ontrolTrigger::TrigActionInt">
|
||||||
|
<prop name="meta" val="302907393"/>
|
||||||
|
<prop name="componentId" val="40"/>
|
||||||
|
<prop name="slotId" val="1"/>
|
||||||
|
<prop name="trigger" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/CntF -->
|
||||||
|
<comp name="CntF" id="51" type="control::I2F">
|
||||||
|
<prop name="meta" val="437125121"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/Add59 -->
|
||||||
|
<comp name="Add59" id="52" type="control::Add2">
|
||||||
|
<prop name="meta" val="437911553"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/Div60 -->
|
||||||
|
<comp name="Div60" id="53" type="control::Div2">
|
||||||
|
<prop name="meta" val="438697985"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/MinI -->
|
||||||
|
<comp name="MinI" id="54" type="control::F2I">
|
||||||
|
<prop name="meta" val="439484417"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/MinF -->
|
||||||
|
<comp name="MinF" id="55" type="control::I2F">
|
||||||
|
<prop name="meta" val="440270849"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/Add15 -->
|
||||||
|
<comp name="Add15" id="56" type="control::Add2">
|
||||||
|
<prop name="meta" val="572129281"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/Ext15I -->
|
||||||
|
<comp name="Ext15I" id="57" type="control::F2I">
|
||||||
|
<prop name="meta" val="572915713"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/Ext15A -->
|
||||||
|
<comp name="Ext15A" id="58" type="ontrolTrigger::TrigActionInt">
|
||||||
|
<prop name="meta" val="574488577"/>
|
||||||
|
<prop name="componentId" val="40"/>
|
||||||
|
<prop name="slotId" val="1"/>
|
||||||
|
<prop name="trigger" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/Lim15 -->
|
||||||
|
<comp name="Lim15" id="59" type="control::Sub2">
|
||||||
|
<prop name="meta" val="706347009"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/Cmp15 -->
|
||||||
|
<comp name="Cmp15" id="60" type="control::Cmpr">
|
||||||
|
<prop name="meta" val="707133441"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/And15 -->
|
||||||
|
<comp name="And15" id="61" type="control::And2">
|
||||||
|
<prop name="meta" val="707919873"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/Add30 -->
|
||||||
|
<comp name="Add30" id="62" type="control::Add2">
|
||||||
|
<prop name="meta" val="840564737"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/Ext30I -->
|
||||||
|
<comp name="Ext30I" id="63" type="control::F2I">
|
||||||
|
<prop name="meta" val="841351169"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/Ext30A -->
|
||||||
|
<comp name="Ext30A" id="64" type="ontrolTrigger::TrigActionInt">
|
||||||
|
<prop name="meta" val="842924033"/>
|
||||||
|
<prop name="componentId" val="40"/>
|
||||||
|
<prop name="slotId" val="1"/>
|
||||||
|
<prop name="trigger" val="true"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/Lim30 -->
|
||||||
|
<comp name="Lim30" id="65" type="control::Sub2">
|
||||||
|
<prop name="meta" val="974782465"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/Cmp30 -->
|
||||||
|
<comp name="Cmp30" id="66" type="control::Cmpr">
|
||||||
|
<prop name="meta" val="975568897"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/And30 -->
|
||||||
|
<comp name="And30" id="67" type="control::And2">
|
||||||
|
<prop name="meta" val="976355329"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /meeting/PageSw -->
|
||||||
|
<comp name="PageSw" id="68" type="control::ISW">
|
||||||
|
<prop name="meta" val="35258369"/>
|
||||||
|
</comp>
|
||||||
|
</comp>
|
||||||
|
<!-- /lights -->
|
||||||
|
<comp name="lights" id="69" type="sys::Folder">
|
||||||
|
<prop name="meta" val="169738241"/>
|
||||||
|
<!-- /lights/Scene -->
|
||||||
|
<comp name="Scene" id="70" type="ontrolTrigger::TrigNumericSelect12">
|
||||||
|
<prop name="meta" val="34471937"/>
|
||||||
|
<prop name="value1" val="1.0"/>
|
||||||
|
<prop name="value2" val="2.0"/>
|
||||||
|
<prop name="value3" val="3.0"/>
|
||||||
|
<prop name="value4" val="4.0"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /lights/StartSc -->
|
||||||
|
<comp name="StartSc" id="71" type="control::Or2">
|
||||||
|
<prop name="meta" val="33685505"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /lights/S1 -->
|
||||||
|
<comp name="S1" id="72" type="control::ConstFloat">
|
||||||
|
<prop name="meta" val="201457665"/>
|
||||||
|
<prop name="out" val="1.0"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /lights/Is1 -->
|
||||||
|
<comp name="Is1" id="73" type="control::Cmpr">
|
||||||
|
<prop name="meta" val="203030529"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /lights/S2 -->
|
||||||
|
<comp name="S2" id="74" type="control::ConstFloat">
|
||||||
|
<prop name="meta" val="302120961"/>
|
||||||
|
<prop name="out" val="2.0"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /lights/Is2 -->
|
||||||
|
<comp name="Is2" id="75" type="control::Cmpr">
|
||||||
|
<prop name="meta" val="303693825"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /lights/S3 -->
|
||||||
|
<comp name="S3" id="76" type="control::ConstFloat">
|
||||||
|
<prop name="meta" val="402784257"/>
|
||||||
|
<prop name="out" val="3.0"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /lights/Is3 -->
|
||||||
|
<comp name="Is3" id="77" type="control::Cmpr">
|
||||||
|
<prop name="meta" val="404357121"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /lights/S4 -->
|
||||||
|
<comp name="S4" id="78" type="control::ConstFloat">
|
||||||
|
<prop name="meta" val="503447553"/>
|
||||||
|
<prop name="out" val="4.0"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /lights/Is4 -->
|
||||||
|
<comp name="Is4" id="79" type="control::Cmpr">
|
||||||
|
<prop name="meta" val="505020417"/>
|
||||||
|
</comp>
|
||||||
|
</comp>
|
||||||
|
<!-- /climate -->
|
||||||
|
<comp name="climate" id="80" type="sys::Folder">
|
||||||
|
<prop name="meta" val="303955969"/>
|
||||||
|
<!-- /climate/SpReg -->
|
||||||
|
<comp name="SpReg" id="81" type="ontrolControl::RegFloat">
|
||||||
|
<prop name="meta" val="33685505"/>
|
||||||
|
<prop name="address" val="1"/>
|
||||||
|
</comp>
|
||||||
|
<!-- /climate/SpUD -->
|
||||||
|
<comp name="SpUD" id="82" type="ontrolTrigger::TrigNumericUpDown">
|
||||||
|
<prop name="meta" val="34471937"/>
|
||||||
|
<prop name="delta" val="0.5"/>
|
||||||
|
<prop name="min" val="16.0"/>
|
||||||
|
<prop name="max" val="30.0"/>
|
||||||
|
</comp>
|
||||||
|
</comp>
|
||||||
|
</app>
|
||||||
|
<links>
|
||||||
|
<link from="/ui/Free/Start.touch" to="/meeting/StartA.in"/>
|
||||||
|
<link from="/meeting/DefDur.out" to="/meeting/StartA.value"/>
|
||||||
|
<link from="/ui/InUse/End.touch" to="/meeting/EndA.in"/>
|
||||||
|
<link from="/meeting/BootOn.out" to="/meeting/BootA.in"/>
|
||||||
|
<link from="/meeting/Timer.count" to="/meeting/CntF.in"/>
|
||||||
|
<link from="/meeting/CntF.out" to="/meeting/Add59.in1"/>
|
||||||
|
<link from="/meeting/K59.out" to="/meeting/Add59.in2"/>
|
||||||
|
<link from="/meeting/Add59.out" to="/meeting/Div60.in1"/>
|
||||||
|
<link from="/meeting/K60.out" to="/meeting/Div60.in2"/>
|
||||||
|
<link from="/meeting/Div60.out" to="/meeting/MinI.in"/>
|
||||||
|
<link from="/meeting/MinI.out" to="/meeting/MinF.in"/>
|
||||||
|
<link from="/meeting/MinF.out" to="/ui/InUse/Left.in"/>
|
||||||
|
<link from="/meeting/CntF.out" to="/meeting/Add15.in1"/>
|
||||||
|
<link from="/meeting/K900.out" to="/meeting/Add15.in2"/>
|
||||||
|
<link from="/meeting/Add15.out" to="/meeting/Ext15I.in"/>
|
||||||
|
<link from="/meeting/Ext15I.out" to="/meeting/Ext15A.value"/>
|
||||||
|
<link from="/meeting/MaxDur.out" to="/meeting/Lim15.in1"/>
|
||||||
|
<link from="/meeting/K900.out" to="/meeting/Lim15.in2"/>
|
||||||
|
<link from="/meeting/CntF.out" to="/meeting/Cmp15.x"/>
|
||||||
|
<link from="/meeting/Lim15.out" to="/meeting/Cmp15.y"/>
|
||||||
|
<link from="/meeting/Cmp15.xly" to="/ui/InUse/Ext15.in"/>
|
||||||
|
<link from="/ui/InUse/Ext15.touch" to="/meeting/And15.in1"/>
|
||||||
|
<link from="/meeting/Cmp15.xly" to="/meeting/And15.in2"/>
|
||||||
|
<link from="/meeting/And15.out" to="/meeting/Ext15A.in"/>
|
||||||
|
<link from="/meeting/CntF.out" to="/meeting/Add30.in1"/>
|
||||||
|
<link from="/meeting/K1800.out" to="/meeting/Add30.in2"/>
|
||||||
|
<link from="/meeting/Add30.out" to="/meeting/Ext30I.in"/>
|
||||||
|
<link from="/meeting/Ext30I.out" to="/meeting/Ext30A.value"/>
|
||||||
|
<link from="/meeting/MaxDur.out" to="/meeting/Lim30.in1"/>
|
||||||
|
<link from="/meeting/K1800.out" to="/meeting/Lim30.in2"/>
|
||||||
|
<link from="/meeting/CntF.out" to="/meeting/Cmp30.x"/>
|
||||||
|
<link from="/meeting/Lim30.out" to="/meeting/Cmp30.y"/>
|
||||||
|
<link from="/meeting/Cmp30.xly" to="/ui/InUse/Ext30.in"/>
|
||||||
|
<link from="/ui/InUse/Ext30.touch" to="/meeting/And30.in1"/>
|
||||||
|
<link from="/meeting/Cmp30.xly" to="/meeting/And30.in2"/>
|
||||||
|
<link from="/meeting/And30.out" to="/meeting/Ext30A.in"/>
|
||||||
|
<link from="/ui/Free.pageId" to="/meeting/PageSw.in1"/>
|
||||||
|
<link from="/ui/InUse.pageId" to="/meeting/PageSw.in2"/>
|
||||||
|
<link from="/meeting/Timer.out" to="/meeting/PageSw.s1"/>
|
||||||
|
<link from="/meeting/PageSw.out" to="/service/RionPlt/OxBase.homePageId"/>
|
||||||
|
<link from="/ui/Lights/Scene2.touch" to="/lights/StartSc.in1"/>
|
||||||
|
<link from="/ui/Free/Start.touch" to="/lights/StartSc.in2"/>
|
||||||
|
<link from="/lights/Scene.out" to="/lights/Is1.x"/>
|
||||||
|
<link from="/lights/S1.out" to="/lights/Is1.y"/>
|
||||||
|
<link from="/lights/Is1.xey" to="/ui/Lights/Scene1.in"/>
|
||||||
|
<link from="/ui/Lights/Scene1.touch" to="/lights/Scene.trigIn1"/>
|
||||||
|
<link from="/lights/Scene.out" to="/lights/Is2.x"/>
|
||||||
|
<link from="/lights/S2.out" to="/lights/Is2.y"/>
|
||||||
|
<link from="/lights/Is2.xey" to="/ui/Lights/Scene2.in"/>
|
||||||
|
<link from="/lights/StartSc.out" to="/lights/Scene.trigIn2"/>
|
||||||
|
<link from="/lights/Scene.out" to="/lights/Is3.x"/>
|
||||||
|
<link from="/lights/S3.out" to="/lights/Is3.y"/>
|
||||||
|
<link from="/lights/Is3.xey" to="/ui/Lights/Scene3.in"/>
|
||||||
|
<link from="/ui/Lights/Scene3.touch" to="/lights/Scene.trigIn3"/>
|
||||||
|
<link from="/lights/Scene.out" to="/lights/Is4.x"/>
|
||||||
|
<link from="/lights/S4.out" to="/lights/Is4.y"/>
|
||||||
|
<link from="/lights/Is4.xey" to="/ui/Lights/Scene4.in"/>
|
||||||
|
<link from="/ui/Lights/Scene4.touch" to="/lights/Scene.trigIn4"/>
|
||||||
|
<link from="/climate/SpReg.value" to="/climate/SpUD.value"/>
|
||||||
|
<link from="/climate/SpUD.out" to="/climate/SpReg.in"/>
|
||||||
|
<link from="/ui/Climate/Up.touch" to="/climate/SpUD.trigUp"/>
|
||||||
|
<link from="/ui/Climate/Down.touch" to="/climate/SpUD.trigDown"/>
|
||||||
|
<link from="/climate/SpUD.out" to="/ui/Climate/SetPt.in"/>
|
||||||
|
<link from="/service/RionPlt.roomTemperature" to="/ui/Free/RoomT.in"/>
|
||||||
|
<link from="/service/RionPlt.roomTemperature" to="/ui/InUse/RoomT.in"/>
|
||||||
|
<link from="/service/RionPlt.roomTemperature" to="/ui/Lights/RoomT.in"/>
|
||||||
|
<link from="/service/RionPlt.roomTemperature" to="/ui/Climate/RoomT.in"/>
|
||||||
|
<link from="/service/RionPlt.roomTemperature" to="/ui/Climate/RoomV.in"/>
|
||||||
|
<link from="/service/RionPlt.roomRh" to="/ui/Climate/HumV.in"/>
|
||||||
|
<link from="/ui/Free/TabLt.touch" to="/ui/Lights.trigThisPage"/>
|
||||||
|
<link from="/ui/Free/TabCl.touch" to="/ui/Climate.trigThisPage"/>
|
||||||
|
<link from="/ui/InUse/TabLt.touch" to="/ui/Lights.trigThisPage"/>
|
||||||
|
<link from="/ui/InUse/TabCl.touch" to="/ui/Climate.trigThisPage"/>
|
||||||
|
<link from="/ui/Lights/TabMt.touch" to="/ui/Lights.trigHome"/>
|
||||||
|
<link from="/ui/Lights/TabCl.touch" to="/ui/Climate.trigThisPage"/>
|
||||||
|
<link from="/ui/Climate/TabMt.touch" to="/ui/Climate.trigHome"/>
|
||||||
|
<link from="/ui/Climate/TabLt.touch" to="/ui/Lights.trigThisPage"/>
|
||||||
|
</links>
|
||||||
|
</sedonaApp>
|
||||||
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 632 B |
|
After Width: | Height: | Size: 675 B |
|
After Width: | Height: | Size: 791 B |
|
After Width: | Height: | Size: 837 B |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |