UNPKG

@pmouli/isy-matter-server

Version:

Service to expose an ISY device as a Matter Border router

202 lines (201 loc) 7.84 kB
#!/usr/bin/env node import path from 'path'; import chalk from 'chalk'; import { emphasize, findPackageJson } from 'isy-nodejs/Utils'; import './utils.js'; import { addClientLogTransport, handleExit, initialize, isyConfig, logger, matterConfig, options, serverConfig } from './utils.js'; var ServerState; (function (ServerState) { ServerState[ServerState["Stopped"] = 0] = "Stopped"; ServerState[ServerState["Starting"] = 1] = "Starting"; ServerState[ServerState["Running"] = 2] = "Running"; ServerState[ServerState["Stopping"] = 3] = "Stopping"; })(ServerState || (ServerState = {})); let bridgeServerState = ServerState.Stopped; let interfaceState = ServerState.Stopped; let apiInfo = {}; let isy; let serverNode; export let pluginEnv; export let matterServer; export async function startBridgeServer() { if (bridgeServerState === ServerState.Starting || bridgeServerState === ServerState.Running) { logger.info(emphasize('Bridge server already starting or running')); return; } if (!isyConfig || !matterConfig) { logger.error('Missing configuration'); return; } if (isy || serverNode) { logger.info(emphasize('Bridge already started/starting')); return; } bridgeServerState = ServerState.Starting; try { logger.info(emphasize('Connecting to IoX')); isy = await loadISYInterface(); //await isy.initialize(); logger.info(emphasize('Connected to IoX')); serverNode = await loadBridgeServer(); //if (process.send) process.send({ pairingInfo: matterServer.getPairingCode() }); bridgeServerState = ServerState.Running; logger.info(emphasize('Bridge started')); logger.info('*'.repeat(80)); logger.info(`IoX firmware version: ${emphasize(isy.firmwareVersion)}`); logger.info(`IoX model: ${emphasize(isy.productName)}`); logger.info(`IoX model number: ${isy.productId}`); logger.info(`IoX api version: ${emphasize(apiInfo.isy_nodejs.version)}`); logger.info(`IoX to Matter api version: ${emphasize(apiInfo.isy_matter.version)}`); logger.info(`Matter api version: ${emphasize(apiInfo.matter_js.version)}`); logger.info('*'.repeat(80)); } catch (e) { bridgeServerState = ServerState.Stopped; if (e instanceof Error) { logger.error(`Error starting bridge: ${e.message}`, e); } else logger.error(`Error starting bridge: ${e}`); try { await isy[Symbol.asyncDispose](); isy = undefined; } finally { try { await serverNode.close(); await serverNode[Symbol.asyncDispose](); serverNode = undefined; } catch { } } } } async function loadISYInterface() { let modulePath = 'isy-nodejs/ISY'; if (options.dependencies === 'plugin') { logger.info('Locating ISY api from plugin dependencies'); if (!pluginEnv) { logger.error('Plugin environment not set'); } else { modulePath = path.resolve('isy-nodejs', 'node_modules', pluginEnv.PLUGIN_PATH); logger.info('IoX api located: ' + modulePath); } } logger.info('Loading IoX api from ' + modulePath); let ISYNS = (await import(modulePath)).ISY; let pj = await findPackageJson('isy-nodejs'); let apiMeta = { name: pj.name, version: pj.version, path: pj.path.toString() }; logger.info(`IoX api loaded`); logApiInfo(apiMeta); apiInfo.isy_nodejs = apiMeta; return ISYNS.create(isyConfig, logger, serverConfig.workingDir); } async function logApiInfo(apiMeta) { logger.info(`module: ${apiMeta.name}, version: ${apiMeta.version}, location: ${apiMeta.path}`); } async function loadBridgeServer() { if (!matterServer) { logger.info('Loading IoX to matter bridge api'); matterServer = await import('isy-matter/Bridge/Server'); let pj = await findPackageJson('isy-matter'); apiInfo.isy_matter = { name: pj.name, version: pj.version, path: pj.path.toString() }; let pj2 = await findPackageJson('@matter/main'); apiInfo.matter_js = { name: pj2.name, version: pj2.version, path: pj2.path.toString() }; logger.info(`IoX to matter bridge & matter.js api loaded`); logApiInfo(apiInfo.isy_matter); logApiInfo(apiInfo.matter_js); } logger.info(emphasize('Starting bridge')); return matterServer.create(isy, matterConfig); } export async function stopBridgeServer() { const startState = bridgeServerState; try { if (!isy || !serverNode || startState === ServerState.Stopped) { logger.info(chalk.white.bold('Matter bridge not started. Nothing to stop.')); return; } if (startState === ServerState.Stopping) { logger.info(chalk.white.bold('Bridge already stopping')); return; } bridgeServerState = ServerState.Stopping; if (isy) { logger.info(chalk.white.bold('Disconnecting from ISY')); await isy[Symbol.asyncDispose](); isy = undefined; logger.info(chalk.white.bold('Disconnected from ISY')); } if (serverNode) { logger.info(chalk.white.bold('Stopping bridge')); //await serverNode.prepareRuntimeShutdown(); await serverNode.env.runtime.close(); //await serverNode.close(); //await serverNode[Symbol.asyncDispose](); serverNode = undefined; matterServer = undefined; logger.info(chalk.white.bold('Bridge stopped')); } bridgeServerState = ServerState.Stopped; } catch (e) { logger.error(`Error stopping bridge server ${e.message}`, e); //bridgeServerState = ServerState.Stopping; } } /*process.on('SIGTERM', async () => { if (exiting) { logger.info('SIGTERM received again, exiting'); process.exit(0); } logger.info('SIGTERM received, stopping bridge server'); await stopBridgeServer(); process.exit(0); });*/ let client; process.on('uncaughtException', async (err) => { logger.error('Uncaught exception: ' + err.message, err); }); await initialize(); if (serverConfig.subprocess) { logger.info('Running in subprocess'); logger.info(`args: [${process.argv.join(', ')}]`); if (options.openSocket) { addClientLogTransport(process); } await startBridgeServer(); if (process.send) { process.send('Matter bridge started'); process.send({ pairingInfo: matterServer.getPairingCode() }); } process.on('SIGABRT', handleExit(stopBridgeServer)); process.on('SIGINT', async () => { logger.info('SIGINT received, doing nothing. Waiting for abort from parent'); }); process.on('SIGTERM', async () => { logger.info('SIGTERM received, doing nothing. Waiting for abort from parent'); }); /*process.on('message', async (message, socket: Socket) => { if (message === 'client') { addClientLogTransport(process); logger.info('Client logger connected'); client = socket; await startBridgeServer(); socket.write(JSON.stringify({ pairingInfo: matterServer.getPairingCode() })); } });*/ /*process.on('disconnect', async () => { logger.info('parent disconnected. removing client log transport'); if (clientLogTransport) { removeClientLogTransport(); } //ogger.info('Matter bridge server stopped'); //process.exit(0); });*/ } //main(); //# sourceMappingURL=server.js.map //# sourceMappingURL=server.js.map //# sourceMappingURL=server.js.map