Skip to content

Commit

Permalink
ECHONET Lite communication waits for the response of the previous com…
Browse files Browse the repository at this point in the history
…mand before sending the next command. (#22)

ECHONETLite2MQTT waits for a command response before sending the next command.
Therefore, commands can be sent correctly even to devices that are slow to respond.
Additionally, devices can now be discovered faster.
  • Loading branch information
banban525 committed Oct 26, 2023
2 parents 1863311 + 6a5416e commit 43f70ec
Show file tree
Hide file tree
Showing 10 changed files with 1,114 additions and 727 deletions.
169 changes: 168 additions & 1 deletion server/EchoNetCommunicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ export class EchoNetCommunicator
});
}

public static release():void
{
EL.release();
}

public static updateidentifierFromMacAddress = (base:number[]):number[] =>
{
const result = JSON.parse(JSON.stringify(base));
Expand Down Expand Up @@ -140,6 +145,8 @@ export class EchoNetCommunicator
{
this.getHandlers.forEach(_=>_(rinfo,els));
}
this.commandResponse?.addResponse({rinfo, els});

this.reveivedHandlers.forEach(_=>_(rinfo,els));
}

Expand Down Expand Up @@ -180,6 +187,7 @@ export class EchoNetCommunicator
{
return EL.facilities;
}

public static send = (
ip: string,
seoj: string | number[],
Expand Down Expand Up @@ -232,6 +240,111 @@ export class EchoNetCommunicator
return EL.replyGetDetail(rinfo, els, dev_details);
}

static readonly DefaultCommandTimeout=1000;
static commandResponse:CommandResponse|undefined = undefined;
public static execCommandPromise(
ip: string,
seoj: string,
deoj: string,
esv: string,
epc: string,
edt: string
): Promise<CommandResponse>
{
const command:Command = {
ip,
seoj,
deoj,
esv,
epc,
edt,
tid: ""
}
const tid = EL.sendOPC1(ip, seoj, deoj, esv, epc, edt);
command.tid = EL.bytesToString(tid);
const commandResponse = new CommandResponse(command);
this.commandResponse = commandResponse;

return new Promise<CommandResponse>((resolve,reject)=>{
const handle = setTimeout(()=>{
reject({message:"timeout", commandResponse});
}, this.DefaultCommandTimeout);
commandResponse.setCallback(()=>{
this.commandResponse = undefined;
clearTimeout(handle);
resolve(commandResponse);
});
});
}

public static async getMultiPropertyPromise(
ip: string,
seoj: string,
deoj: string,
esv: string,
epc: string[]
): Promise<CommandResponse>
{
const command:Command = {
ip,
seoj,
deoj,
esv,
epc:"",
edt:"",
tid: ""
}
const edt:{[key:string]:string} = {};
epc.forEach(_=>{
edt[_]="";
});
const tid = await EL.sendDetails(ip, seoj, deoj, esv, edt);
command.tid = EL.bytesToString(tid);
const commandResponse = new CommandResponse(command);
this.commandResponse = commandResponse;

return await new Promise<CommandResponse>((resolve,reject)=>{
const handle = setTimeout(()=>{
reject({message:"timeout", commandResponse});
}, this.DefaultCommandTimeout);
commandResponse.setCallback(()=>{
this.commandResponse = undefined;
clearTimeout(handle);
resolve(commandResponse);
});
});
}

public static getForTimeoutPromise(
ip: string,
seoj: string,
deoj: string,
esv: string,
epc: string,
edt: string,
timeout: number
): Promise<CommandResponse>
{
const command:Command = {
ip,
seoj,
deoj,
esv,
epc,
edt,
tid: ""
}
const tid = EL.sendOPC1(ip, seoj, deoj, esv, epc, edt);
command.tid = EL.bytesToString(tid);
const commandResponse = new CommandResponse(command);
this.commandResponse = commandResponse;

return new Promise<CommandResponse>((resolve,reject)=>{
setTimeout(()=>{
resolve(commandResponse);
}, timeout);
});
}
}

export class ELSV
Expand All @@ -243,4 +356,58 @@ export class ELSV
public static readonly SETI="60";
public static readonly SET_RES="71";
public static readonly GET_SNA="52";
}
}


export interface Command
{
ip: string,
seoj: string,
deoj: string,
esv: string ,
epc: string,
edt: string;
tid: string;
}

export class CommandResponse
{
readonly command:Command;
callback:()=>void = ()=>{};
constructor(command:Command)
{
this.command = command;
}
responses:Response[] = [];

public setCallback(callback:()=>void):void
{
this.callback = callback;
}

public addResponse = (response:Response):void =>
{
if((this.command.ip === EL.EL_Multi || response.rinfo.address === this.command.ip ) &&
response.els.SEOJ === this.command.deoj && response.els.TID === this.command.tid)
{
this.responses.push(response);
this.callback();
}
}
}

export interface Response
{
rinfo: rinfo;
els: eldata;
}


export interface RawDataSet
{
existsDevice:(ip:string, eoj:string)=>boolean;
existsData:(ip:string, eoj:string, epc:string)=>boolean;
getIpList:()=>string[];
getEojList:(ip:string)=>string[];
getRawData:(ip:string, eoj:string, epc:string)=>string|undefined;
}
Loading

0 comments on commit 43f70ec

Please sign in to comment.