'use strict' /** * Copyright (c) 2017~2023, OBCon Inc. * All rights reserved. */ /** * @file * @copyright 2017~2023, OBCon Inc. * @author gye hyun james kim [pnuskgh@gmail.com] */ const fs = require('fs'); // const path = require('path'); class Interfaces { constructor() { this.command = { S: '단말기 제어', A: '단말기 제어에 대한 ACK', L: '정류기 LTE 모뎀 리셋 전용 프로토콜', G: '수집 데이터 서버 전송', Q: '원격 TB에 저장된 제어 항목이 있는지 물어보는 명령어 및 제어 없음 응답', C: '블루통신 통신으로 원격 TB 환경 설정을 변경한 항목을 서버에 전송하는 명령어', // T: 'Client에 시간 정보 제공' }; this.protocols = [ //--- 통신 프로세스 정의 { start: 'server', req: 'S', res: 'A' }, //--- S 요청을 보낸후 A 응답을 받음 { start: 'server', req: 'L', res: null }, //--- L 요청을 한후 응답을 받지 않음 { start: 'client', req: 'G', res: 'G' }, //--- G 요청을 받은후 응답하지 않음 (일부는 응답 함, 2023.11.16) { start: 'client', req: 'Q', res: 'Q' }, //--- Q 요청을 받은 후 제어가 없는 경우 Q 응답을 함 { start: 'client', req: 'C', res: null }, //--- C 요청을 받은후 응답하지 않음 // { start: 'client', req: 'T', res: 'T' } //--- Client에 시간 정보 제공 ]; // this.types = [ //--- Interfaces를 찾는 순서 // '5', '4', '3', '2', '1' // ]; } existCommand(cmd) { return typeof(this.command[cmd]) != 'undefined'; // return Object.getOwnPropertyNames(this.command).includes(cmd); // return -1 < Object.getOwnPropertyNames(this.command).indexOf(cmd); } //--- Interface를 찾는 순서 (folder, cmd, type은 고정) //--- custom/${service}/interfaces/${version}/${folder}/${interfaceFile} //--- version별 순환 //--- custom/interfaces/${version}/${folder}/${interfaceFile} //--- version별 순환 //--- interfaces/${version}/${folder}/${interfaceFile} //--- version별 순환 getInterfaceFile(version, folder, interfaceFile, type='default') { //--- 순환할 버전을 찾는다. const versionCurrent = this.getVersion(version); const versionFolders = []; //--- 동적 설정이 없으므로 정적 설정(modules/devices/models.js)에서 반환 (확인 필요) settingSync.getSetting2(null, 'devices', 'interfaces', 'folders', [])['type_' + type].forEach(versionFolder => { if (this.getVersion(versionFolder) <= versionCurrent) { versionFolders.push(this.getVersion(versionFolder)); } }); //--- custom/${service}/ 폴더를 탐색 한다. //--- custom/ 폴더를 탐색 한다. //--- interfaces/ 폴더를 탐색 한다. const files = []; for (let idx = 0; idx < versionFolders.length; idx++) { files.push(utils.getPath('custom', config.service.name, 'interfaces', versionFolders[idx], folder, interfaceFile)); } for (let idx = 0; idx < versionFolders.length; idx++) { files.push(utils.getPath('custom', 'interfaces', versionFolders[idx], folder, interfaceFile)); } for (let idx = 0; idx < versionFolders.length; idx++) { files.push(utils.getPath('interfaces', versionFolders[idx], folder, interfaceFile)); } //--- 존재하는 파일을 반환 한다. for (let idx = 0; idx < files.length; idx++) { if (fs.existsSync(files[idx])) { console.log('Interface file : ' + files[idx]); return files[idx]; } } return null; } //--- Interface Handler를 반환 한다. getHandler(version, folder, cmd, type, position=null) { try { const interfaceFile = this.getInterfaceFile(this.getVersion(version), folder, folder + '_' + cmd + '_' + type + '_handler.js', type); if (interfaceFile == null) { return null; } else { const interfaceClass = require(interfaceFile); const rtHandler = new interfaceClass(); if (position != null) { rtHandler.position = position; } logger.info('interfaces/interfaces.js : ' + version + '/' + folder + '_' + cmd + '_' + type + ', interfaceFile: ' + interfaceFile); return rtHandler; } } catch (e) { logger.error('interfaces/interfaces.js : interfaces getHandler error'); logger.error('interfaces/interfaces.js : ' + e.name + ': ' + e.message); logger.error('interfaces/interfaces.js : ' + e.stack); return null; } } getVersion(version) { let rtVersion = settingSync.getSetting2(null, 'devices', 'interfaces', 'versionDefault', '1.00'); if ((version != null) && (utils.isNone(version) == false)) { rtVersion = version; } if (rtVersion.startsWith('v') == false) { rtVersion = 'v' + rtVersion; } return rtVersion.replace('.', ''); } //--- Server가 받은 요청을 처리할 Handler를 반환 getServerHandler(version, cmd, type) { for (let idx = 0; idx < this.protocols.length; idx++) { let protocol = this.protocols[idx]; if (protocol.start == 'server') { if (protocol.res == cmd) { return this.getHandler(this.getVersion(version), 'response', cmd, type, 'server'); } } else { if (protocol.req == cmd) { return this.getHandler(this.getVersion(version), 'request', cmd, type, 'server'); } } }; return null; } //--- Client가 받은 요청을 처리할 Handler를 반환 getClientHandler(version, cmd, type) { for (let idx = 0; idx < this.protocols.length; idx++) { const protocol = this.protocols[idx]; if (protocol.start == 'client') { if (protocol.res == cmd) { return this.getHandler(this.getVersion(version), 'response', cmd, type, 'client'); } } else { if (protocol.req == cmd) { return this.getHandler(this.getVersion(version), 'request', cmd, type, 'client'); } } }; return null; } } module.exports = Interfaces;