zigbee-herdsman
Version:
An open source ZigBee gateway solution with node.js.
190 lines (152 loc) • 6.93 kB
text/typescript
import events from "node:events";
import type * as Models from "../models";
import type {BroadcastAddress} from "../zspec/enums";
import * as Zcl from "../zspec/zcl";
import type * as Zdo from "../zspec/zdo";
import type * as ZdoTypes from "../zspec/zdo/definition/tstypes";
import {discoverAdapter} from "./adapterDiscovery";
import type * as AdapterEvents from "./events";
import type * as TsType from "./tstype";
interface AdapterEventMap {
deviceJoined: [payload: AdapterEvents.DeviceJoinedPayload];
zclPayload: [payload: AdapterEvents.ZclPayload];
zdoResponse: [clusterId: Zdo.ClusterId, response: ZdoTypes.GenericZdoResponse];
disconnected: [];
deviceLeave: [payload: AdapterEvents.DeviceLeavePayload];
}
export abstract class Adapter extends events.EventEmitter<AdapterEventMap> {
public hasZdoMessageOverhead: boolean;
public manufacturerID: Zcl.ManufacturerCode;
protected networkOptions: TsType.NetworkOptions;
protected adapterOptions: TsType.AdapterOptions;
protected serialPortOptions: TsType.SerialPortOptions;
protected backupPath: string;
protected constructor(
networkOptions: TsType.NetworkOptions,
serialPortOptions: TsType.SerialPortOptions,
backupPath: string,
adapterOptions: TsType.AdapterOptions,
) {
super();
this.hasZdoMessageOverhead = true;
this.manufacturerID = Zcl.ManufacturerCode.RESERVED_10;
this.networkOptions = networkOptions;
this.adapterOptions = adapterOptions;
this.serialPortOptions = serialPortOptions;
this.backupPath = backupPath;
}
/**
* Utility
*/
public static async create(
networkOptions: TsType.NetworkOptions,
serialPortOptions: TsType.SerialPortOptions,
backupPath: string,
adapterOptions: TsType.AdapterOptions,
): Promise<Adapter> {
const [adapter, path] = await discoverAdapter(serialPortOptions.adapter, serialPortOptions.path);
serialPortOptions.adapter = adapter;
serialPortOptions.path = path;
switch (adapter) {
case "zstack": {
const {ZStackAdapter} = await import("./z-stack/adapter/zStackAdapter.js");
return new ZStackAdapter(networkOptions, serialPortOptions, backupPath, adapterOptions);
}
case "ember": {
const {EmberAdapter} = await import("./ember/adapter/emberAdapter.js");
return new EmberAdapter(networkOptions, serialPortOptions, backupPath, adapterOptions);
}
case "deconz": {
const {DeconzAdapter} = await import("./deconz/adapter/deconzAdapter.js");
return new DeconzAdapter(networkOptions, serialPortOptions, backupPath, adapterOptions);
}
case "zigate": {
const {ZiGateAdapter} = await import("./zigate/adapter/zigateAdapter.js");
return new ZiGateAdapter(networkOptions, serialPortOptions, backupPath, adapterOptions);
}
case "zboss": {
const {ZBOSSAdapter} = await import("./zboss/adapter/zbossAdapter.js");
return new ZBOSSAdapter(networkOptions, serialPortOptions, backupPath, adapterOptions);
}
case "zoh": {
const {ZoHAdapter} = await import("./zoh/adapter/zohAdapter.js");
return new ZoHAdapter(networkOptions, serialPortOptions, backupPath, adapterOptions);
}
// @deprecated
case "ezsp": {
const {EZSPAdapter} = await import("./ezsp/adapter/ezspAdapter.js");
return new EZSPAdapter(networkOptions, serialPortOptions, backupPath, adapterOptions);
}
default: {
throw new Error(`Adapter '${adapter}' does not exists, possible options: zstack, ember, deconz, zigate, zboss, zoh, ezsp`);
}
}
}
public abstract start(): Promise<TsType.StartResult>;
public abstract stop(): Promise<void>;
public abstract getCoordinatorIEEE(): Promise<string>;
public abstract getCoordinatorVersion(): Promise<TsType.CoordinatorVersion>;
public abstract reset(type: "soft" | "hard"): Promise<void>;
public abstract supportsBackup(): Promise<boolean>;
public abstract backup(ieeeAddressesInDatabase: string[]): Promise<Models.Backup>;
public abstract getNetworkParameters(): Promise<TsType.NetworkParameters>;
public abstract addInstallCode(ieeeAddress: string, key: Buffer, hashed: boolean): Promise<void>;
public abstract waitFor(
networkAddress: number | undefined,
endpoint: number,
frameType: Zcl.FrameType,
direction: Zcl.Direction,
transactionSequenceNumber: number | undefined,
clusterID: number,
commandIdentifier: number,
timeout: number,
): {promise: Promise<AdapterEvents.ZclPayload>; cancel: () => void};
/**
* ZDO
*/
public abstract sendZdo(
ieeeAddress: string,
networkAddress: number,
clusterId: Zdo.ClusterId,
payload: Buffer,
disableResponse: true,
): Promise<void>;
public abstract sendZdo<K extends keyof ZdoTypes.RequestToResponseMap>(
ieeeAddress: string,
networkAddress: number,
clusterId: K,
payload: Buffer,
disableResponse: false,
): Promise<ZdoTypes.RequestToResponseMap[K]>;
public abstract sendZdo<K extends keyof ZdoTypes.RequestToResponseMap>(
ieeeAddress: string,
networkAddress: number,
clusterId: K,
payload: Buffer,
disableResponse: boolean,
): Promise<ZdoTypes.RequestToResponseMap[K] | undefined>;
public abstract permitJoin(seconds: number, networkAddress?: number): Promise<void>;
/**
* ZCL
*/
public abstract sendZclFrameToEndpoint(
ieeeAddr: string,
networkAddress: number,
endpoint: number,
zclFrame: Zcl.Frame,
timeout: number,
disableResponse: boolean,
disableRecovery: boolean,
sourceEndpoint?: number,
): Promise<AdapterEvents.ZclPayload | undefined>;
public abstract sendZclFrameToGroup(groupID: number, zclFrame: Zcl.Frame, sourceEndpoint?: number): Promise<void>;
public abstract sendZclFrameToAll(endpoint: number, zclFrame: Zcl.Frame, sourceEndpoint: number, destination: BroadcastAddress): Promise<void>;
/**
* InterPAN
*/
public abstract setChannelInterPAN(channel: number): Promise<void>;
public abstract sendZclFrameInterPANToIeeeAddr(zclFrame: Zcl.Frame, ieeeAddress: string): Promise<void>;
public abstract sendZclFrameInterPANBroadcast(zclFrame: Zcl.Frame, timeout: number): Promise<AdapterEvents.ZclPayload>;
public abstract restoreChannelInterPAN(): Promise<void>;
}
export default Adapter;