inventoresed
Version:
Z-Wave driver written entirely in JavaScript/TypeScript
102 lines (90 loc) • 2.97 kB
text/typescript
import type { ZWaveApplicationHost } from "@zwave-js/host";
import { isArray } from "alcalzone-shared/typeguards";
import { CommandClass, CommandClassOptions } from "./CommandClass";
/** Defines the static side of an encapsulating command class */
export interface EncapsulatingCommandClassStatic {
new (
applHost: ZWaveApplicationHost,
options: CommandClassOptions,
): EncapsulatingCommandClass;
encapsulate(
applHost: ZWaveApplicationHost,
cc: CommandClass,
): EncapsulatingCommandClass;
}
export type EncapsulatedCommandClass = CommandClass & {
encapsulatingCC: EncapsulatingCommandClass;
};
export type EncapsulatingCommandClass = CommandClass & {
constructor: EncapsulatingCommandClassStatic;
encapsulated: EncapsulatedCommandClass;
};
/**
* Tests if a given CC statically implements the EncapsulatingCommandClassStatic interface
* @param cc The command class instance to test
*/
export function isEncapsulatingCommandClass(
cc: any,
): cc is CommandClass & EncapsulatingCommandClass {
// To satisfy the criterion, cc must be a CommandClass
if (!(cc instanceof CommandClass)) return false;
// The encapsulated property must be a CommandClass
if (!((cc as any).encapsulated instanceof CommandClass)) {
return false;
}
// Walk up the static side of the prototype chain to see if it has the required methods
let proto: any = Object.getPrototypeOf(cc.constructor);
while (proto) {
if (typeof proto.encapsulate === "function") {
return true;
}
proto = Object.getPrototypeOf(proto);
}
return false;
}
/** Defines the static side of an encapsulating command class */
export interface MultiEncapsulatingCommandClassStatic {
new (
applHost: ZWaveApplicationHost,
options: CommandClassOptions,
): MultiEncapsulatingCommandClass;
requiresEncapsulation(cc: CommandClass): boolean;
encapsulate(
applHost: ZWaveApplicationHost,
CCs: CommandClass[],
): MultiEncapsulatingCommandClass;
}
export interface MultiEncapsulatingCommandClass {
constructor: MultiEncapsulatingCommandClassStatic;
encapsulated: EncapsulatedCommandClass[];
}
/**
* Tests if a given CC statically implements the EncapsulatingCommandClassStatic interface
* @param cc The command class instance to test
*/
export function isMultiEncapsulatingCommandClass(
cc: any,
): cc is CommandClass & MultiEncapsulatingCommandClass {
// To satisfy the criterion, cc must be a CommandClass
if (!(cc instanceof CommandClass)) return false;
// The encapsulated property must array of CCs
if (
!(
isArray((cc as any).encapsulated) &&
(cc as any).encapsulated.every(
(item: any) => item instanceof CommandClass,
)
)
) {
return false;
}
// Walk up the static side of the prototype chain to see if it has the required methods
let proto: any = Object.getPrototypeOf(cc.constructor);
while (proto) {
if (typeof proto.encapsulate === "function") {
return true;
}
proto = Object.getPrototypeOf(proto);
}
return false;
}