mirror of
https://github.com/IoTManagerProject/IoTManagerWeb.git
synced 2026-03-26 15:02:21 +03:00
Add layout and configuration handling in mock_backend; update WebSocketManager and App.svelte for improved state management
This commit is contained in:
@@ -112,6 +112,43 @@ def get_layout(device_slot: int) -> list:
|
|||||||
# Per-slot state for controls; keys = last segment of topic (id). Merged into get_params.
|
# Per-slot state for controls; keys = last segment of topic (id). Merged into get_params.
|
||||||
_params_state: dict = {} # slot -> { topic_id: value }
|
_params_state: dict = {} # slot -> { topic_id: value }
|
||||||
|
|
||||||
|
def _topic_id(topic: str) -> str:
|
||||||
|
"""Last segment of topic (e.g. /mock/d0/relay1 -> relay1)."""
|
||||||
|
if not topic or "/" not in topic:
|
||||||
|
return topic or ""
|
||||||
|
return topic.rstrip("/").split("/")[-1]
|
||||||
|
|
||||||
|
|
||||||
|
def _ensure_params_for_layout(slot: int, layout: list) -> None:
|
||||||
|
"""Add missing topic ids from layout to _params_state[slot] so added widgets get data."""
|
||||||
|
state = _get_params_state(slot)
|
||||||
|
for w in layout:
|
||||||
|
topic = w.get("topic") or ""
|
||||||
|
wid = _topic_id(topic)
|
||||||
|
if not wid or wid in state:
|
||||||
|
continue
|
||||||
|
widget_type = (w.get("widget") or "").lower()
|
||||||
|
if "chart" in widget_type:
|
||||||
|
state[wid] = ""
|
||||||
|
elif "toggle" in widget_type:
|
||||||
|
state[wid] = "0"
|
||||||
|
elif "range" in widget_type:
|
||||||
|
state[wid] = str(w.get("min", 0) if isinstance(w.get("min"), (int, float)) else 50)
|
||||||
|
elif "input" in widget_type:
|
||||||
|
itype = w.get("type") or "number"
|
||||||
|
if itype == "number":
|
||||||
|
state[wid] = "20"
|
||||||
|
elif itype == "text":
|
||||||
|
state[wid] = "Room"
|
||||||
|
elif itype == "time":
|
||||||
|
state[wid] = "08:00"
|
||||||
|
elif itype == "date":
|
||||||
|
state[wid] = "2025-01-01"
|
||||||
|
else:
|
||||||
|
state[wid] = "0"
|
||||||
|
else:
|
||||||
|
state[wid] = "0"
|
||||||
|
|
||||||
|
|
||||||
def _get_params_state(slot: int) -> dict:
|
def _get_params_state(slot: int) -> dict:
|
||||||
if slot not in _params_state:
|
if slot not in _params_state:
|
||||||
@@ -126,9 +163,12 @@ def _get_params_state(slot: int) -> dict:
|
|||||||
return _params_state[slot]
|
return _params_state[slot]
|
||||||
|
|
||||||
|
|
||||||
def get_params(device_slot: int) -> dict:
|
def get_params(device_slot: int, layout: Optional[list] = None) -> dict:
|
||||||
"""Params JSON: topic id -> value (for layout widgets)."""
|
"""Params JSON: topic id -> value (for layout widgets). If layout given, ensure all its topic ids have state."""
|
||||||
return dict(_get_params_state(device_slot))
|
state = _get_params_state(device_slot)
|
||||||
|
if layout:
|
||||||
|
_ensure_params_for_layout(device_slot, layout)
|
||||||
|
return dict(state)
|
||||||
|
|
||||||
|
|
||||||
def get_chart_data(topic: str, points: int = 20, base_val: float = 20.0, amplitude: float = 5.0) -> dict:
|
def get_chart_data(topic: str, points: int = 20, base_val: float = 20.0, amplitude: float = 5.0) -> dict:
|
||||||
@@ -241,15 +281,41 @@ def get_devlist(host: str) -> list:
|
|||||||
|
|
||||||
# Saved device list from /tsil| (reversed "list"). When udps=0 backend returns from "file", else from "heap" (default).
|
# Saved device list from /tsil| (reversed "list"). When udps=0 backend returns from "file", else from "heap" (default).
|
||||||
_saved_devlist: Optional[list] = None
|
_saved_devlist: Optional[list] = None
|
||||||
|
# Configurator: saved layout/config/scenario per slot (from /tuoyal|, /gifnoc|, /oiranecs|)
|
||||||
|
_saved_layout: dict = {} # slot -> list (layout JSON array)
|
||||||
|
_saved_config: dict = {} # slot -> list (config JSON array)
|
||||||
|
_saved_scenario: dict = {} # slot -> str (scenario text)
|
||||||
|
|
||||||
|
|
||||||
def get_items_json() -> list:
|
def get_items_json() -> list:
|
||||||
"""Minimal items list."""
|
"""Items list covering all widget types (anydata, chart, toggle, range, input)."""
|
||||||
return [
|
return [
|
||||||
{"name": "Выберите элемент", "num": 0},
|
{"name": "Выберите элемент", "num": 0},
|
||||||
{"header": "virtual_elments"},
|
{"header": "virtual_elments"},
|
||||||
{"global": 0, "name": "Temp", "type": "Reading", "subtype": "AnalogAdc", "id": "temp", "widget": "anydataTmp", "page": "Сенсоры", "descr": "Temperature", "num": 1},
|
# anydata
|
||||||
{"global": 0, "name": "Graph", "type": "Writing", "subtype": "Loging", "id": "log", "widget": "chart2", "page": "Графики 1", "descr": "Temperature", "num": 2, "points": 100},
|
{"global": 0, "name": "Text", "type": "Reading", "subtype": "Variable", "id": "text", "widget": "anydataDef", "page": "Сенсоры", "descr": "Text", "num": 1},
|
||||||
|
{"global": 0, "name": "Temperature", "type": "Reading", "subtype": "AnalogAdc", "id": "temp", "widget": "anydataTmp", "page": "Сенсоры", "descr": "Temperature", "num": 2},
|
||||||
|
{"global": 0, "name": "Humidity", "type": "Reading", "subtype": "Variable", "id": "hum", "widget": "anydataDef", "page": "Сенсоры", "descr": "Humidity", "num": 3},
|
||||||
|
{"global": 0, "name": "Pressure", "type": "Reading", "subtype": "Variable", "id": "pressure", "widget": "anydataDef", "page": "Сенсоры", "descr": "Pressure", "num": 4},
|
||||||
|
{"global": 0, "name": "Voltage", "type": "Reading", "subtype": "Variable", "id": "voltage", "widget": "anydataDef", "page": "Сенсоры", "descr": "Voltage", "num": 5},
|
||||||
|
{"global": 0, "name": "Power", "type": "Reading", "subtype": "Variable", "id": "power", "widget": "anydataDef", "page": "Сенсоры", "descr": "Power", "num": 6},
|
||||||
|
{"global": 0, "name": "RSSI", "type": "Reading", "subtype": "Variable", "id": "rssi", "widget": "anydataDef", "page": "Сенсоры", "descr": "WiFi RSSI", "num": 7},
|
||||||
|
# chart
|
||||||
|
{"global": 0, "name": "Chart line", "type": "Writing", "subtype": "Loging", "id": "log", "widget": "chart2", "page": "Графики 1", "descr": "Chart", "num": 10, "points": 100},
|
||||||
|
{"global": 0, "name": "Chart bar", "type": "Writing", "subtype": "Loging", "id": "logBar", "widget": "chartBar", "page": "Графики 2", "descr": "Bar chart", "num": 11, "points": 100},
|
||||||
|
# toggle
|
||||||
|
{"global": 0, "name": "Toggle", "type": "Writing", "subtype": "ButtonOut", "id": "relay", "widget": "toggleDef", "page": "Реле и свет", "descr": "Relay", "num": 20},
|
||||||
|
{"global": 0, "name": "Light", "type": "Writing", "subtype": "ButtonOut", "id": "light", "widget": "toggleDef", "page": "Реле и свет", "descr": "Light", "num": 21},
|
||||||
|
{"global": 0, "name": "Fan", "type": "Writing", "subtype": "ButtonOut", "id": "fan", "widget": "toggleDef", "page": "Реле и свет", "descr": "Fan", "num": 22},
|
||||||
|
# range
|
||||||
|
{"global": 0, "name": "Dimmer", "type": "Writing", "subtype": "Variable", "id": "dimmer", "widget": "rangeDef", "page": "Параметры", "descr": "Dimmer", "num": 30},
|
||||||
|
{"global": 0, "name": "Volume", "type": "Writing", "subtype": "Variable", "id": "volume", "widget": "rangeDef", "page": "Параметры", "descr": "Volume", "num": 31},
|
||||||
|
{"global": 0, "name": "Setpoint", "type": "Writing", "subtype": "Variable", "id": "setpoint", "widget": "rangeDef", "page": "Параметры", "descr": "Setpoint", "num": 32},
|
||||||
|
# input
|
||||||
|
{"global": 0, "name": "Input number", "type": "Reading", "subtype": "Variable", "id": "settemp", "widget": "inputNumber", "page": "Параметры", "descr": "Number", "num": 40},
|
||||||
|
{"global": 0, "name": "Input text", "type": "Reading", "subtype": "Variable", "id": "label", "widget": "inputText", "page": "Параметры", "descr": "Label", "num": 41},
|
||||||
|
{"global": 0, "name": "Input time", "type": "Reading", "subtype": "Variable", "id": "alarmtime", "widget": "inputTime", "page": "Параметры", "descr": "Time", "num": 42},
|
||||||
|
{"global": 0, "name": "Input date", "type": "Reading", "subtype": "Variable", "id": "eventdate", "widget": "inputDate", "page": "Параметры", "descr": "Date", "num": 43},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -305,11 +371,12 @@ def assign_slot() -> int:
|
|||||||
|
|
||||||
async def handle_ws_message(ws, message: str, slot: int) -> None:
|
async def handle_ws_message(ws, message: str, slot: int) -> None:
|
||||||
"""Handle text command from frontend and send responses."""
|
"""Handle text command from frontend and send responses."""
|
||||||
global _saved_devlist
|
global _saved_devlist, _saved_layout, _saved_config, _saved_scenario
|
||||||
if "|" not in message:
|
if "|" not in message:
|
||||||
return
|
return
|
||||||
cmd = message.split("|")[0] + "|"
|
cmd = message.split("|")[0] + "|"
|
||||||
|
|
||||||
|
# Heartbeat/ping: same as original IoTManager WsServer.cpp — reply immediately so frontend can measure RTT (device.ping)
|
||||||
if cmd == "/tst|":
|
if cmd == "/tst|":
|
||||||
await ws.send("/tstr|")
|
await ws.send("/tstr|")
|
||||||
return
|
return
|
||||||
@@ -322,19 +389,20 @@ async def handle_ws_message(ws, message: str, slot: int) -> None:
|
|||||||
return ws.send(make_binary_frame(header, payload))
|
return ws.send(make_binary_frame(header, payload))
|
||||||
|
|
||||||
if cmd == "/|":
|
if cmd == "/|":
|
||||||
layout = get_layout(slot)
|
layout = _saved_layout.get(slot) if slot in _saved_layout else get_layout(slot)
|
||||||
await send_bin("layout", json.dumps(layout))
|
await send_bin("layout", json.dumps(layout))
|
||||||
# Send params immediately so front has data (front also requests /params| after layout; both trigger updateAllStatuses)
|
# Send params immediately so front has data (incl. for saved-layout widgets)
|
||||||
await send_bin("params", json.dumps(get_params(slot)))
|
await send_bin("params", json.dumps(get_params(slot, layout)))
|
||||||
return
|
return
|
||||||
|
|
||||||
if cmd == "/params|":
|
if cmd == "/params|":
|
||||||
params = get_params(slot)
|
layout = _saved_layout.get(slot) if slot in _saved_layout else get_layout(slot)
|
||||||
|
params = get_params(slot, layout)
|
||||||
await send_bin("params", json.dumps(params))
|
await send_bin("params", json.dumps(params))
|
||||||
return
|
return
|
||||||
|
|
||||||
if cmd == "/charts|":
|
if cmd == "/charts|":
|
||||||
layout = get_layout(slot)
|
layout = _saved_layout.get(slot) if slot in _saved_layout else get_layout(slot)
|
||||||
for w in layout:
|
for w in layout:
|
||||||
if w.get("widget") != "chart" or not w.get("topic"):
|
if w.get("widget") != "chart" or not w.get("topic"):
|
||||||
continue
|
continue
|
||||||
@@ -352,8 +420,10 @@ async def handle_ws_message(ws, message: str, slot: int) -> None:
|
|||||||
if cmd == "/config|":
|
if cmd == "/config|":
|
||||||
await send_bin("itemsj", json.dumps(get_items_json()))
|
await send_bin("itemsj", json.dumps(get_items_json()))
|
||||||
await send_bin("widget", json.dumps(get_widgets_json()))
|
await send_bin("widget", json.dumps(get_widgets_json()))
|
||||||
await send_bin("config", json.dumps(get_config_json()))
|
config_data = _saved_config[slot] if slot in _saved_config else get_config_json()
|
||||||
await send_bin("scenar", "// mock scenario\n")
|
await send_bin("config", json.dumps(config_data))
|
||||||
|
scenario_txt = _saved_scenario.get(slot, "// mock scenario\n")
|
||||||
|
await send_bin("scenar", scenario_txt if isinstance(scenario_txt, str) else "// mock scenario\n")
|
||||||
await send_bin("settin", json.dumps(get_settings(HTTP_HOST, HTTP_PORT, slot)))
|
await send_bin("settin", json.dumps(get_settings(HTTP_HOST, HTTP_PORT, slot)))
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -442,8 +512,34 @@ async def handle_ws_message(ws, message: str, slot: int) -> None:
|
|||||||
# Reboot (no-op in mock)
|
# Reboot (no-op in mock)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Save commands: no-op
|
# Save configurator data (layout, config, scenario) per slot
|
||||||
if cmd in ("/gifnoc|", "/tuoyal|", "/oiranecs|"):
|
if cmd == "/tuoyal|":
|
||||||
|
payload = message[len(cmd) :].strip()
|
||||||
|
if payload:
|
||||||
|
try:
|
||||||
|
data = json.loads(payload)
|
||||||
|
if isinstance(data, list):
|
||||||
|
_saved_layout[slot] = data
|
||||||
|
_ensure_params_for_layout(slot, data)
|
||||||
|
print(f"[mock] layout saved for slot {slot}, {len(data)} widget(s)")
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
pass
|
||||||
|
return
|
||||||
|
if cmd == "/gifnoc|":
|
||||||
|
payload = message[len(cmd) :].strip()
|
||||||
|
if payload:
|
||||||
|
try:
|
||||||
|
data = json.loads(payload)
|
||||||
|
if isinstance(data, list):
|
||||||
|
_saved_config[slot] = data
|
||||||
|
print(f"[mock] config saved for slot {slot}, {len(data)} item(s)")
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
pass
|
||||||
|
return
|
||||||
|
if cmd == "/oiranecs|":
|
||||||
|
payload = message[len(cmd) :].strip()
|
||||||
|
_saved_scenario[slot] = payload if payload is not None else ""
|
||||||
|
print(f"[mock] scenario saved for slot {slot}")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,9 @@
|
|||||||
let versionsList = {};
|
let versionsList = {};
|
||||||
let choosingVersion = undefined;
|
let choosingVersion = undefined;
|
||||||
let selectedWs = 0;
|
let selectedWs = 0;
|
||||||
|
let socketConnected = false;
|
||||||
|
let percent = 0;
|
||||||
|
let remainingTimeout = 60;
|
||||||
|
|
||||||
let opened = true;
|
let opened = true;
|
||||||
let preventMove = false;
|
let preventMove = false;
|
||||||
@@ -67,7 +70,6 @@
|
|||||||
let showInput = false;
|
let showInput = false;
|
||||||
|
|
||||||
$: currentPageName = wsManager.currentPageName;
|
$: currentPageName = wsManager.currentPageName;
|
||||||
$: remainingTimeout = wsManager.remainingTimeout;
|
|
||||||
$: wsManager.choosingVersion = choosingVersion;
|
$: wsManager.choosingVersion = choosingVersion;
|
||||||
|
|
||||||
router.subscribe(handleNavigation);
|
router.subscribe(handleNavigation);
|
||||||
@@ -148,6 +150,9 @@
|
|||||||
opened = screenSize > 900;
|
opened = screenSize > 900;
|
||||||
wsManager.firstDevListRequest = true;
|
wsManager.firstDevListRequest = true;
|
||||||
wsManager.selectedDeviceDataRefresh();
|
wsManager.selectedDeviceDataRefresh();
|
||||||
|
socketConnected = wsManager.socketConnected;
|
||||||
|
percent = wsManager.percent;
|
||||||
|
remainingTimeout = wsManager.remainingTimeout;
|
||||||
wsManager.connectToAllDevices();
|
wsManager.connectToAllDevices();
|
||||||
wsManager.startReconnectTask();
|
wsManager.startReconnectTask();
|
||||||
|
|
||||||
@@ -155,9 +160,16 @@
|
|||||||
layoutJson = data.layoutJson || [];
|
layoutJson = data.layoutJson || [];
|
||||||
pages = data.pages || [];
|
pages = data.pages || [];
|
||||||
if (data.pageReady) pageReady = data.pageReady;
|
if (data.pageReady) pageReady = data.pageReady;
|
||||||
|
if (data.configJson !== undefined) configJson = data.configJson;
|
||||||
|
if (data.scenarioTxt !== undefined) scenarioTxt = data.scenarioTxt;
|
||||||
});
|
});
|
||||||
eventEmitter.on("deviceListUpdated", () => {
|
eventEmitter.on("deviceListUpdated", () => {
|
||||||
deviceList = wsManager.deviceList;
|
deviceList = [...wsManager.deviceList];
|
||||||
|
socketConnected = wsManager.socketConnected;
|
||||||
|
});
|
||||||
|
eventEmitter.on("reconnectTick", (data) => {
|
||||||
|
percent = data.percent;
|
||||||
|
remainingTimeout = data.remainingTimeout;
|
||||||
});
|
});
|
||||||
eventEmitter.on("configUpdated", (data) => {
|
eventEmitter.on("configUpdated", (data) => {
|
||||||
configJson = data.configJson || [];
|
configJson = data.configJson || [];
|
||||||
@@ -190,7 +202,7 @@
|
|||||||
{deviceList}
|
{deviceList}
|
||||||
bind:selectedWs
|
bind:selectedWs
|
||||||
showDropdown={wsManager.currentPageName !== "/|" && wsManager.currentPageName !== "/list|"}
|
showDropdown={wsManager.currentPageName !== "/|" && wsManager.currentPageName !== "/list|"}
|
||||||
socketConnected={wsManager.socketConnected}
|
{socketConnected}
|
||||||
{devicesDropdownChange}
|
{devicesDropdownChange}
|
||||||
/>
|
/>
|
||||||
<AppNav bind:opened onCheck={() => onCheck()} userdata={wsManager.userdata} />
|
<AppNav bind:opened onCheck={() => onCheck()} userdata={wsManager.userdata} />
|
||||||
@@ -198,7 +210,7 @@
|
|||||||
<main class="flex-1 overflow-y-auto p-0 {opened === true && !preventMove ? 'ml-36' : 'ml-0'}">
|
<main class="flex-1 overflow-y-auto p-0 {opened === true && !preventMove ? 'ml-36' : 'ml-0'}">
|
||||||
<ul class="menu__main">
|
<ul class="menu__main">
|
||||||
<div class="bg-cover pt-0 px-4">
|
<div class="bg-cover pt-0 px-4">
|
||||||
{#if !wsManager.socketConnected && wsManager.currentPageName !== "/|"}
|
{#if !socketConnected && wsManager.currentPageName !== "/|"}
|
||||||
<Alarm title="Подключение через {remainingTimeout} сек." />
|
<Alarm title="Подключение через {remainingTimeout} сек." />
|
||||||
{:else}
|
{:else}
|
||||||
<Route path="/">
|
<Route path="/">
|
||||||
@@ -211,7 +223,7 @@
|
|||||||
<ConnectionPage show={pageReady.connection} rebootEsp={() => wsManager.rebootEsp()} ssidClick={() => wsManager.ssidClick()} saveSett={() => { wsManager.settingsJson = settingsJson; wsManager.saveSett(); }} saveMqtt={() => { wsManager.settingsJson = settingsJson; wsManager.saveMqtt(); }} {settingsJson} {errorsJson} {ssidJson} />
|
<ConnectionPage show={pageReady.connection} rebootEsp={() => wsManager.rebootEsp()} ssidClick={() => wsManager.ssidClick()} saveSett={() => { wsManager.settingsJson = settingsJson; wsManager.saveSett(); }} saveMqtt={() => { wsManager.settingsJson = settingsJson; wsManager.saveMqtt(); }} {settingsJson} {errorsJson} {ssidJson} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/list">
|
<Route path="/list">
|
||||||
<ListPage show={pageReady.list} deviceList={deviceList} settingsJson={wsManager.settingsJson} saveSett={() => wsManager.saveSett()} rebootEsp={() => wsManager.rebootEsp()} showInput={showInput} addDevInList={() => wsManager.addDevInList()} newDevice={wsManager.newDevice} sendToAllDevices={(msg) => wsManager.sendToAllDevices(msg)} saveList={() => wsManager.saveList()} percent={wsManager.percent} devListOverride={() => wsManager.devListOverride()} applicationReboot={() => wsManager.applicationReboot()} />
|
<ListPage show={pageReady.list} deviceList={deviceList} settingsJson={wsManager.settingsJson} saveSett={() => wsManager.saveSett()} rebootEsp={() => wsManager.rebootEsp()} showInput={showInput} addDevInList={() => wsManager.addDevInList()} newDevice={wsManager.newDevice} sendToAllDevices={(msg) => wsManager.sendToAllDevices(msg)} saveList={() => wsManager.saveList()} {percent} devListOverride={() => wsManager.devListOverride()} applicationReboot={() => wsManager.applicationReboot()} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/system">
|
<Route path="/system">
|
||||||
<SystemPage show={pageReady.system} errorsJson={wsManager.errorsJson} settingsJson={wsManager.settingsJson} saveSett={() => wsManager.saveSett()} rebootEsp={() => wsManager.rebootEsp()} cleanLogs={() => wsManager.cleanLogs()} cancelAlarm={(alarmKey) => wsManager.cancelAlarm(alarmKey)} versionsList={versionsList} bind:choosingVersion coreMessages={wsManager.coreMessages} />
|
<SystemPage show={pageReady.system} errorsJson={wsManager.errorsJson} settingsJson={wsManager.settingsJson} saveSett={() => wsManager.saveSett()} rebootEsp={() => wsManager.rebootEsp()} cleanLogs={() => wsManager.cleanLogs()} cancelAlarm={(alarmKey) => wsManager.cancelAlarm(alarmKey)} versionsList={versionsList} bind:choosingVersion coreMessages={wsManager.coreMessages} />
|
||||||
|
|||||||
@@ -149,7 +149,13 @@ export default class WebSocketManager {
|
|||||||
setRemainingTimeout: (v) => (this.remainingTimeout = v),
|
setRemainingTimeout: (v) => (this.remainingTimeout = v),
|
||||||
reconnectTimeout: this.reconnectTimeout,
|
reconnectTimeout: this.reconnectTimeout,
|
||||||
getPreventReconnect: () => this.preventReconnect,
|
getPreventReconnect: () => this.preventReconnect,
|
||||||
setPercent: (v) => (this.percent = v),
|
setPercent: (v) => {
|
||||||
|
this.percent = v;
|
||||||
|
eventEmitter.emit("reconnectTick", {
|
||||||
|
percent: this.percent,
|
||||||
|
remainingTimeout: this.remainingTimeout,
|
||||||
|
});
|
||||||
|
},
|
||||||
getRebootOrUpdateProcess: () => this.rebootOrUpdateProcess,
|
getRebootOrUpdateProcess: () => this.rebootOrUpdateProcess,
|
||||||
setRebootOrUpdateProcess: (v) => (this.rebootOrUpdateProcess = v),
|
setRebootOrUpdateProcess: (v) => (this.rebootOrUpdateProcess = v),
|
||||||
getSocketConnected: () => this.socketConnected,
|
getSocketConnected: () => this.socketConnected,
|
||||||
@@ -321,6 +327,8 @@ export default class WebSocketManager {
|
|||||||
layoutJson: this.layoutJson,
|
layoutJson: this.layoutJson,
|
||||||
pages: this.pages,
|
pages: this.pages,
|
||||||
pageReady: { ...this.pageReady },
|
pageReady: { ...this.pageReady },
|
||||||
|
configJson: this.configJson,
|
||||||
|
scenarioTxt: this.scenarioTxt,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user