/* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT DIRECTLY. */

import { Family, UnitOfMeasure } from "../../../Definitions/Global/index.js";
import type { NodeInfo } from "../../../Model/NodeInfo.js";
import { ISY } from "../../../ISY.js";
import { ISYNode } from "../../../ISYNode.js";
import { ISYDeviceNode } from "../../ISYDeviceNode.js";
import { Base } from "../index.js";
import { Driver } from "../../../Definitions/Global/Drivers.js";
import type { IntRange } from "type-fest";
import { ZigBee } from "../../../Definitions/index.js";
import { NodeFactory } from "../../NodeFactory.js";

type Commands = ColorHueSat.Commands.Type;
type Drivers = ColorHueSat.Drivers.Type;
type Events = ColorHueSat.Events.Type;

export class ColorHueSat extends Base<Drivers, Commands, Events> implements ColorHueSat.Interface {
	public override readonly commands = {
		MOVETO: this.moveTo,
		MOVETOHUE: this.moveToHue,
		MOVETOSAT: this.moveToSaturation,
		MOVEHUE: this.moveHue,
		MOVESAT: this.moveSaturation,
		STEPHUE: this.stepHue,
		STEPSAT: this.stepSaturation,
		STOP: this.stop,
		EHUE: this.updateEnhancedHue,
		QUERY: this.query
	};
	static override nodeDefId = "106";
	static override implements = ['106'];
	declare readonly nodeDefId: '106';
	constructor (isy: ISY, nodeInfo: NodeInfo<Family.ZigBee>) {
		super(isy, nodeInfo);
		this.drivers.ST = Driver.create("ST", this, nodeInfo.state['ST'], { uom: UnitOfMeasure.RawValue, label: "Hue", name: "hue" });
		this.drivers.GV1 = Driver.create("GV1", this, nodeInfo.state['GV1'], { uom: UnitOfMeasure.RawValue, label: "Saturation", name: "saturation" });
		this.drivers.GV2 = Driver.create("GV2", this, nodeInfo.state['GV2'], { uom: UnitOfMeasure.OffOn, label: "Enhanced Hue", name: "enhancedHue" });
	}
	async moveTo(hue: number, saturation: number, duration?: number) { return this.sendCommand("MOVETO", { HUE: [hue, UnitOfMeasure.DegreeOfHue0To360], SAT: [saturation, UnitOfMeasure.Percent], DUR: [duration, UnitOfMeasure.DurationInSeconds] }); }
	async moveToHue(hue: number, direction?: ZigBee.ColorControlDirection, duration?: number) { return this.sendCommand("MOVETOHUE", { HUE: [hue, UnitOfMeasure.DegreeOfHue0To360], DIR: [direction, UnitOfMeasure.Index], DUR: [duration, UnitOfMeasure.DurationInSeconds] }); }
	async moveToSaturation(saturation: number, duration?: number) { return this.sendCommand("MOVETOSAT", { SAT: [saturation, UnitOfMeasure.Percent], DUR: [duration, UnitOfMeasure.DurationInSeconds] }); }
	async moveHue(mode: ZigBee.ColorControlMoveMode, rate?: number) { return this.sendCommand("MOVEHUE", { MODE: [mode, UnitOfMeasure.Index], RATE: [rate, UnitOfMeasure.RawValue] }); }
	async moveSaturation(mode: ZigBee.ColorControlMoveMode, rate?: number) { return this.sendCommand("MOVESAT", { MODE: [mode, UnitOfMeasure.Index], RATE: [rate, UnitOfMeasure.RawValue] }); }
	async stepHue(mode: ZigBee.ColorControlStepMode, stepSize?: number, duration?: number) { return this.sendCommand("STEPHUE", { MODE: [mode, UnitOfMeasure.Index], SIZE: [stepSize, UnitOfMeasure.DegreeOfHue0To360], DUR: [duration, UnitOfMeasure.DurationInSeconds] }); }
	async stepSaturation(mode: ZigBee.ColorControlStepMode, stepSize?: number, duration?: number) { return this.sendCommand("STEPSAT", { MODE: [mode, UnitOfMeasure.Index], SIZE: [stepSize, UnitOfMeasure.Percent], DUR: [duration, UnitOfMeasure.DurationInSeconds] }); }
	async stop() { return this.sendCommand("STOP"); }
	async updateEnhancedHue(value: (0 | 100)) { return this.sendCommand("EHUE", [value, UnitOfMeasure.OffOn]); }
	async query() { return this.sendCommand("QUERY"); }
	public get hue(): number {
		return this.drivers.ST?.value;
	}
	public get saturation(): IntRange<0, 1> {
		return this.drivers.GV1?.value;
	}
	public get enhancedHue(): (0 | 100) {
		return this.drivers.GV2?.value;
	}
}

