[ { "id": "12f41a7b538c40db", "type": "tab", "label": "RotatingMachine Integration", "disabled": false, "info": "Manual integration-style scenario builder for rotatingMachine" }, { "id": "ui_base_rm_int", "type": "ui-base", "name": "EVOLV Demo", "path": "/dashboard", "includeClientData": true, "acceptsClientConfig": [ "ui-notification", "ui-control" ], "showPathInSidebar": false, "headerContent": "page", "navigationStyle": "default", "titleBarStyle": "default" }, { "id": "ui_theme_rm_int", "type": "ui-theme", "name": "EVOLV Integration Theme", "colors": { "surface": "#ffffff", "primary": "#0094ce", "bgPage": "#eeeeee", "groupBg": "#ffffff", "groupOutline": "#cccccc" }, "sizes": { "density": "default", "pagePadding": "12px", "groupGap": "12px", "groupBorderRadius": "4px", "widgetGap": "12px" } }, { "id": "ui_page_rm_int", "type": "ui-page", "name": "RotatingMachine Integration", "ui": "ui_base_rm_int", "path": "/rotating-machine-integration", "icon": "lan", "layout": "grid", "theme": "ui_theme_rm_int", "breakpoints": [ { "name": "Default", "px": "0", "cols": "12" } ], "order": 2, "className": "" }, { "id": "ui_group_rm_int_ctrl", "type": "ui-group", "name": "Control Sequences", "page": "ui_page_rm_int", "width": "6", "height": "1", "order": 1, "showTitle": true, "className": "" }, { "id": "ui_group_rm_int_sim", "type": "ui-group", "name": "Process Simulation", "page": "ui_page_rm_int", "width": "6", "height": "1", "order": 2, "showTitle": true, "className": "" }, { "id": "ui_group_rm_int_vis", "type": "ui-group", "name": "Observed Behaviour", "page": "ui_page_rm_int", "width": "12", "height": "20", "order": 3, "showTitle": true, "className": "" }, { "id": "rm_node_int", "type": "rotatingMachine", "z": "12f41a7b538c40db", "name": "RM Integration", "speed": "1", "startup": "3", "warmup": "3", "shutdown": "3", "cooldown": "3", "movementMode": "staticspeed", "machineCurve": "", "uuid": "", "supplier": "hidrostal", "category": "machine", "assetType": "pump-centrifugal", "model": "hidrostal-H05K-S03R", "unit": "m3/h", "enableLog": false, "logLevel": "error", "positionVsParent": "atEquipment", "x": 1040, "y": 360, "wires": [ [ "rm_int_parse" ], [ "rm_int_debug_influx" ], [ "rm_int_debug_parent" ] ], "hasDistance": false }, { "id": "rm_int_startup", "type": "ui-button", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_ctrl", "name": "Startup", "label": "Startup", "order": 1, "width": "3", "height": "1", "icon": "play_arrow", "payload": "startup", "payloadType": "str", "x": 190, "y": 120, "wires": [ [ "rm_int_exec_seq" ] ] }, { "id": "rm_int_shutdown", "type": "ui-button", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_ctrl", "name": "Shutdown", "label": "Shutdown", "order": 2, "width": "3", "height": "1", "icon": "stop", "payload": "shutdown", "payloadType": "str", "x": 190, "y": 160, "wires": [ [ "rm_int_exec_seq" ] ] }, { "id": "rm_int_maint", "type": "ui-button", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_ctrl", "name": "Maintenance", "label": "Enter Maintenance", "order": 3, "width": "6", "height": "1", "icon": "build", "payload": "entermaintenance", "payloadType": "str", "x": 220, "y": 200, "wires": [ [ "rm_int_exec_seq" ] ] }, { "id": "rm_int_exec_seq", "type": "function", "z": "12f41a7b538c40db", "name": "Build execSequence", "func": "msg.topic = 'execSequence';\nmsg.payload = {source:'GUI', action:'execSequence', parameter: msg.payload};\nreturn msg;", "outputs": 1, "x": 450, "y": 160, "wires": [ [ "rm_node_int" ] ] }, { "id": "rm_int_setpoint", "type": "ui-number-input", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_ctrl", "name": "Setpoint", "label": "Setpoint %", "order": 4, "width": "6", "height": "1", "passthru": true, "min": 0, "max": 100, "step": 1, "x": 190, "y": 260, "wires": [ [ "rm_int_exec_movement", "rm_int_ctrl_setpoint_for_chart" ] ] }, { "id": "rm_int_exec_movement", "type": "function", "z": "12f41a7b538c40db", "name": "Build execMovement", "func": "msg.topic='execMovement';\nmsg.payload={source:'GUI', action:'execMovement', setpoint:Number(msg.payload)};\nreturn msg;", "outputs": 1, "x": 460, "y": 260, "wires": [ [ "rm_node_int" ] ] }, { "id": "rm_int_flow_target", "type": "ui-number-input", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_sim", "name": "Flow target", "label": "Flow target (m3/h)", "order": 1, "width": "6", "height": "1", "passthru": true, "min": 0, "max": 1000, "step": 5, "x": 200, "y": 340, "wires": [ [ "rm_int_flow_move", "rm_int_flow_setpoint_for_chart" ] ] }, { "id": "rm_int_flow_move", "type": "function", "z": "12f41a7b538c40db", "name": "Build flowMovement", "func": "msg.topic='flowMovement';\nmsg.payload={source:'GUI', action:'flowMovement', setpoint:Number(msg.payload)};\nreturn msg;", "outputs": 1, "x": 450, "y": 340, "wires": [ [ "rm_node_int" ] ] }, { "id": "rm_int_pressure_up", "type": "ui-number-input", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_sim", "name": "Upstream Pressure", "label": "Upstream pressure (mbar)", "order": 2, "width": "6", "height": "1", "passthru": true, "min": 0, "max": 3000, "step": 10, "x": 210, "y": 390, "wires": [ [ "rm_int_sim_up" ] ] }, { "id": "rm_int_pressure_down", "type": "ui-number-input", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_sim", "name": "Downstream Pressure", "label": "Downstream pressure (mbar)", "order": 3, "width": "6", "height": "1", "passthru": true, "min": 0, "max": 3000, "step": 10, "x": 220, "y": 430, "wires": [ [ "rm_int_sim_down" ] ] }, { "id": "rm_int_sim_up", "type": "function", "z": "12f41a7b538c40db", "name": "simulate upstream pressure", "func": "msg.topic='simulateMeasurement';\nmsg.payload={type:'pressure', position:'upstream', value:Number(msg.payload), unit:'mbar'};\nreturn msg;", "outputs": 1, "x": 500, "y": 390, "wires": [ [ "rm_node_int" ] ] }, { "id": "rm_int_sim_down", "type": "function", "z": "12f41a7b538c40db", "name": "simulate downstream pressure", "func": "msg.topic='simulateMeasurement';\nmsg.payload={type:'pressure', position:'downstream', value:Number(msg.payload), unit:'mbar'};\nreturn msg;", "outputs": 1, "x": 510, "y": 430, "wires": [ [ "rm_node_int" ] ] }, { "id": "rm_int_parse", "type": "function", "z": "12f41a7b538c40db", "name": "Parse RM output", "func": "const incoming = (msg && msg.payload && typeof msg.payload === 'object') ? msg.payload : {};\nconst lastPayload = context.get('lastPayload') || {};\nconst merged = { ...lastPayload, ...incoming };\ncontext.set('lastPayload', merged);\n\nconst cache = context.get('metricCache') || {\n flow: 0,\n power: 0,\n nCog: 0,\n ctrl: 0,\n stateCode: 0,\n state: 'idle',\n mode: 'auto',\n runtime: 0,\n moveTimeleft: 0,\n maintenanceTime: 0\n};\n\nconst pickNumber = (...keys) => {\n for (const key of keys) {\n const value = Number(merged[key]);\n if (Number.isFinite(value)) return value;\n }\n return null;\n};\n\nconst pickString = (key, fallback = null) => {\n const value = merged[key];\n if (value === undefined || value === null || value === '') return fallback;\n return String(value);\n};\n\nconst flow = pickNumber('flow.predicted.downstream.default', 'flow.predicted.downstream');\nconst power = pickNumber('power.predicted.atequipment.default', 'power.predicted.atequipment', 'power.predicted.atEquipment.default', 'power.predicted.atEquipment');\nconst nCog = pickNumber('NCogPercent', 'NCog');\nconst ctrl = pickNumber('ctrl', 'ctrl.predicted.atequipment.default', 'ctrl.predicted.atequipment', 'ctrl.predicted.atEquipment.default', 'ctrl.predicted.atEquipment');\nconst runtime = pickNumber('runtime');\nconst moveTimeleft = pickNumber('moveTimeleft');\nconst maintenanceTime = pickNumber('maintenanceTime');\nconst state = pickString('state', cache.state);\nconst mode = pickString('mode', cache.mode);\n\nconst stateCodeMap = { off: 0, idle: 1, starting: 2, warmingup: 3, operational: 4, accelerating: 5, decelerating: 6, stopping: 7, coolingdown: 8, maintenance: 9 };\nconst stateCode = stateCodeMap[state] ?? cache.stateCode;\n\nif (flow !== null) cache.flow = flow;\nif (power !== null) cache.power = power;\nif (nCog !== null) cache.nCog = nCog;\nif (ctrl !== null) cache.ctrl = ctrl;\nif (runtime !== null) cache.runtime = runtime;\nif (moveTimeleft !== null) cache.moveTimeleft = moveTimeleft;\nif (maintenanceTime !== null) cache.maintenanceTime = maintenanceTime;\ncache.state = state;\ncache.mode = mode;\ncache.stateCode = stateCode;\ncontext.set('metricCache', cache);\n\nreturn [\n { topic: 'actual_flow', payload: cache.flow },\n { topic: 'predicted_power', payload: cache.power },\n { topic: 'nCog', payload: cache.nCog },\n { topic: 'actual_ctrl', payload: cache.ctrl },\n { topic: 'stateCode', payload: cache.stateCode },\n { payload: JSON.stringify({ state: cache.state, mode: cache.mode, ctrl: cache.ctrl, runtime: cache.runtime, moveTimeleft: cache.moveTimeleft, maintenanceTime: cache.maintenanceTime }) }\n];", "outputs": 6, "x": 1260, "y": 360, "wires": [ [ "rm_int_chart_flow" ], [ "rm_int_chart_power" ], [ "rm_int_chart_nCog" ], [ "rm_int_chart_ctrl" ], [ "rm_int_chart_statecode" ], [ "rm_int_state_text" ] ] }, { "id": "rm_int_chart_flow", "type": "ui-chart", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_vis", "name": "Flow", "label": "Flow (m3/h)", "order": 1, "width": 12, "height": 4, "chartType": "line", "xAxisType": "time", "yAxisLabel": "m3/h", "removeOlder": "1", "removeOlderUnit": "3600", "x": 1510, "y": 280, "wires": [], "showLegend": true }, { "id": "rm_int_chart_power", "type": "ui-chart", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_vis", "name": "Power", "label": "Power (kW)", "order": 2, "width": 12, "height": 4, "chartType": "line", "xAxisType": "time", "yAxisLabel": "kW", "removeOlder": "1", "removeOlderUnit": "3600", "x": 1510, "y": 340, "wires": [], "showLegend": true }, { "id": "rm_int_chart_nCog", "type": "ui-chart", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_vis", "name": "NCog", "label": "NCog (%)", "order": 3, "width": 12, "height": 4, "chartType": "line", "xAxisType": "time", "yAxisLabel": "%", "removeOlder": "1", "removeOlderUnit": "3600", "x": 1510, "y": 400, "wires": [], "showLegend": true }, { "id": "rm_int_state_text", "type": "ui-text", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_vis", "name": "State", "label": "State Snapshot", "order": 6, "width": 12, "height": 1, "format": "{{msg.payload}}", "layout": "row-spread", "x": 1510, "y": 460, "wires": [] }, { "id": "rm_int_debug_influx", "type": "debug", "z": "12f41a7b538c40db", "name": "Influx", "active": true, "tosidebar": true, "complete": "true", "targetType": "full", "x": 1250, "y": 520, "wires": [] }, { "id": "rm_int_debug_parent", "type": "debug", "z": "12f41a7b538c40db", "name": "Parent", "active": true, "tosidebar": true, "complete": "true", "targetType": "full", "x": 1240, "y": 560, "wires": [] }, { "id": "rm_int_chart_ctrl", "type": "ui-chart", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_vis", "name": "Ctrl", "label": "Ctrl (%)", "order": 4, "width": 12, "height": 4, "chartType": "line", "xAxisType": "time", "yAxisLabel": "%", "removeOlder": "1", "removeOlderUnit": "3600", "x": 1510, "y": 460, "wires": [], "showLegend": true }, { "id": "rm_int_chart_statecode", "type": "ui-chart", "z": "12f41a7b538c40db", "group": "ui_group_rm_int_vis", "name": "State Code", "label": "State Code (off=0 .. maint=9)", "order": 5, "width": 12, "height": 4, "chartType": "line", "xAxisType": "time", "yAxisLabel": "state", "removeOlder": "1", "removeOlderUnit": "3600", "x": 1510, "y": 520, "wires": [], "showLegend": true }, { "id": "rm_int_ctrl_setpoint_for_chart", "type": "function", "z": "12f41a7b538c40db", "name": "ctrl setpoint series", "func": "msg.topic = 'setpoint_ctrl';\nmsg.payload = Number(msg.payload);\nreturn Number.isFinite(msg.payload) ? msg : null;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 560, "y": 220, "wires": [ [ "rm_int_chart_ctrl" ] ] }, { "id": "rm_int_flow_setpoint_for_chart", "type": "function", "z": "12f41a7b538c40db", "name": "flow setpoint series", "func": "msg.topic = 'setpoint_flow';\nmsg.payload = Number(msg.payload);\nreturn Number.isFinite(msg.payload) ? msg : null;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 570, "y": 330, "wires": [ [ "rm_int_chart_flow" ] ] } ]