"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var NabuCasa_exports = {};
__export(NabuCasa_exports, {
  ControllerProprietary_NabuCasa: () => ControllerProprietary_NabuCasa,
  FUNC_ID_NABUCASA: () => FUNC_ID_NABUCASA,
  NabuCasaCommand: () => NabuCasaCommand,
  NabuCasaConfigKey: () => NabuCasaConfigKey,
  NabuCasaIndicationSeverity: () => NabuCasaIndicationSeverity
});
module.exports = __toCommonJS(NabuCasa_exports);
var import_cc = require("@zwave-js/cc");
var import_core = require("@zwave-js/core");
var import_serial = require("@zwave-js/serial");
var import_shared = require("@zwave-js/shared");
var import_math = require("alcalzone-shared/math");
const FUNC_ID_NABUCASA = import_serial.FunctionType.Proprietary_F0;
var NabuCasaCommand;
(function(NabuCasaCommand2) {
  NabuCasaCommand2[NabuCasaCommand2["GetSupportedCommands"] = 0] = "GetSupportedCommands";
  NabuCasaCommand2[NabuCasaCommand2["GetLED"] = 1] = "GetLED";
  NabuCasaCommand2[NabuCasaCommand2["SetLED"] = 2] = "SetLED";
  NabuCasaCommand2[NabuCasaCommand2["ReadGyro"] = 3] = "ReadGyro";
  NabuCasaCommand2[NabuCasaCommand2["SetSystemIndication"] = 4] = "SetSystemIndication";
  NabuCasaCommand2[NabuCasaCommand2["GetConfig"] = 5] = "GetConfig";
  NabuCasaCommand2[NabuCasaCommand2["SetConfig"] = 6] = "SetConfig";
  NabuCasaCommand2[NabuCasaCommand2["GetLEDBinary"] = 7] = "GetLEDBinary";
  NabuCasaCommand2[NabuCasaCommand2["SetLEDBinary"] = 8] = "SetLEDBinary";
})(NabuCasaCommand || (NabuCasaCommand = {}));
var NabuCasaIndicationSeverity;
(function(NabuCasaIndicationSeverity2) {
  NabuCasaIndicationSeverity2[NabuCasaIndicationSeverity2["None"] = 0] = "None";
  NabuCasaIndicationSeverity2[NabuCasaIndicationSeverity2["Warning"] = 1] = "Warning";
  NabuCasaIndicationSeverity2[NabuCasaIndicationSeverity2["Error"] = 2] = "Error";
})(NabuCasaIndicationSeverity || (NabuCasaIndicationSeverity = {}));
var NabuCasaConfigKey;
(function(NabuCasaConfigKey2) {
  NabuCasaConfigKey2[NabuCasaConfigKey2["EnableTiltIndicator"] = 0] = "EnableTiltIndicator";
})(NabuCasaConfigKey || (NabuCasaConfigKey = {}));
const binarySwitchCurrentValue = import_cc.BinarySwitchCCValues.currentValue.id;
const binarySwitchCurrentValueTranslated = {
  ...binarySwitchCurrentValue,
  commandClassName: (0, import_core.getCCName)(binarySwitchCurrentValue.commandClass),
  propertyName: "Current value"
};
const binarySwitchTargetValue = import_cc.BinarySwitchCCValues.targetValue.id;
const binarySwitchTargetValueTranslated = {
  ...binarySwitchTargetValue,
  commandClassName: (0, import_core.getCCName)(binarySwitchTargetValue.commandClass),
  propertyName: "Target value"
};
const configEnableTiltIndicator = import_cc.ConfigurationCCValues.paramInformation(NabuCasaConfigKey.EnableTiltIndicator).id;
const configEnableTiltIndicatorTranslated = {
  ...configEnableTiltIndicator,
  commandClassName: (0, import_core.getCCName)(configEnableTiltIndicator.commandClass),
  propertyName: "enableTiltIndicator"
};
const configEnableTiltIndicatorMeta = {
  type: "number",
  readable: true,
  writeable: true,
  min: 0,
  max: 1,
  allowManualEntry: false,
  default: 1,
  format: import_core.ConfigValueFormat.UnsignedInteger,
  label: "Enable Tilt Indicator",
  states: {
    0: "Disable",
    1: "Enable"
  },
  valueSize: 1
};
const WHITE = { r: 255, g: 255, b: 255 };
const BLACK = { r: 0, g: 2, b: 0 };
function parseGyro(msg) {
  const x = (0, import_math.roundTo)(msg.payload.readInt16BE(1) / 1024 * 9.77, 2);
  const y = (0, import_math.roundTo)(msg.payload.readInt16BE(3) / 1024 * 9.77, 2);
  const z = (0, import_math.roundTo)(msg.payload.readInt16BE(5) / 1024 * 9.77, 2);
  return { x, y, z };
}
__name(parseGyro, "parseGyro");
class ControllerProprietary_NabuCasa {
  static {
    __name(this, "ControllerProprietary_NabuCasa");
  }
  constructor(driver, controller) {
    this.driver = driver;
    this.controller = controller;
  }
  driver;
  controller;
  supportedCommands;
  async interview() {
    const valueDB = this.controller.valueDB;
    const supported = await this.getSupportedCommands();
    this.supportedCommands = supported;
    if (supported.includes(NabuCasaCommand.GetLEDBinary) || supported.includes(NabuCasaCommand.GetLED)) {
      valueDB.setMetadata(import_cc.BinarySwitchCCValues.currentValue.id, import_cc.BinarySwitchCCValues.currentValue.meta);
      valueDB.setMetadata(import_cc.BinarySwitchCCValues.targetValue.id, import_cc.BinarySwitchCCValues.targetValue.meta);
      valueDB.setMetadata(import_cc.ColorSwitchCCValues.currentColor.id, void 0);
      valueDB.removeValue(import_cc.ColorSwitchCCValues.currentColor.id);
      valueDB.setMetadata(import_cc.ColorSwitchCCValues.targetColor.id, void 0);
      valueDB.removeValue(import_cc.ColorSwitchCCValues.targetColor.id);
      valueDB.setMetadata(import_cc.ColorSwitchCCValues.hexColor.id, void 0);
      valueDB.removeValue(import_cc.ColorSwitchCCValues.hexColor.id);
      valueDB.setMetadata(import_cc.ColorSwitchCCValues.currentColorChannel(import_cc.ColorComponent.Red).id, void 0);
      valueDB.removeValue(import_cc.ColorSwitchCCValues.currentColorChannel(import_cc.ColorComponent.Red).id);
      valueDB.setMetadata(import_cc.ColorSwitchCCValues.currentColorChannel(import_cc.ColorComponent.Green).id, void 0);
      valueDB.removeValue(import_cc.ColorSwitchCCValues.currentColorChannel(import_cc.ColorComponent.Green).id);
      valueDB.setMetadata(import_cc.ColorSwitchCCValues.currentColorChannel(import_cc.ColorComponent.Blue).id, void 0);
      valueDB.removeValue(import_cc.ColorSwitchCCValues.currentColorChannel(import_cc.ColorComponent.Blue).id);
    }
    if (supported.includes(NabuCasaCommand.GetLEDBinary)) {
      const state = await this.getLEDBinary();
      this.persistLEDState(valueDB, state);
    } else if (supported.includes(NabuCasaCommand.GetLED)) {
      const rgb = await this.getLED();
      this.persistRGBValue(valueDB, rgb);
    }
    if (supported.includes(NabuCasaCommand.GetConfig)) {
      const enableTiltIndicator = await this.getConfig(NabuCasaConfigKey.EnableTiltIndicator);
      valueDB.setMetadata(configEnableTiltIndicator, configEnableTiltIndicatorMeta);
      valueDB.setValue(configEnableTiltIndicator, enableTiltIndicator);
    }
  }
  persistRGBValue(valueDB, rgb) {
    valueDB.setValue(import_cc.BinarySwitchCCValues.currentValue.id, rgb.r > BLACK.r || rgb.g > BLACK.g || rgb.b > BLACK.b);
    valueDB.setValue(import_cc.BinarySwitchCCValues.targetValue.id, rgb.r > BLACK.r || rgb.g > BLACK.g || rgb.b > BLACK.b);
  }
  persistLEDState(valueDB, state) {
    valueDB.setValue(import_cc.BinarySwitchCCValues.currentValue.id, state);
    valueDB.setValue(import_cc.BinarySwitchCCValues.targetValue.id, state);
  }
  async getSupportedCommands() {
    const getSupportedCmd = new import_serial.Message({
      type: import_serial.MessageType.Request,
      functionType: FUNC_ID_NABUCASA,
      payload: import_shared.Bytes.from([NabuCasaCommand.GetSupportedCommands]),
      expectedResponse: /* @__PURE__ */ __name((self, msg) => {
        return msg.functionType === FUNC_ID_NABUCASA && msg.type === import_serial.MessageType.Response && msg.payload[0] === NabuCasaCommand.GetSupportedCommands;
      }, "expectedResponse")
    });
    const result = await this.driver.sendMessage(getSupportedCmd, {
      priority: import_core.MessagePriority.Controller,
      supportCheck: false
    });
    const supported = result.payload.subarray(1);
    return (0, import_core.parseBitMask)(supported, NabuCasaCommand.GetSupportedCommands);
  }
  async getLED() {
    const getLEDStateCmd = new import_serial.Message({
      type: import_serial.MessageType.Request,
      functionType: FUNC_ID_NABUCASA,
      payload: import_shared.Bytes.from([NabuCasaCommand.GetLED]),
      expectedResponse: /* @__PURE__ */ __name((self, msg) => {
        return msg.functionType === FUNC_ID_NABUCASA && msg.type === import_serial.MessageType.Response && msg.payload[0] === NabuCasaCommand.GetLED;
      }, "expectedResponse")
    });
    const resultPromise = this.driver.sendMessage(getLEDStateCmd, {
      priority: import_core.MessagePriority.Controller,
      supportCheck: false
    });
    const { payload: result } = await resultPromise;
    return {
      r: result[1],
      g: result[2],
      b: result[3]
    };
  }
  async setLED(rgb) {
    const payload = import_shared.Bytes.from([
      NabuCasaCommand.SetLED,
      rgb.r,
      rgb.g,
      rgb.b,
      1
      // SOLID
    ]);
    const setLEDStateCmd = new import_serial.Message({
      type: import_serial.MessageType.Request,
      functionType: FUNC_ID_NABUCASA,
      payload,
      expectedResponse: /* @__PURE__ */ __name((self, msg) => {
        return msg.functionType === FUNC_ID_NABUCASA && msg.type === import_serial.MessageType.Response && msg.payload[0] === NabuCasaCommand.SetLED;
      }, "expectedResponse")
    });
    const result = await this.driver.sendMessage(setLEDStateCmd, {
      priority: import_core.MessagePriority.Controller,
      supportCheck: false
    });
    const success = !!result.payload[1];
    return success;
  }
  async getLEDBinary() {
    const getLEDStateCmd = new import_serial.Message({
      type: import_serial.MessageType.Request,
      functionType: FUNC_ID_NABUCASA,
      payload: import_shared.Bytes.from([NabuCasaCommand.GetLEDBinary]),
      expectedResponse: /* @__PURE__ */ __name((self, msg) => {
        return msg.functionType === FUNC_ID_NABUCASA && msg.type === import_serial.MessageType.Response && msg.payload[0] === NabuCasaCommand.GetLEDBinary;
      }, "expectedResponse")
    });
    const resultPromise = this.driver.sendMessage(getLEDStateCmd, {
      priority: import_core.MessagePriority.Controller,
      supportCheck: false
    });
    const { payload: result } = await resultPromise;
    return !!result[1];
  }
  async setLEDBinary(state) {
    const payload = import_shared.Bytes.from([
      NabuCasaCommand.SetLEDBinary,
      state ? 1 : 0
    ]);
    const setLEDStateCmd = new import_serial.Message({
      type: import_serial.MessageType.Request,
      functionType: FUNC_ID_NABUCASA,
      payload,
      expectedResponse: /* @__PURE__ */ __name((self, msg) => {
        return msg.functionType === FUNC_ID_NABUCASA && msg.type === import_serial.MessageType.Response && msg.payload[0] === NabuCasaCommand.SetLEDBinary;
      }, "expectedResponse")
    });
    const result = await this.driver.sendMessage(setLEDStateCmd, {
      priority: import_core.MessagePriority.Controller,
      supportCheck: false
    });
    const success = !!result.payload[1];
    return success;
  }
  async readGyro() {
    const readGyroCmd = new import_serial.Message({
      type: import_serial.MessageType.Request,
      functionType: FUNC_ID_NABUCASA,
      payload: import_shared.Bytes.from([NabuCasaCommand.ReadGyro]),
      expectedResponse: /* @__PURE__ */ __name((self, msg) => {
        return msg.functionType === FUNC_ID_NABUCASA && msg.type === import_serial.MessageType.Response && msg.payload[0] === NabuCasaCommand.ReadGyro;
      }, "expectedResponse")
    });
    const callbackPromise = this.driver.waitForMessage((msg) => {
      return msg.functionType === FUNC_ID_NABUCASA && msg.type === import_serial.MessageType.Request && msg.payload[0] === NabuCasaCommand.ReadGyro;
    }, 1e3);
    const response = await this.driver.sendMessage(readGyroCmd, {
      priority: import_core.MessagePriority.Controller,
      supportCheck: false
    });
    if (!response.payload[0]) {
      return;
    }
    const callback = await callbackPromise;
    return parseGyro(callback);
  }
  async setSystemIndication(severity) {
    const payload = import_shared.Bytes.from([
      NabuCasaCommand.SetSystemIndication,
      severity
    ]);
    const systemIndicationCmd = new import_serial.Message({
      type: import_serial.MessageType.Request,
      functionType: FUNC_ID_NABUCASA,
      payload,
      expectedResponse: /* @__PURE__ */ __name((self, msg) => {
        return msg.functionType === FUNC_ID_NABUCASA && msg.type === import_serial.MessageType.Response && msg.payload[0] === NabuCasaCommand.SetSystemIndication;
      }, "expectedResponse")
    });
    const result = await this.driver.sendMessage(systemIndicationCmd, {
      priority: import_core.MessagePriority.Controller,
      supportCheck: false
    });
    const success = !!result.payload[1];
    return success;
  }
  async getConfig(key) {
    const payload = import_shared.Bytes.from([
      NabuCasaCommand.GetConfig,
      key
    ]);
    const getConfigCmd = new import_serial.Message({
      type: import_serial.MessageType.Request,
      functionType: FUNC_ID_NABUCASA,
      payload,
      expectedResponse: /* @__PURE__ */ __name((self, msg) => {
        return msg.functionType === FUNC_ID_NABUCASA && msg.type === import_serial.MessageType.Response && msg.payload[0] === NabuCasaCommand.GetConfig && msg.payload[1] === key;
      }, "expectedResponse")
    });
    const resultPromise = this.driver.sendMessage(getConfigCmd, {
      priority: import_core.MessagePriority.Controller,
      supportCheck: false
    });
    const { payload: result } = await resultPromise;
    const size = result[2];
    if (result.length > 3 + size) {
      return Number.NEGATIVE_INFINITY;
    } else {
      return result.readIntBE(3, size);
    }
  }
  async setConfig(key, value) {
    const payload = import_shared.Bytes.from([
      NabuCasaCommand.SetConfig,
      key,
      // For now, only 1 byte is supported
      1,
      value
    ]);
    const setConfigCmd = new import_serial.Message({
      type: import_serial.MessageType.Request,
      functionType: FUNC_ID_NABUCASA,
      payload,
      expectedResponse: /* @__PURE__ */ __name((self, msg) => {
        return msg.functionType === FUNC_ID_NABUCASA && msg.type === import_serial.MessageType.Response && msg.payload[0] === NabuCasaCommand.SetConfig;
      }, "expectedResponse")
    });
    const result = await this.driver.sendMessage(setConfigCmd, {
      priority: import_core.MessagePriority.Controller,
      supportCheck: false
    });
    const success = !!result.payload[1];
    return success;
  }
  getDefinedValueIDs() {
    return [
      // LED: Binary Switch
      binarySwitchCurrentValueTranslated,
      binarySwitchTargetValueTranslated,
      // Configuration
      configEnableTiltIndicatorTranslated
    ];
  }
  async pollValue(valueId) {
    if (import_cc.BinarySwitchCCValues.targetValue.is(valueId) || import_cc.BinarySwitchCCValues.currentValue.is(valueId)) {
      if (this.supportedCommands?.includes(NabuCasaCommand.GetLEDBinary)) {
        const state = await this.getLEDBinary();
        this.persistLEDState(this.controller.valueDB, state);
        return state;
      } else {
        const rgb = await this.getLED();
        this.persistRGBValue(this.controller.valueDB, rgb);
        return rgb;
      }
    }
    if (import_cc.ConfigurationCCValues.paramInformation.is(valueId) && valueId.propertyKey == void 0) {
      switch (valueId.property) {
        case NabuCasaConfigKey.EnableTiltIndicator:
          break;
        default:
          return void 0;
      }
      const value = await this.getConfig(valueId.property);
      if (value != void 0) {
        this.controller.valueDB.setValue(valueId, value);
        return value;
      }
    }
  }
  async setValue(valueId, value) {
    if (import_cc.BinarySwitchCCValues.targetValue.is(valueId) && typeof value === "boolean") {
      if (this.supportedCommands?.includes(NabuCasaCommand.SetLEDBinary)) {
        await this.setLEDBinary(value);
        this.persistLEDState(this.controller.valueDB, value);
        return { status: import_cc.SetValueStatus.Success };
      } else {
        const rgb = value ? WHITE : BLACK;
        await this.setLED(rgb);
        this.persistRGBValue(this.controller.valueDB, rgb);
        return { status: import_cc.SetValueStatus.Success };
      }
    }
    if (import_cc.ConfigurationCCValues.paramInformation.is(valueId) && valueId.propertyKey == void 0 && typeof value === "number" && [
      NabuCasaConfigKey.EnableTiltIndicator
    ].includes(valueId.property)) {
      await this.setConfig(valueId.property, value);
      this.controller.valueDB.setValue(valueId, value);
      return { status: import_cc.SetValueStatus.Success };
    }
    return { status: import_cc.SetValueStatus.NoDeviceSupport };
  }
  // eslint-disable-next-line @typescript-eslint/require-await
  async handleUnsolicited(_msg) {
    return false;
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  ControllerProprietary_NabuCasa,
  FUNC_ID_NABUCASA,
  NabuCasaCommand,
  NabuCasaConfigKey,
  NabuCasaIndicationSeverity
});
//# sourceMappingURL=NabuCasa.js.map
