node-red-contrib-motechat
Version:
ultranet topic and payload communication
259 lines (238 loc) • 8.88 kB
JavaScript
const mchat = require('motechat')
const os = require('os')
const { name, version } = require('../package.json')
const { EventEmitter } = require('events')
const debug = require('debug')('nr-motechat')
//let config = require('./config.js')
let mcState = false
let mcEvent = new EventEmitter()
mcEvent.setMaxListeners(0)
let settings = {}
let isReg = false;
debug(`${name} version:${version}`)
let conf = {
"AppName": process.env.MCHAT_APPNAME || os.hostname(),
"AppKey": process.env.APP_KEY || "1u6WauSf",
"DCenter": process.env.MCHAT_DC || "dc",
"IOC": process.env.MCHAT_IOC || "",
"MotebusGW": process.env.MCHAT_MBGWIP || "127.0.0.1",
"MotebusPort": process.env.MCHAT_PORT || "6262",
"WatchLevel": process.env.MCHAT_WATCHLEVEL || "0"
}
let eiInfo = {
"EiOwner": process.env.NCHAT_EIOWNER || "",
"EiName": process.env.MCHAT_EINAME || os.hostname(),
"EiType": process.env.MCHAT_EITYPE || ".flow",
"EiTag": process.env.MCHAT_EITAG || "",
"EiLoc": process.env.MCHAT_EILOC || ""
}
let reginfo = {
"SToken":"",
"EiToken":"",
"DDN":"",
"EiUDID":"",
"WIP":"",
"LIP":"",
"EdgeInfo":""
}
let checkUDID = process.env.MCHAT_UDID || "0";
class MCClient {
static async setdSIM(data){
let setdata = {"catalog":conf.AppName,"idname":"dSIM","data":data};
let result = await mchat.mbSetConfig(setdata);
return result
}
static async getdSIM(){
let getdata = {"catalog":conf.AppName,"idname":"dSIM"};
let result = await mchat.mbGetConfig(getdata);
return result
}
static getMessage({ Topic = '', DDN = '', Data } = {}) {
return {
SToken: reginfo.SToken,
Topic, DDN, Data,
SendTimeout: process.env.SENDTIMEOUT || 6,
WaitReply: process.env.WAITREPLY || 12
}
}
static getRPC({ Topic = '', DDN = '', Func, Data } = {}) {
return {
SToken: reginfo.SToken,
Topic, DDN, Func, Data,
SendTimeout: process.env.SENDTIMEOUT || 6,
WaitReply: process.env.WAITREPLY || 12
}
}
static async setEi({ name, tag, location}){
function isDiffEi({ name, tag, location }) {
const { EiName, EiTag, EiLoc } = reginfo.EdgeInfo;
if (name !== EiName) return true
if (tag !== EiTag) return true
if (location !== EiLoc) return true
return false
}
if (!isDiffEi({ name, tag, location })) {
return new Promise(resolve => resolve({}))
}
reginfo.EdgeInfo = {"EiName":name,"EiType":reginfo.EdgeInfo.EiType,"EiTag":tag,"EiLoc":location}
let setdata = {"catalog":conf.AppName,"idname":"dSIM","data":reginfo};
let result = await mchat.mbSetConfig(setdata);
//let savret = await this.setdSIM(reginfo)
return new Promise(resolve => {
mchat.Set(reginfo, result => resolve(result))
})
}
static async setup() {
debug("DC env: ", process.env.DC)
await mchat.Open(conf, async (openret) => { //open motechat
//console.log('motechat open result=', openret)
let getret = await this.getdSIM() // let "getret" = config content
//console.log('get dsim=', getret);
if (getret.ErrCode == 0){ // if connect motebus OK
let dsimflag = false
if (getret.result) { // if config is not empty, let "reginfo" = "getret"
dsimflag = true
reginfo = getret.result
if(reginfo.EdgeInfo.EiName != eiInfo.EiName){
reginfo.EdgeInfo.EiName = eiInfo.EiName;
if (checkUDID === '1'){
reginfo.EdgeInfo.EiName = reginfo.EiUDID + '-' + eiInfo.EiName;
}
await this.setdSIM(reginfo);
}
}
let regret = await mchat.Reg(reginfo);
debug("motechat reg result= ", regret);
isReg = true;
if (regret.ErrCode == 0 && regret.result && !dsimflag){ // first time(config is empty)
let info = regret.result //reg data without Ei
let {SToken,EiToken,DDN, EiUDID} = info;
if (checkUDID === '1'){
eiInfo.EiName = EiUDID + '-' + eiInfo.EiName; //EiName merge with UDID
}
reginfo.EdgeInfo = eiInfo;
reginfo.SToken = info.SToken;
reginfo.EiToken = info.EiToken;
let setret = await mchat.Set(reginfo);
let {EiName,EiType,EiTag,EiLoc} = setret.result;
let ei = {"EiName":EiName,"EiType":EiType,"EiTag":EiTag,"EiLoc":EiLoc}
let savereg = {"SToken":SToken,"EiToken":EiToken,"DDN":DDN, "EiUDID":EiUDID,"EdgeInfo":ei}
let savret = await this.setdSIM(savereg) // save(first time data) to config
console.log('set dsim=', savret);
reginfo = savereg
}
}
mchat.OnEvent('message', (ch, inctl, data, cb) => {
mcEvent.emit('message', { ch, inctl, data, mcBack: cb })
// cb({ ErrCode: 0, ErrMsg: 'OK' })
}, '')
mchat.OnEvent('state', state => mcEvent.emit('state', { state }), '')
})
}
}
function isRegist(){
return isReg;
}
const checkNormal = (reply) => {
if (!Array.isArray(reply)) {
const { ErrCode } = reply
return ErrCode == 0
}
const [result] = reply
if (result.State) {
const { ErrCode } = result.State
return ErrCode == 0
}
if (result.IN.State) {
const { ErrCode } = result.IN.State
return ErrCode == 0
}
}
MCClient.setup()
module.exports = {
/**
* @summary Send the message to the DDN, and return the promise of the reply
* @function send
* @public
*
* @param {string} topic the topic
* @param {string} DDN the DDN
* @param {*} payload the data that send to the DDN
*
* @returns {Promise<object>} return the send reply
*/
send(topic, DDN, timers = {}, payload) {
let { t1, t2 } = timers
return new Promise((resolve, reject) => {
const message = MCClient.getMessage({
Topic: topic, DDN, Data: payload,
t1, t2
})
mchat.Send(message, reply => {
const isNormal = checkNormal(reply)
if (!isNormal) reject(reply)
resolve(reply)
})
})
},
/**
* @summary Call the function of the DDN, and then return the reply
* @function call
* @public
*
* @param {stirng} topic the topic
* @param {string} DDN the DDN
* @param {string} func the function name
* @param {*} payload the data that send to the called topic
*
* @returns {Promise<object>} return the call reply
*/
call(topic, DDN, func, timers = {}, payload = {}) {
let { t1, t2 } = timers
return new Promise((resolve, reject) => {
let xrpc = MCClient.getRPC({
Topic: topic, DDN, Func: func, Data: payload,
t1, t2
})
mchat.Call(xrpc, reply => {
const isNormal = checkNormal(reply)
if (!isNormal) reject(reply)
resolve(reply)
})
})
},
/**
* @summary set the triggerID signal to the event emitter
* @function setEvent
* @public
*
* @param {string} event the event signal
* @param {function} callback the event callback fucntion
*/
setEvent(event, callback) {
if (event !== "message" && event !== "status") return
debug("setting event")
mcEvent.on(event, callback)
debug(mcEvent)
},
/**
* @summary remove the event listener from the event emitter
* @function removeEvent
* @public
*
* @param {string} event the event signal that removed from the event emitter
* @param {function} callback the event callback that removed
*/
removeEvent(event, callback) {
mcEvent.removeListener(event, callback)
},
getDDN() {
return reginfo.DDN
},
setEi: MCClient.setEi,
debug: debug,
isRegist() {
return isRegist();
}
}