NodeFactory.register(ColorHueSat);

export namespace ColorHueSat {
	export interface Interface extends Omit<InstanceType<typeof ColorHueSat>, keyof ISYDeviceNode<any, any, any, any>> {
	}
	export function is(node: ISYNode<any, any, any, any>): node is ColorHueSat {
		return ['106'].includes(node.nodeDefId);
	}
	export function isImplementedBy(node: ISYNode<any, any, any, any>): node is ColorHueSat {
		return ['106'].includes(node.nodeDefId);
	}
	export function create(isy: ISY, nodeInfo: NodeInfo<Family.ZigBee>) {
		return new ColorHueSat(isy, nodeInfo);
	}
	export const Node = ColorHueSat;
	export const Class = ColorHueSat;
	export namespace Commands {
		export type Type = {
			MOVETO: ((HUE: number, SAT: number, DUR?: number) => Promise<boolean>) & {
				label: "Move To";
				name: "moveTo";
			};
			MOVETOHUE: ((HUE: number, DIR?: ZigBee.ColorControlDirection, DUR?: number) => Promise<boolean>) & {
				label: "Move To Hue";
				name: "moveToHue";
			};
			MOVETOSAT: ((SAT: number, DUR?: number) => Promise<boolean>) & {
				label: "Move To Saturation";
				name: "moveToSaturation";
			};
			MOVEHUE: ((MODE: ZigBee.ColorControlMoveMode, RATE?: number) => Promise<boolean>) & {
				label: "Move Hue";
				name: "moveHue";
			};
			MOVESAT: ((MODE: ZigBee.ColorControlMoveMode, RATE?: number) => Promise<boolean>) & {
				label: "Move Saturation";
				name: "moveSaturation";
			};
			STEPHUE: ((MODE: ZigBee.ColorControlStepMode, SIZE?: number, DUR?: number) => Promise<boolean>) & {
				label: "Step Hue";
				name: "stepHue";
			};
			STEPSAT: ((MODE: ZigBee.ColorControlStepMode, SIZE?: number, DUR?: number) => Promise<boolean>) & {
				label: "Step Saturation";
				name: "stepSaturation";
			};
			STOP: (() => Promise<boolean>) & {
				label: "Stop";
				name: "stop";
			};
			EHUE: ((value: (0 | 100)) => Promise<boolean>) & {
				label: "Enhanced Hue";
				name: "updateEnhancedHue";
			};
			QUERY: (() => Promise<boolean>) & {
				label: "Query";
				name: "query";
			};
		};
	}
	export enum Commands {
		moveTo = 'MOVETO',
		moveToHue = 'MOVETOHUE',
		moveToSaturation = 'MOVETOSAT',
		moveHue = 'MOVEHUE',
		moveSaturation = 'MOVESAT',
		stepHue = 'STEPHUE',
		stepSaturation = 'STEPSAT',
		stop = 'STOP',
		updateEnhancedHue = 'EHUE',
		query = 'QUERY'
	}
	export namespace Drivers {
		export type Type = {
			ST: {
				uom: UnitOfMeasure.RawValue;
				value: number;
				label: "Hue";
				name: "hue";
			};
			GV1: {
				uom: UnitOfMeasure.RawValue;
				value: IntRange<0, 1>;
				label: "Saturation";
				name: "saturation";
			};
			GV2: {
				uom: UnitOfMeasure.OffOn;
				value: (0 | 100);
				label: "Enhanced Hue";
				name: "enhancedHue";
			};
		};
	}
	export enum Drivers {
		hue = 'ST',
		saturation = 'GV1',
		enhancedHue = 'GV2'
	}
	export namespace Events {
		export type Type = {};
	}
	export enum Events {
	}
}
