zigbee-herdsman-zigate
Version:
An open source ZigBee gateway solution with node.js.
191 lines (157 loc) • 6.29 kB
text/typescript
import {DataType, Cluster, Foundation} from './definition';
import * as TsType from './tstype';
const DataTypeValueType = {
discrete: [
DataType.data8, DataType.data16, DataType.data24, DataType.data32, DataType.data40,
DataType.data48, DataType.data56, DataType.data64, DataType.boolean,
DataType.bitmap8, DataType.bitmap16, DataType.bitmap24, DataType.bitmap32, DataType.bitmap40,
DataType.bitmap48, DataType.bitmap56, DataType.bitmap64, DataType.enum8, DataType.enum16,
DataType.octetStr, DataType.charStr, DataType.longOctetStr, DataType.longCharStr, DataType.array,
DataType.struct, DataType.set, DataType.bag, DataType.clusterId, DataType.attrId, DataType.bacOid,
DataType.ieeeAddr, DataType.secKey,
],
analog:[
DataType.uint8, DataType.uint16, DataType.uint24, DataType.uint32, DataType.uint40,
DataType.uint48, DataType.uint56,
DataType.int8, DataType.int16, DataType.int24, DataType.int32, DataType.int40,
DataType.int48, DataType.int56, DataType.semiPrec, DataType.singlePrec, DataType.doublePrec,
DataType.tod, DataType.date, DataType.utc,
],
};
function IsDataTypeAnalogOrDiscrete(dataType: DataType): 'ANALOG' | 'DISCRETE' {
if (DataTypeValueType.discrete.includes(dataType)) {
return 'DISCRETE';
} else if (DataTypeValueType.analog.includes(dataType)) {
return 'ANALOG';
} else {
throw new Error(`Don't know value type for '${DataType[dataType]}'`);
}
}
function getCluster(key: string | number, manufacturerCode: number = null): TsType.Cluster {
let name: string;
if (typeof key === 'number') {
if (manufacturerCode) {
for (const [clusterName, cluster] of Object.entries(Cluster)) {
if (cluster.ID === key && cluster.manufacturerCode === manufacturerCode) {
name = clusterName;
break;
}
}
}
if (!name) {
for (const [clusterName, cluster] of Object.entries(Cluster)) {
if (cluster.ID === key) {
name = clusterName;
break;
}
}
}
} else {
name = key;
}
const cluster = Cluster[name];
if (!cluster) {
throw new Error(`Cluster with key '${key}' does not exist`);
}
// eslint-disable-next-line
let attributes: {[s: string]: TsType.Attribute} = Object.assign({}, ...Object.entries(cluster.attributes).map(([k, v]): any => ({[k]: {...v, name: k}})));
// eslint-disable-next-line
const commands: {[s: string]: TsType.Command} = Object.assign({}, ...Object.entries(cluster.commands).map(([k, v]): any => ({[k]: {...v, name: k}})));
// eslint-disable-next-line
const commandsResponse: {[s: string]: TsType.Command} = Object.assign({}, ...Object.entries(cluster.commandsResponse).map(([k, v]): any => ({[k]: {...v, name: k}})));
const getAttribute = (key: number | string): TsType.Attribute => {
let result: TsType.Attribute = null;
if (typeof key === 'number') {
if (manufacturerCode) {
result = Object.values(attributes).find((a): boolean => {
return a.ID === key && a.manufacturerCode === manufacturerCode;
});
}
if (!result) {
result = Object.values(attributes).find((a): boolean => a.ID === key);
}
} else {
result = Object.values(attributes).find((a): boolean => a.name === key);
}
if (!result) {
throw new Error(`Cluster '${name}' has no attribute '${key}'`);
}
return result;
};
const hasAttribute = (key: number | string): boolean => {
let result: TsType.Attribute = null;
if (typeof key === 'number') {
result = Object.values(attributes).find((a): boolean => a.ID === key);
} else {
result = Object.values(attributes).find((a): boolean => a.name === key);
}
return !!result;
};
const getCommand = (key: number | string): TsType.Command => {
let result: TsType.Command = null;
if (typeof key === 'number') {
result = Object.values(commands).find((a): boolean => a.ID === key);
} else {
result = Object.values(commands).find((a): boolean => a.name === key);
}
if (!result) {
throw new Error(`Cluster '${name}' has no command '${key}'`);
}
return result;
};
const getCommandResponse = (key: number | string): TsType.Command => {
let result: TsType.Command = null;
if (typeof key === 'number') {
result = Object.values(commandsResponse).find((a): boolean => a.ID === key);
} else {
result = Object.values(commandsResponse).find((a): boolean => a.name === key);
}
if (!result) {
throw new Error(`Cluster '${name}' has no command response '${key}'`);
}
return result;
};
return {
ID: cluster.ID,
attributes,
name,
commands,
// eslint-disable-next-line
commandsResponse: Object.assign({}, ...Object.entries(cluster.commandsResponse).map(([k, v]): any => ({[k]: {...v, name: k}}))),
getAttribute,
hasAttribute,
getCommand,
getCommandResponse,
};
}
function getGlobalCommand(key: number | string): TsType.Command {
let name;
if (typeof key === 'number') {
for (const commandName in Foundation) {
if (Foundation[commandName].ID === key) {
name = commandName;
break;
}
}
} else {
name = key;
}
const command = Foundation[name];
if (!command) {
throw new Error(`Global command with key '${key}' does not exist`);
}
const result: TsType.Command = {
ID: command.ID,
name,
parameters: command.parameters,
};
if (command.hasOwnProperty('response')) {
result.response = command.response;
}
return result;
}
export {
getCluster,
getGlobalCommand,
IsDataTypeAnalogOrDiscrete,
};