From 0485b2f7d560628d82e2008dfcad785c7890e6d5 Mon Sep 17 00:00:00 2001 From: tobias <thinkdifferent055@gmail.com> Date: Tue, 19 Sep 2023 17:01:09 +0200 Subject: [PATCH] #187 - Fetch current project on websocket connected --- actions.js | 9 +- main.js | 280 ++++++++++++++++++---------------- package.json | 2 +- receive/message_executable.js | 5 + receive/project_update.js | 8 + 5 files changed, 167 insertions(+), 137 deletions(-) create mode 100644 receive/message_executable.js create mode 100644 receive/project_update.js diff --git a/actions.js b/actions.js index df48d56..43e9caf 100644 --- a/actions.js +++ b/actions.js @@ -14,14 +14,9 @@ module.exports = function (self) { ], callback: async (event) => { const payload = { - 'messageId': 'id', - 'type': 'pad-status-change', - 'payload': { - 'pad': '8b7ef494-d735-45f9-ab84-c95e299298a6', - 'status': 'PLAY' - } + 'pad': '8b7ef494-d735-45f9-ab84-c95e299298a6' }; - self.ws.send(JSON.stringify(payload)) + self.sendToWebSocket('cart-action', payload) }, }, }) diff --git a/main.js b/main.js index 8691d4d..5e74222 100644 --- a/main.js +++ b/main.js @@ -1,139 +1,161 @@ -const { InstanceBase, Regex, runEntrypoint, InstanceStatus } = require('@companion-module/base') +const {InstanceBase, Regex, runEntrypoint, InstanceStatus} = require('@companion-module/base') const UpgradeScripts = require('./upgrades') const UpdateActions = require('./actions') const UpdateFeedbacks = require('./feedbacks') const UpdateVariableDefinitions = require('./variables') const WebSocket = require('ws') +const ProjectUpdate = require("./receive/project_update"); class ModuleInstance extends InstanceBase { - isInitialized = false - // language=RegExp - wsRegex = '^wss?:\\/\\/([\\da-z\\.-]+)(:\\d{1,5})?(?:\\/(.*))?$' - - constructor(internal) { - super(internal) - } - - async init(config) { - this.config = config - - this.initWebSocket() - this.isInitialized = true - - this.updateActions() // export actions - this.updateFeedbacks() // export feedbacks - this.updateVariableDefinitions() // export variable definitions - } - // When module gets deleted - async destroy() { - this.isInitialized = false - - if (this.ws) { - this.ws.close(1000) - delete this.ws - } - } - - async configUpdated(config) { - this.config = config - this.initWebSocket() - } - - // Return config fields for web config - getConfigFields() { - return [ - { - type: 'textinput', - id: 'host', - label: 'PlayWall IP', - width: 8, - regex: Regex.IP, - }, - { - type: 'textinput', - id: 'port', - label: 'PlayWall Port', - width: 4, - regex: Regex.PORT, - }, - { - type: 'checkbox', - id: 'debug_messages', - label: 'Debug messages', - tooltip: 'Log incomming and outcomming messages', - width: 6, - }, - ] - } - - updateActions() { - UpdateActions(this) - } - - updateFeedbacks() { - UpdateFeedbacks(this) - } - - updateVariableDefinitions() { - UpdateVariableDefinitions(this) - } - - // Websocket handling - - initWebSocket() { - if (this.reconnect_timer) { - clearTimeout(this.reconnect_timer) - this.reconnect_timer = null - } - - if (this.config.host == null || this.config.port == null) { - console.log(`PlayWall host '${this.config.host}' or port '${this.config.port}' is invalid`); - this.updateStatus(InstanceStatus.BadConfig, `PlayWall host '${this.config.host}' or port '${this.config.port}' is invalid`) - return - } - const url = `ws://${this.config.host}:${this.config.port}/api` - if (!url || url.match(new RegExp(this.wsRegex)) === null) { - this.updateStatus(InstanceStatus.BadConfig, `WS URL is not defined or invalid`) - return - } - - this.updateStatus(InstanceStatus.Connecting) - - if (this.ws) { - this.ws.close(1000) - delete this.ws - } - - this.ws = new WebSocket(url) - - this.ws.on('open', () => { - this.updateStatus(InstanceStatus.Ok) - this.log('debug', `Connection opened`) - }) - this.ws.on('close', (code) => { - this.log('debug', `Connection closed with code ${code}`) - this.updateStatus(InstanceStatus.Disconnected, `Connection closed with code ${code}`) - }) - - this.ws.on('message', this.messageReceivedFromWebSocket.bind(this)) - - this.ws.on('error', (data) => { - this.log('error', `WebSocket error: ${data}`) - }) - } - - messageReceivedFromWebSocket(data) { - if (this.config.debug_messages) { - this.log('debug', `Message received: ${data}`) - } - - let msgValue = null - try { - msgValue = JSON.parse(data) - } catch (e) { - msgValue = data - } - } + isInitialized = false + // language=RegExp + wsRegex = '^wss?:\\/\\/([\\da-z\\.-]+)(:\\d{1,5})?(?:\\/(.*))?$' + + messageHandlers = { + 'project-current': new ProjectUpdate() + }; + + currentProject = {} + + constructor(internal) { + super(internal) + } + + async init(config) { + this.config = config + + this.initWebSocket() + this.isInitialized = true + + this.updateActions() // export actions + this.updateFeedbacks() // export feedbacks + this.updateVariableDefinitions() // export variable definitions + } + + // When module gets deleted + async destroy() { + this.isInitialized = false + + if (this.ws) { + this.ws.close(1000) + delete this.ws + } + } + + async configUpdated(config) { + this.config = config + this.initWebSocket() + } + + // Return config fields for web config + getConfigFields() { + return [ + { + type: 'textinput', + id: 'host', + label: 'PlayWall IP', + width: 8, + regex: Regex.IP, + }, + { + type: 'textinput', + id: 'port', + label: 'PlayWall Port', + width: 4, + regex: Regex.PORT, + }, + { + type: 'checkbox', + id: 'debug_messages', + label: 'Debug messages', + tooltip: 'Log incomming and outcomming messages', + width: 6, + }, + ] + } + + updateActions() { + UpdateActions(this) + } + + updateFeedbacks() { + UpdateFeedbacks(this) + } + + updateVariableDefinitions() { + UpdateVariableDefinitions(this) + } + + // Websocket handling + + initWebSocket() { + if (this.reconnect_timer) { + clearTimeout(this.reconnect_timer) + this.reconnect_timer = null + } + + if (this.config.host == null || this.config.port == null) { + console.log(`PlayWall host '${this.config.host}' or port '${this.config.port}' is invalid`); + this.updateStatus(InstanceStatus.BadConfig, `PlayWall host '${this.config.host}' or port '${this.config.port}' is invalid`) + return + } + const url = `ws://${this.config.host}:${this.config.port}/api` + if (!url || url.match(new RegExp(this.wsRegex)) === null) { + this.updateStatus(InstanceStatus.BadConfig, `WS URL is not defined or invalid`) + return + } + + this.updateStatus(InstanceStatus.Connecting) + + if (this.ws) { + this.ws.close(1000) + delete this.ws + } + + this.ws = new WebSocket(url) + + this.ws.on('open', () => { + this.updateStatus(InstanceStatus.Ok) + this.log('debug', `Connection opened`) + + this.sendToWebSocket('project-current', {}); + }) + this.ws.on('close', (code) => { + this.log('debug', `Connection closed with code ${code}`) + this.updateStatus(InstanceStatus.Disconnected, `Connection closed with code ${code}`) + }) + + this.ws.on('message', this.messageReceivedFromWebSocket.bind(this)) + + this.ws.on('error', (data) => { + this.log('error', `WebSocket error: ${data}`) + }) + } + + sendToWebSocket(type, payload) { + this.ws.send(JSON.stringify({ + 'type': type, + 'messageId': 'ID', + 'payload': payload + })); + } + + messageReceivedFromWebSocket(data) { + if (this.config.debug_messages) { + this.log('debug', `Message received: ${data}`) + } + + const message = JSON.parse(data) + if (message.type != null) { + if (this.messageHandlers[message.type] != null) { + this.messageHandlers[message.type].handleMessage(this, message) + } else { + this.log('debug', `Cannot handle incoming message of type ${message.type}`) + } + } else { + this.log('debug', `Cannot handle incoming message ${message}`) + } + } } runEntrypoint(ModuleInstance, UpgradeScripts) diff --git a/package.json b/package.json index 1fc3d14..84dba83 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "MyModule", + "name": "play_wall_companion", "version": "0.1.0", "main": "main.js", "scripts": { diff --git a/receive/message_executable.js b/receive/message_executable.js new file mode 100644 index 0000000..34ecf98 --- /dev/null +++ b/receive/message_executable.js @@ -0,0 +1,5 @@ +module.exports = class MessageExecutable { + handleMessage(plugin, message) { + // Abstract method + } +} \ No newline at end of file diff --git a/receive/project_update.js b/receive/project_update.js new file mode 100644 index 0000000..219e055 --- /dev/null +++ b/receive/project_update.js @@ -0,0 +1,8 @@ +const MessageExecutable = require("./message_executable"); + +module.exports = class ProjectUpdate extends MessageExecutable { + + handleMessage(plugin, message) { + plugin.currentProject = message.payload + } +} \ No newline at end of file -- GitLab