iobroker.homewizard 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +190 -0
- package/admin/homewizard.svg +6 -0
- package/admin/i18n/de/translations.json +16 -0
- package/admin/i18n/en/translations.json +16 -0
- package/admin/i18n/es/translations.json +16 -0
- package/admin/i18n/fr/translations.json +16 -0
- package/admin/i18n/it/translations.json +16 -0
- package/admin/i18n/nl/translations.json +16 -0
- package/admin/i18n/pl/translations.json +16 -0
- package/admin/i18n/pt/translations.json +16 -0
- package/admin/i18n/ru/translations.json +16 -0
- package/admin/i18n/uk/translations.json +16 -0
- package/admin/i18n/zh-cn/translations.json +16 -0
- package/admin/jsonConfig.json +99 -0
- package/build/lib/discovery.js +103 -0
- package/build/lib/discovery.js.map +7 -0
- package/build/lib/homewizard-client.js +193 -0
- package/build/lib/homewizard-client.js.map +7 -0
- package/build/lib/state-manager.js +749 -0
- package/build/lib/state-manager.js.map +7 -0
- package/build/lib/types.js +17 -0
- package/build/lib/types.js.map +7 -0
- package/build/lib/websocket-client.js +151 -0
- package/build/lib/websocket-client.js.map +7 -0
- package/build/main.js +441 -0
- package/build/main.js.map +7 -0
- package/io-package.json +136 -0
- package/package.json +77 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/lib/state-manager.ts"],
|
|
4
|
+
"sourcesContent": ["import type * as utils from \"@iobroker/adapter-core\";\nimport type {\n BatteryControl,\n DeviceConfig,\n Measurement,\n SystemInfo,\n} from \"./types\";\n\n/** Measurement field to state definition mapping */\ninterface MeasurementStateDef {\n /** Measurement field key */\n key: string;\n /** ioBroker state ID suffix */\n id: string;\n /** State display name */\n name: string;\n /** State value type */\n type: ioBroker.CommonType;\n /** ioBroker role */\n role: string;\n /** Unit string */\n unit?: string;\n}\n\n/**\n * Sanitize a string for use as ioBroker object ID\n *\n * @param str Raw string to sanitize\n */\nfunction sanitize(str: string): string {\n return str.replace(/[^a-zA-Z0-9_-]/g, \"_\").toLowerCase();\n}\n\nconst MEASUREMENT_STATE_DEFS: MeasurementStateDef[] = [\n // Power\n {\n key: \"power_w\",\n id: \"power_w\",\n name: \"Total power\",\n type: \"number\",\n role: \"value.power\",\n unit: \"W\",\n },\n {\n key: \"power_l1_w\",\n id: \"power_l1_w\",\n name: \"Power L1\",\n type: \"number\",\n role: \"value.power\",\n unit: \"W\",\n },\n {\n key: \"power_l2_w\",\n id: \"power_l2_w\",\n name: \"Power L2\",\n type: \"number\",\n role: \"value.power\",\n unit: \"W\",\n },\n {\n key: \"power_l3_w\",\n id: \"power_l3_w\",\n name: \"Power L3\",\n type: \"number\",\n role: \"value.power\",\n unit: \"W\",\n },\n // Voltage\n {\n key: \"voltage_v\",\n id: \"voltage_v\",\n name: \"Voltage\",\n type: \"number\",\n role: \"value.voltage\",\n unit: \"V\",\n },\n {\n key: \"voltage_l1_v\",\n id: \"voltage_l1_v\",\n name: \"Voltage L1\",\n type: \"number\",\n role: \"value.voltage\",\n unit: \"V\",\n },\n {\n key: \"voltage_l2_v\",\n id: \"voltage_l2_v\",\n name: \"Voltage L2\",\n type: \"number\",\n role: \"value.voltage\",\n unit: \"V\",\n },\n {\n key: \"voltage_l3_v\",\n id: \"voltage_l3_v\",\n name: \"Voltage L3\",\n type: \"number\",\n role: \"value.voltage\",\n unit: \"V\",\n },\n // Current\n {\n key: \"current_a\",\n id: \"current_a\",\n name: \"Current\",\n type: \"number\",\n role: \"value.current\",\n unit: \"A\",\n },\n {\n key: \"current_l1_a\",\n id: \"current_l1_a\",\n name: \"Current L1\",\n type: \"number\",\n role: \"value.current\",\n unit: \"A\",\n },\n {\n key: \"current_l2_a\",\n id: \"current_l2_a\",\n name: \"Current L2\",\n type: \"number\",\n role: \"value.current\",\n unit: \"A\",\n },\n {\n key: \"current_l3_a\",\n id: \"current_l3_a\",\n name: \"Current L3\",\n type: \"number\",\n role: \"value.current\",\n unit: \"A\",\n },\n // Frequency\n {\n key: \"frequency_hz\",\n id: \"frequency_hz\",\n name: \"Frequency\",\n type: \"number\",\n role: \"value\",\n unit: \"Hz\",\n },\n // Energy import\n {\n key: \"energy_import_kwh\",\n id: \"energy_import_kwh\",\n name: \"Energy import total\",\n type: \"number\",\n role: \"value.energy\",\n unit: \"kWh\",\n },\n {\n key: \"energy_import_t1_kwh\",\n id: \"energy_import_t1_kwh\",\n name: \"Energy import T1\",\n type: \"number\",\n role: \"value.energy\",\n unit: \"kWh\",\n },\n {\n key: \"energy_import_t2_kwh\",\n id: \"energy_import_t2_kwh\",\n name: \"Energy import T2\",\n type: \"number\",\n role: \"value.energy\",\n unit: \"kWh\",\n },\n {\n key: \"energy_import_t3_kwh\",\n id: \"energy_import_t3_kwh\",\n name: \"Energy import T3\",\n type: \"number\",\n role: \"value.energy\",\n unit: \"kWh\",\n },\n {\n key: \"energy_import_t4_kwh\",\n id: \"energy_import_t4_kwh\",\n name: \"Energy import T4\",\n type: \"number\",\n role: \"value.energy\",\n unit: \"kWh\",\n },\n // Energy export\n {\n key: \"energy_export_kwh\",\n id: \"energy_export_kwh\",\n name: \"Energy export total\",\n type: \"number\",\n role: \"value.energy\",\n unit: \"kWh\",\n },\n {\n key: \"energy_export_t1_kwh\",\n id: \"energy_export_t1_kwh\",\n name: \"Energy export T1\",\n type: \"number\",\n role: \"value.energy\",\n unit: \"kWh\",\n },\n {\n key: \"energy_export_t2_kwh\",\n id: \"energy_export_t2_kwh\",\n name: \"Energy export T2\",\n type: \"number\",\n role: \"value.energy\",\n unit: \"kWh\",\n },\n {\n key: \"energy_export_t3_kwh\",\n id: \"energy_export_t3_kwh\",\n name: \"Energy export T3\",\n type: \"number\",\n role: \"value.energy\",\n unit: \"kWh\",\n },\n {\n key: \"energy_export_t4_kwh\",\n id: \"energy_export_t4_kwh\",\n name: \"Energy export T4\",\n type: \"number\",\n role: \"value.energy\",\n unit: \"kWh\",\n },\n // Tariff\n {\n key: \"tariff\",\n id: \"tariff\",\n name: \"Active tariff\",\n type: \"number\",\n role: \"value\",\n },\n // Power quality\n {\n key: \"voltage_sag_l1_count\",\n id: \"quality.voltage_sag_l1_count\",\n name: \"Voltage sag L1\",\n type: \"number\",\n role: \"value\",\n },\n {\n key: \"voltage_sag_l2_count\",\n id: \"quality.voltage_sag_l2_count\",\n name: \"Voltage sag L2\",\n type: \"number\",\n role: \"value\",\n },\n {\n key: \"voltage_sag_l3_count\",\n id: \"quality.voltage_sag_l3_count\",\n name: \"Voltage sag L3\",\n type: \"number\",\n role: \"value\",\n },\n {\n key: \"voltage_swell_l1_count\",\n id: \"quality.voltage_swell_l1_count\",\n name: \"Voltage swell L1\",\n type: \"number\",\n role: \"value\",\n },\n {\n key: \"voltage_swell_l2_count\",\n id: \"quality.voltage_swell_l2_count\",\n name: \"Voltage swell L2\",\n type: \"number\",\n role: \"value\",\n },\n {\n key: \"voltage_swell_l3_count\",\n id: \"quality.voltage_swell_l3_count\",\n name: \"Voltage swell L3\",\n type: \"number\",\n role: \"value\",\n },\n {\n key: \"any_power_fail_count\",\n id: \"quality.power_fail_count\",\n name: \"Power fail count\",\n type: \"number\",\n role: \"value\",\n },\n {\n key: \"long_power_fail_count\",\n id: \"quality.long_power_fail_count\",\n name: \"Long power fail count\",\n type: \"number\",\n role: \"value\",\n },\n // Capacity tariff (Belgium)\n {\n key: \"average_power_15m_w\",\n id: \"average_power_15m_w\",\n name: \"Average power 15min\",\n type: \"number\",\n role: \"value.power\",\n unit: \"W\",\n },\n {\n key: \"monthly_power_peak_w\",\n id: \"monthly_power_peak_w\",\n name: \"Monthly power peak\",\n type: \"number\",\n role: \"value.power\",\n unit: \"W\",\n },\n {\n key: \"monthly_power_peak_timestamp\",\n id: \"monthly_power_peak_timestamp\",\n name: \"Monthly power peak time\",\n type: \"string\",\n role: \"date\",\n },\n // kWh meter specifics\n {\n key: \"apparent_current_a\",\n id: \"apparent_current_a\",\n name: \"Apparent current\",\n type: \"number\",\n role: \"value.current\",\n unit: \"A\",\n },\n {\n key: \"reactive_current_a\",\n id: \"reactive_current_a\",\n name: \"Reactive current\",\n type: \"number\",\n role: \"value.current\",\n unit: \"A\",\n },\n {\n key: \"apparent_power_va\",\n id: \"apparent_power_va\",\n name: \"Apparent power\",\n type: \"number\",\n role: \"value.power\",\n unit: \"VA\",\n },\n {\n key: \"reactive_power_var\",\n id: \"reactive_power_var\",\n name: \"Reactive power\",\n type: \"number\",\n role: \"value.power\",\n unit: \"var\",\n },\n {\n key: \"power_factor\",\n id: \"power_factor\",\n name: \"Power factor\",\n type: \"number\",\n role: \"value\",\n },\n // Battery specifics\n {\n key: \"state_of_charge_pct\",\n id: \"state_of_charge_pct\",\n name: \"State of charge\",\n type: \"number\",\n role: \"value.battery\",\n unit: \"%\",\n },\n {\n key: \"cycles\",\n id: \"cycles\",\n name: \"Charge cycles\",\n type: \"number\",\n role: \"value\",\n },\n // Metadata\n {\n key: \"meter_model\",\n id: \"meter_model\",\n name: \"Meter model\",\n type: \"string\",\n role: \"text\",\n },\n {\n key: \"timestamp\",\n id: \"timestamp\",\n name: \"Measurement timestamp\",\n type: \"string\",\n role: \"date\",\n },\n];\n\n/** Manages ioBroker state creation and updates for HomeWizard devices */\nexport class StateManager {\n private readonly adapter: utils.AdapterInstance;\n\n /** @param adapter The ioBroker adapter instance */\n constructor(adapter: utils.AdapterInstance) {\n this.adapter = adapter;\n }\n\n /**\n * Create device channel and info states\n *\n * @param config Device configuration\n */\n async createDeviceStates(config: DeviceConfig): Promise<void> {\n const prefix = this.devicePrefix(config);\n\n await this.adapter.extendObjectAsync(prefix, {\n type: \"device\",\n common: { name: config.productName || config.productType },\n native: {},\n });\n\n await this.adapter.extendObjectAsync(`${prefix}.info`, {\n type: \"channel\",\n common: { name: \"Device Information\" },\n native: {},\n });\n\n await this.createState(\n `${prefix}.info.productName`,\n \"Product name\",\n \"string\",\n \"text\",\n false,\n );\n await this.createState(\n `${prefix}.info.productType`,\n \"Product type\",\n \"string\",\n \"text\",\n false,\n );\n await this.createState(\n `${prefix}.info.firmware`,\n \"Firmware version\",\n \"string\",\n \"text\",\n false,\n );\n await this.createState(\n `${prefix}.info.connected`,\n \"Device connected\",\n \"boolean\",\n \"indicator.reachable\",\n false,\n );\n await this.createState(\n `${prefix}.info.wifi_rssi_db`,\n \"WiFi signal strength\",\n \"number\",\n \"value\",\n false,\n \"dB\",\n );\n await this.createState(\n `${prefix}.info.uptime_s`,\n \"Uptime\",\n \"number\",\n \"value\",\n false,\n \"s\",\n );\n\n // Set initial info values\n await this.adapter.setStateAsync(`${prefix}.info.productName`, {\n val: config.productName,\n ack: true,\n });\n await this.adapter.setStateAsync(`${prefix}.info.productType`, {\n val: config.productType,\n ack: true,\n });\n }\n\n /**\n * Update measurement states \u2014 only creates states that have values\n *\n * @param config Device configuration\n * @param data Measurement data\n */\n async updateMeasurement(\n config: DeviceConfig,\n data: Measurement,\n ): Promise<void> {\n const prefix = this.devicePrefix(config);\n\n // Main measurement values\n const fields = MEASUREMENT_STATE_DEFS;\n for (const def of fields) {\n const rawValue = data[def.key as keyof Measurement];\n if (\n rawValue !== undefined &&\n rawValue !== null &&\n !Array.isArray(rawValue)\n ) {\n await this.ensureAndSet(\n `${prefix}.${def.id}`,\n def.name,\n def.type,\n def.role,\n rawValue as ioBroker.StateValue,\n def.unit,\n );\n }\n }\n\n // External meters (P1 gas/water/heat)\n if (data.external?.length) {\n await this.adapter.extendObjectAsync(`${prefix}.external`, {\n type: \"channel\",\n common: { name: \"External Meters\" },\n native: {},\n });\n\n for (const ext of data.external) {\n const extId = `${prefix}.external.${sanitize(ext.type)}_${sanitize(ext.unique_id)}`;\n await this.adapter.extendObjectAsync(extId, {\n type: \"channel\",\n common: { name: ext.type },\n native: {},\n });\n await this.ensureAndSet(\n `${extId}.value`,\n \"Value\",\n \"number\",\n \"value\",\n ext.value,\n ext.unit,\n );\n await this.ensureAndSet(\n `${extId}.unit`,\n \"Unit\",\n \"string\",\n \"text\",\n ext.unit,\n );\n await this.ensureAndSet(\n `${extId}.timestamp`,\n \"Timestamp\",\n \"string\",\n \"date\",\n ext.timestamp,\n );\n }\n }\n }\n\n /**\n * Update system states\n *\n * @param config Device configuration\n * @param system System info data\n */\n async updateSystem(config: DeviceConfig, system: SystemInfo): Promise<void> {\n const prefix = this.devicePrefix(config);\n\n // WiFi/uptime in info channel\n await this.ensureAndSet(\n `${prefix}.info.wifi_rssi_db`,\n \"WiFi signal strength\",\n \"number\",\n \"value\",\n system.wifi_rssi_db,\n \"dB\",\n );\n await this.ensureAndSet(\n `${prefix}.info.uptime_s`,\n \"Uptime\",\n \"number\",\n \"value\",\n system.uptime_s,\n \"s\",\n );\n\n // System control channel\n await this.adapter.extendObjectAsync(`${prefix}.system`, {\n type: \"channel\",\n common: { name: \"System Settings\" },\n native: {},\n });\n\n await this.ensureAndSet(\n `${prefix}.system.cloud_enabled`,\n \"Cloud enabled\",\n \"boolean\",\n \"switch\",\n system.cloud_enabled,\n undefined,\n true,\n );\n await this.ensureAndSet(\n `${prefix}.system.status_led_brightness_pct`,\n \"LED brightness\",\n \"number\",\n \"level\",\n system.status_led_brightness_pct,\n \"%\",\n true,\n );\n\n if (system.api_v1_enabled !== undefined) {\n await this.ensureAndSet(\n `${prefix}.system.api_v1_enabled`,\n \"API v1 enabled\",\n \"boolean\",\n \"switch\",\n system.api_v1_enabled,\n undefined,\n true,\n );\n }\n\n // Action buttons\n await this.createState(\n `${prefix}.system.reboot`,\n \"Reboot device\",\n \"boolean\",\n \"button\",\n true,\n );\n await this.createState(\n `${prefix}.system.identify`,\n \"Identify (blink LED)\",\n \"boolean\",\n \"button\",\n true,\n );\n }\n\n /**\n * Update battery control states\n *\n * @param config Device configuration\n * @param battery Battery control data\n */\n async updateBattery(\n config: DeviceConfig,\n battery: BatteryControl,\n ): Promise<void> {\n const prefix = this.devicePrefix(config);\n\n await this.adapter.extendObjectAsync(`${prefix}.battery`, {\n type: \"channel\",\n common: { name: \"Battery Control\" },\n native: {},\n });\n\n await this.ensureAndSet(\n `${prefix}.battery.mode`,\n \"Battery mode\",\n \"string\",\n \"text\",\n battery.mode,\n undefined,\n true,\n );\n if (battery.permissions !== undefined) {\n await this.ensureAndSet(\n `${prefix}.battery.permissions`,\n \"Battery permissions\",\n \"string\",\n \"json\",\n JSON.stringify(battery.permissions),\n undefined,\n true,\n );\n }\n if (battery.battery_count !== undefined) {\n await this.ensureAndSet(\n `${prefix}.battery.battery_count`,\n \"Connected batteries\",\n \"number\",\n \"value\",\n battery.battery_count,\n );\n }\n if (battery.power_w !== undefined) {\n await this.ensureAndSet(\n `${prefix}.battery.power_w`,\n \"Battery power\",\n \"number\",\n \"value.power\",\n battery.power_w,\n \"W\",\n );\n }\n if (battery.target_power_w !== undefined) {\n await this.ensureAndSet(\n `${prefix}.battery.target_power_w`,\n \"Target power\",\n \"number\",\n \"value.power\",\n battery.target_power_w,\n \"W\",\n );\n }\n if (battery.max_consumption_w !== undefined) {\n await this.ensureAndSet(\n `${prefix}.battery.max_consumption_w`,\n \"Max consumption\",\n \"number\",\n \"value.power\",\n battery.max_consumption_w,\n \"W\",\n );\n }\n if (battery.max_production_w !== undefined) {\n await this.ensureAndSet(\n `${prefix}.battery.max_production_w`,\n \"Max production\",\n \"number\",\n \"value.power\",\n battery.max_production_w,\n \"W\",\n );\n }\n }\n\n /**\n * Set device connected state\n *\n * @param config Device configuration\n * @param connected Connection status\n */\n async setDeviceConnected(\n config: DeviceConfig,\n connected: boolean,\n ): Promise<void> {\n const prefix = this.devicePrefix(config);\n await this.adapter.setStateAsync(`${prefix}.info.connected`, {\n val: connected,\n ack: true,\n });\n }\n\n /**\n * Remove all states for a device\n *\n * @param config Device configuration\n */\n async removeDevice(config: DeviceConfig): Promise<void> {\n const prefix = this.devicePrefix(config);\n await this.adapter.delObjectAsync(prefix, { recursive: true });\n }\n\n /**\n * Get device object ID prefix\n *\n * @param config Device configuration\n */\n devicePrefix(config: DeviceConfig): string {\n return `${sanitize(config.productType)}_${sanitize(config.serial)}`;\n }\n\n /**\n * Create a state if it doesn't exist\n *\n * @param id State ID\n * @param name State name\n * @param type Value type\n * @param role ioBroker role\n * @param write Whether state is writable\n * @param unit Optional unit\n */\n private async createState(\n id: string,\n name: string,\n type: ioBroker.CommonType,\n role: string,\n write: boolean,\n unit?: string,\n ): Promise<void> {\n const common: Partial<ioBroker.StateCommon> = {\n name,\n type,\n role,\n read: true,\n write,\n };\n if (unit) {\n common.unit = unit;\n }\n await this.adapter.extendObjectAsync(id, {\n type: \"state\",\n common: common as ioBroker.StateCommon,\n native: {},\n });\n }\n\n /**\n * Ensure state exists and set value\n *\n * @param id State ID\n * @param name State name\n * @param type Value type\n * @param role ioBroker role\n * @param value State value\n * @param unit Optional unit\n * @param write Whether state is writable\n */\n private async ensureAndSet(\n id: string,\n name: string,\n type: ioBroker.CommonType,\n role: string,\n value: ioBroker.StateValue,\n unit?: string,\n write?: boolean,\n ): Promise<void> {\n await this.createState(id, name, type, role, write ?? false, unit);\n await this.adapter.setStateAsync(id, { val: value, ack: true });\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA6BA,SAAS,SAAS,KAAqB;AACrC,SAAO,IAAI,QAAQ,mBAAmB,GAAG,EAAE,YAAY;AACzD;AAEA,MAAM,yBAAgD;AAAA;AAAA,EAEpD;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AACF;AAGO,MAAM,aAAa;AAAA,EACP;AAAA;AAAA,EAGjB,YAAY,SAAgC;AAC1C,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBAAmB,QAAqC;AAC5D,UAAM,SAAS,KAAK,aAAa,MAAM;AAEvC,UAAM,KAAK,QAAQ,kBAAkB,QAAQ;AAAA,MAC3C,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,OAAO,eAAe,OAAO,YAAY;AAAA,MACzD,QAAQ,CAAC;AAAA,IACX,CAAC;AAED,UAAM,KAAK,QAAQ,kBAAkB,GAAG,MAAM,SAAS;AAAA,MACrD,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,qBAAqB;AAAA,MACrC,QAAQ,CAAC;AAAA,IACX,CAAC;AAED,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,KAAK,QAAQ,cAAc,GAAG,MAAM,qBAAqB;AAAA,MAC7D,KAAK,OAAO;AAAA,MACZ,KAAK;AAAA,IACP,CAAC;AACD,UAAM,KAAK,QAAQ,cAAc,GAAG,MAAM,qBAAqB;AAAA,MAC7D,KAAK,OAAO;AAAA,MACZ,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBACJ,QACA,MACe;AAhenB;AAieI,UAAM,SAAS,KAAK,aAAa,MAAM;AAGvC,UAAM,SAAS;AACf,eAAW,OAAO,QAAQ;AACxB,YAAM,WAAW,KAAK,IAAI,GAAwB;AAClD,UACE,aAAa,UACb,aAAa,QACb,CAAC,MAAM,QAAQ,QAAQ,GACvB;AACA,cAAM,KAAK;AAAA,UACT,GAAG,MAAM,IAAI,IAAI,EAAE;AAAA,UACnB,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ;AAAA,UACA,IAAI;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAGA,SAAI,UAAK,aAAL,mBAAe,QAAQ;AACzB,YAAM,KAAK,QAAQ,kBAAkB,GAAG,MAAM,aAAa;AAAA,QACzD,MAAM;AAAA,QACN,QAAQ,EAAE,MAAM,kBAAkB;AAAA,QAClC,QAAQ,CAAC;AAAA,MACX,CAAC;AAED,iBAAW,OAAO,KAAK,UAAU;AAC/B,cAAM,QAAQ,GAAG,MAAM,aAAa,SAAS,IAAI,IAAI,CAAC,IAAI,SAAS,IAAI,SAAS,CAAC;AACjF,cAAM,KAAK,QAAQ,kBAAkB,OAAO;AAAA,UAC1C,MAAM;AAAA,UACN,QAAQ,EAAE,MAAM,IAAI,KAAK;AAAA,UACzB,QAAQ,CAAC;AAAA,QACX,CAAC;AACD,cAAM,KAAK;AAAA,UACT,GAAG,KAAK;AAAA,UACR;AAAA,UACA;AAAA,UACA;AAAA,UACA,IAAI;AAAA,UACJ,IAAI;AAAA,QACN;AACA,cAAM,KAAK;AAAA,UACT,GAAG,KAAK;AAAA,UACR;AAAA,UACA;AAAA,UACA;AAAA,UACA,IAAI;AAAA,QACN;AACA,cAAM,KAAK;AAAA,UACT,GAAG,KAAK;AAAA,UACR;AAAA,UACA;AAAA,UACA;AAAA,UACA,IAAI;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAa,QAAsB,QAAmC;AAC1E,UAAM,SAAS,KAAK,aAAa,MAAM;AAGvC,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP;AAAA,IACF;AACA,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP;AAAA,IACF;AAGA,UAAM,KAAK,QAAQ,kBAAkB,GAAG,MAAM,WAAW;AAAA,MACvD,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,kBAAkB;AAAA,MAClC,QAAQ,CAAC;AAAA,IACX,CAAC;AAED,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AACA,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAEA,QAAI,OAAO,mBAAmB,QAAW;AACvC,YAAM,KAAK;AAAA,QACT,GAAG,MAAM;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cACJ,QACA,SACe;AACf,UAAM,SAAS,KAAK,aAAa,MAAM;AAEvC,UAAM,KAAK,QAAQ,kBAAkB,GAAG,MAAM,YAAY;AAAA,MACxD,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,kBAAkB;AAAA,MAClC,QAAQ,CAAC;AAAA,IACX,CAAC;AAED,UAAM,KAAK;AAAA,MACT,GAAG,MAAM;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACA,QAAI,QAAQ,gBAAgB,QAAW;AACrC,YAAM,KAAK;AAAA,QACT,GAAG,MAAM;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,KAAK,UAAU,QAAQ,WAAW;AAAA,QAClC;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,QAAQ,kBAAkB,QAAW;AACvC,YAAM,KAAK;AAAA,QACT,GAAG,MAAM;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,MACV;AAAA,IACF;AACA,QAAI,QAAQ,YAAY,QAAW;AACjC,YAAM,KAAK;AAAA,QACT,GAAG,MAAM;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,QAAI,QAAQ,mBAAmB,QAAW;AACxC,YAAM,KAAK;AAAA,QACT,GAAG,MAAM;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,QAAI,QAAQ,sBAAsB,QAAW;AAC3C,YAAM,KAAK;AAAA,QACT,GAAG,MAAM;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,QAAI,QAAQ,qBAAqB,QAAW;AAC1C,YAAM,KAAK;AAAA,QACT,GAAG,MAAM;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,mBACJ,QACA,WACe;AACf,UAAM,SAAS,KAAK,aAAa,MAAM;AACvC,UAAM,KAAK,QAAQ,cAAc,GAAG,MAAM,mBAAmB;AAAA,MAC3D,KAAK;AAAA,MACL,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,QAAqC;AACtD,UAAM,SAAS,KAAK,aAAa,MAAM;AACvC,UAAM,KAAK,QAAQ,eAAe,QAAQ,EAAE,WAAW,KAAK,CAAC;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,QAA8B;AACzC,WAAO,GAAG,SAAS,OAAO,WAAW,CAAC,IAAI,SAAS,OAAO,MAAM,CAAC;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAc,YACZ,IACA,MACA,MACA,MACA,OACA,MACe;AACf,UAAM,SAAwC;AAAA,MAC5C;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN;AAAA,IACF;AACA,QAAI,MAAM;AACR,aAAO,OAAO;AAAA,IAChB;AACA,UAAM,KAAK,QAAQ,kBAAkB,IAAI;AAAA,MACvC,MAAM;AAAA,MACN;AAAA,MACA,QAAQ,CAAC;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAc,aACZ,IACA,MACA,MACA,MACA,OACA,MACA,OACe;AACf,UAAM,KAAK,YAAY,IAAI,MAAM,MAAM,MAAM,wBAAS,OAAO,IAAI;AACjE,UAAM,KAAK,QAAQ,cAAc,IAAI,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,EAChE;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var types_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(types_exports);
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/lib/types.ts"],
|
|
4
|
+
"sourcesContent": ["import type { HomeWizardWebSocket } from \"./websocket-client\";\n\n/** HomeWizard adapter configuration stored in native */\nexport interface AdapterConfig {\n /** Array of paired device configs (tokens encrypted via encryptedNative) */\n devices: DeviceConfig[];\n}\n\n/** Persisted config for a single paired device */\nexport interface DeviceConfig {\n /** Device IP address */\n ip: string;\n /** Bearer token from pairing */\n token: string;\n /** Product type (e.g. HWE-P1) */\n productType: string;\n /** Device serial number */\n serial: string;\n /** Human-readable product name */\n productName: string;\n}\n\n/** Response from GET /api */\nexport interface DeviceInfo {\n /** Product name */\n product_name: string;\n /** Product type identifier */\n product_type: string;\n /** Device serial number */\n serial: string;\n /** Firmware version string */\n firmware_version: string;\n /** API version string */\n api_version: string;\n}\n\n/** Response from POST /api/user (pairing) */\nexport interface PairingResponse {\n /** Bearer token for API access */\n token: string;\n}\n\n/** Measurement data from GET /api/measurement or WebSocket push */\nexport interface Measurement {\n /** Unique meter identifier */\n unique_id?: string;\n /** Protocol version */\n protocol_version?: string;\n /** Meter model */\n meter_model?: string;\n /** Measurement timestamp */\n timestamp?: string;\n /** Active tariff number */\n tariff?: number;\n\n /** Total energy import in kWh */\n energy_import_kwh?: number;\n /** Energy import tariff 1 */\n energy_import_t1_kwh?: number;\n /** Energy import tariff 2 */\n energy_import_t2_kwh?: number;\n /** Energy import tariff 3 */\n energy_import_t3_kwh?: number;\n /** Energy import tariff 4 */\n energy_import_t4_kwh?: number;\n /** Total energy export in kWh */\n energy_export_kwh?: number;\n /** Energy export tariff 1 */\n energy_export_t1_kwh?: number;\n /** Energy export tariff 2 */\n energy_export_t2_kwh?: number;\n /** Energy export tariff 3 */\n energy_export_t3_kwh?: number;\n /** Energy export tariff 4 */\n energy_export_t4_kwh?: number;\n\n /** Total active power in W */\n power_w?: number;\n /** Active power phase 1 */\n power_l1_w?: number;\n /** Active power phase 2 */\n power_l2_w?: number;\n /** Active power phase 3 */\n power_l3_w?: number;\n\n /** Voltage (single phase) */\n voltage_v?: number;\n /** Voltage phase 1 */\n voltage_l1_v?: number;\n /** Voltage phase 2 */\n voltage_l2_v?: number;\n /** Voltage phase 3 */\n voltage_l3_v?: number;\n\n /** Current (single phase) */\n current_a?: number;\n /** Current phase 1 */\n current_l1_a?: number;\n /** Current phase 2 */\n current_l2_a?: number;\n /** Current phase 3 */\n current_l3_a?: number;\n\n /** Grid frequency in Hz */\n frequency_hz?: number;\n\n /** Voltage sag count phase 1 */\n voltage_sag_l1_count?: number;\n /** Voltage sag count phase 2 */\n voltage_sag_l2_count?: number;\n /** Voltage sag count phase 3 */\n voltage_sag_l3_count?: number;\n /** Voltage swell count phase 1 */\n voltage_swell_l1_count?: number;\n /** Voltage swell count phase 2 */\n voltage_swell_l2_count?: number;\n /** Voltage swell count phase 3 */\n voltage_swell_l3_count?: number;\n /** Any power fail count */\n any_power_fail_count?: number;\n /** Long power fail count */\n long_power_fail_count?: number;\n\n /** Average power over 15 min (Belgium) */\n average_power_15m_w?: number;\n /** Monthly power peak (Belgium) */\n monthly_power_peak_w?: number;\n /** Monthly power peak timestamp (Belgium) */\n monthly_power_peak_timestamp?: string;\n\n /** Apparent current */\n apparent_current_a?: number;\n /** Reactive current */\n reactive_current_a?: number;\n /** Apparent power in VA */\n apparent_power_va?: number;\n /** Reactive power in var */\n reactive_power_var?: number;\n /** Power factor */\n power_factor?: number;\n /** Apparent current phase 1 */\n apparent_current_l1_a?: number;\n /** Apparent current phase 2 */\n apparent_current_l2_a?: number;\n /** Apparent current phase 3 */\n apparent_current_l3_a?: number;\n /** Reactive current phase 1 */\n reactive_current_l1_a?: number;\n /** Reactive current phase 2 */\n reactive_current_l2_a?: number;\n /** Reactive current phase 3 */\n reactive_current_l3_a?: number;\n /** Apparent power phase 1 */\n apparent_power_l1_va?: number;\n /** Apparent power phase 2 */\n apparent_power_l2_va?: number;\n /** Apparent power phase 3 */\n apparent_power_l3_va?: number;\n /** Reactive power phase 1 */\n reactive_power_l1_var?: number;\n /** Reactive power phase 2 */\n reactive_power_l2_var?: number;\n /** Reactive power phase 3 */\n reactive_power_l3_var?: number;\n /** Power factor phase 1 */\n power_factor_l1?: number;\n /** Power factor phase 2 */\n power_factor_l2?: number;\n /** Power factor phase 3 */\n power_factor_l3?: number;\n\n /** Battery state of charge in percent */\n state_of_charge_pct?: number;\n /** Battery charge cycles */\n cycles?: number;\n\n /** External meters (gas, water, heat) */\n external?: ExternalMeter[];\n}\n\n/** External meter attached to P1 (gas, water, heat) */\nexport interface ExternalMeter {\n /** Unique meter identifier */\n unique_id: string;\n /** Meter type */\n type:\n | \"gas_meter\"\n | \"heat_meter\"\n | \"warm_water_meter\"\n | \"water_meter\"\n | \"inlet_heat_meter\";\n /** Last reading timestamp */\n timestamp: string;\n /** Meter reading value */\n value: number;\n /** Measurement unit */\n unit: string;\n}\n\n/** System info from GET /api/system */\nexport interface SystemInfo {\n /** WiFi SSID */\n wifi_ssid: string;\n /** WiFi signal strength in dB */\n wifi_rssi_db: number;\n /** Uptime in seconds */\n uptime_s: number;\n /** Cloud communication enabled */\n cloud_enabled: boolean;\n /** Status LED brightness 0-100% */\n status_led_brightness_pct: number;\n /** Legacy API v1 enabled */\n api_v1_enabled?: boolean;\n}\n\n/** Battery control from GET /api/batteries */\nexport interface BatteryControl {\n /** Battery mode */\n mode: \"zero\" | \"to_full\" | \"standby\";\n /** Battery permissions */\n permissions?: string[];\n /** Number of connected batteries */\n battery_count?: number;\n /** Current combined power in W */\n power_w?: number;\n /** Target power in W */\n target_power_w?: number;\n /** Maximum consumption in W */\n max_consumption_w?: number;\n /** Maximum production in W */\n max_production_w?: number;\n}\n\n/** WebSocket message envelope */\nexport interface WsMessage {\n /** Message type */\n type: string;\n /** Message data payload */\n data?: Record<string, unknown>;\n}\n\n/** Device discovered via mDNS */\nexport interface DiscoveredDevice {\n /** Device IP address */\n ip: string;\n /** Product type from mDNS TXT record or device info */\n productType: string;\n /** Serial number from mDNS name */\n serial: string;\n /** Human-readable name */\n name: string;\n}\n\n/** Connection state for a single device */\nexport interface DeviceConnection {\n /** Device config */\n config: DeviceConfig;\n /** WebSocket client instance (if connected) */\n wsClient: HomeWizardWebSocket | null;\n /** Whether WS is authenticated */\n wsAuthenticated: boolean;\n /** REST fallback polling timer */\n pollTimer: ioBroker.Interval | undefined;\n /** Reconnect timer */\n reconnectTimer: ioBroker.Timeout | undefined;\n /** Consecutive WS failures for backoff */\n wsFailCount: number;\n /** Last error code for dedup */\n lastErrorCode: string;\n}\n\n// Augment the ioBroker global namespace\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace ioBroker {\n interface AdapterConfig {\n /** Array of paired device configs (tokens encrypted via encryptedNative) */\n devices: DeviceConfig[];\n }\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var websocket_client_exports = {};
|
|
30
|
+
__export(websocket_client_exports, {
|
|
31
|
+
HomeWizardWebSocket: () => HomeWizardWebSocket
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(websocket_client_exports);
|
|
34
|
+
var import_ws = __toESM(require("ws"));
|
|
35
|
+
class HomeWizardWebSocket {
|
|
36
|
+
ip;
|
|
37
|
+
token;
|
|
38
|
+
callbacks;
|
|
39
|
+
ws = null;
|
|
40
|
+
destroyed = false;
|
|
41
|
+
/**
|
|
42
|
+
* @param ip Device IP address
|
|
43
|
+
* @param token Bearer token
|
|
44
|
+
* @param callbacks Event callbacks
|
|
45
|
+
*/
|
|
46
|
+
constructor(ip, token, callbacks) {
|
|
47
|
+
this.ip = ip;
|
|
48
|
+
this.token = token;
|
|
49
|
+
this.callbacks = callbacks;
|
|
50
|
+
}
|
|
51
|
+
/** Connect to WebSocket and start auth handshake */
|
|
52
|
+
connect() {
|
|
53
|
+
if (this.destroyed) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this.cleanup();
|
|
57
|
+
const url = `wss://${this.ip}/api/ws`;
|
|
58
|
+
this.callbacks.log.debug(`WS connecting to ${url}`);
|
|
59
|
+
this.ws = new import_ws.default(url, {
|
|
60
|
+
rejectUnauthorized: false,
|
|
61
|
+
// HomeWizard uses self-signed certs
|
|
62
|
+
handshakeTimeout: 1e4
|
|
63
|
+
});
|
|
64
|
+
this.ws.on("open", () => {
|
|
65
|
+
this.callbacks.log.debug(`WS open to ${this.ip}`);
|
|
66
|
+
});
|
|
67
|
+
this.ws.on("message", (raw) => {
|
|
68
|
+
this.handleMessage(raw);
|
|
69
|
+
});
|
|
70
|
+
this.ws.on("close", (code, reason) => {
|
|
71
|
+
this.callbacks.log.debug(`WS closed: ${code} ${reason.toString()}`);
|
|
72
|
+
this.ws = null;
|
|
73
|
+
if (!this.destroyed) {
|
|
74
|
+
this.callbacks.onDisconnected();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
this.ws.on("error", (err) => {
|
|
78
|
+
this.callbacks.log.debug(`WS error: ${err.message}`);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/** Gracefully close connection */
|
|
82
|
+
close() {
|
|
83
|
+
this.destroyed = true;
|
|
84
|
+
this.cleanup();
|
|
85
|
+
}
|
|
86
|
+
/** Whether the WebSocket is currently open */
|
|
87
|
+
get isConnected() {
|
|
88
|
+
var _a;
|
|
89
|
+
return ((_a = this.ws) == null ? void 0 : _a.readyState) === import_ws.default.OPEN;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Handle incoming WebSocket message
|
|
93
|
+
*
|
|
94
|
+
* @param raw Raw message data
|
|
95
|
+
*/
|
|
96
|
+
handleMessage(raw) {
|
|
97
|
+
const text = Buffer.isBuffer(raw) ? raw.toString("utf8") : raw instanceof ArrayBuffer ? Buffer.from(raw).toString("utf8") : Array.isArray(raw) ? Buffer.concat(raw).toString("utf8") : "";
|
|
98
|
+
let msg;
|
|
99
|
+
try {
|
|
100
|
+
msg = JSON.parse(text);
|
|
101
|
+
} catch {
|
|
102
|
+
this.callbacks.log.warn(`WS invalid JSON: ${text.substring(0, 200)}`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
switch (msg.type) {
|
|
106
|
+
case "authorization_requested":
|
|
107
|
+
this.callbacks.log.debug("WS auth requested, sending token");
|
|
108
|
+
this.send({ type: "authorization", data: { token: this.token } });
|
|
109
|
+
break;
|
|
110
|
+
case "authorized":
|
|
111
|
+
this.callbacks.log.debug("WS authorized, subscribing to measurement");
|
|
112
|
+
this.send({ type: "subscribe", data: { topic: "measurement" } });
|
|
113
|
+
this.callbacks.onConnected();
|
|
114
|
+
break;
|
|
115
|
+
case "measurement":
|
|
116
|
+
if (msg.data) {
|
|
117
|
+
this.callbacks.onMeasurement(msg.data);
|
|
118
|
+
}
|
|
119
|
+
break;
|
|
120
|
+
default:
|
|
121
|
+
this.callbacks.log.debug(`WS message type: ${msg.type}`);
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Send a message over WebSocket
|
|
127
|
+
*
|
|
128
|
+
* @param msg Message to send
|
|
129
|
+
*/
|
|
130
|
+
send(msg) {
|
|
131
|
+
var _a;
|
|
132
|
+
if (((_a = this.ws) == null ? void 0 : _a.readyState) === import_ws.default.OPEN) {
|
|
133
|
+
this.ws.send(JSON.stringify(msg));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/** Close WebSocket without triggering reconnect */
|
|
137
|
+
cleanup() {
|
|
138
|
+
if (this.ws) {
|
|
139
|
+
this.ws.removeAllListeners();
|
|
140
|
+
if (this.ws.readyState === import_ws.default.OPEN || this.ws.readyState === import_ws.default.CONNECTING) {
|
|
141
|
+
this.ws.close();
|
|
142
|
+
}
|
|
143
|
+
this.ws = null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
148
|
+
0 && (module.exports = {
|
|
149
|
+
HomeWizardWebSocket
|
|
150
|
+
});
|
|
151
|
+
//# sourceMappingURL=websocket-client.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/lib/websocket-client.ts"],
|
|
4
|
+
"sourcesContent": ["import WebSocket from \"ws\";\nimport type { Measurement, WsMessage } from \"./types\";\n\n/** Callback interface for WebSocket events */\nexport interface WsCallbacks {\n /** Called when measurement data is received */\n onMeasurement: (data: Measurement) => void;\n /** Called when connection is established and authenticated */\n onConnected: () => void;\n /** Called when connection is lost */\n onDisconnected: (error?: Error) => void;\n /** Log functions */\n log: {\n debug: (msg: string) => void;\n warn: (msg: string) => void;\n };\n}\n\n/**\n * WebSocket client for HomeWizard real-time measurement push.\n * Handles auth handshake, subscription, and auto-reconnect.\n */\nexport class HomeWizardWebSocket {\n private readonly ip: string;\n private readonly token: string;\n private readonly callbacks: WsCallbacks;\n private ws: WebSocket | null = null;\n private destroyed = false;\n\n /**\n * @param ip Device IP address\n * @param token Bearer token\n * @param callbacks Event callbacks\n */\n constructor(ip: string, token: string, callbacks: WsCallbacks) {\n this.ip = ip;\n this.token = token;\n this.callbacks = callbacks;\n }\n\n /** Connect to WebSocket and start auth handshake */\n connect(): void {\n if (this.destroyed) {\n return;\n }\n\n this.cleanup();\n\n const url = `wss://${this.ip}/api/ws`;\n this.callbacks.log.debug(`WS connecting to ${url}`);\n\n this.ws = new WebSocket(url, {\n rejectUnauthorized: false, // HomeWizard uses self-signed certs\n handshakeTimeout: 10_000,\n });\n\n this.ws.on(\"open\", () => {\n this.callbacks.log.debug(`WS open to ${this.ip}`);\n });\n\n this.ws.on(\"message\", (raw: WebSocket.RawData) => {\n this.handleMessage(raw);\n });\n\n this.ws.on(\"close\", (code: number, reason: Buffer) => {\n this.callbacks.log.debug(`WS closed: ${code} ${reason.toString()}`);\n this.ws = null;\n if (!this.destroyed) {\n this.callbacks.onDisconnected();\n }\n });\n\n this.ws.on(\"error\", (err: Error) => {\n this.callbacks.log.debug(`WS error: ${err.message}`);\n // close event will follow\n });\n }\n\n /** Gracefully close connection */\n close(): void {\n this.destroyed = true;\n this.cleanup();\n }\n\n /** Whether the WebSocket is currently open */\n get isConnected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Handle incoming WebSocket message\n *\n * @param raw Raw message data\n */\n private handleMessage(raw: WebSocket.RawData): void {\n const text = Buffer.isBuffer(raw)\n ? raw.toString(\"utf8\")\n : raw instanceof ArrayBuffer\n ? Buffer.from(raw).toString(\"utf8\")\n : Array.isArray(raw)\n ? Buffer.concat(raw).toString(\"utf8\")\n : \"\";\n let msg: WsMessage;\n try {\n msg = JSON.parse(text) as WsMessage;\n } catch {\n this.callbacks.log.warn(`WS invalid JSON: ${text.substring(0, 200)}`);\n return;\n }\n\n switch (msg.type) {\n case \"authorization_requested\":\n this.callbacks.log.debug(\"WS auth requested, sending token\");\n this.send({ type: \"authorization\", data: { token: this.token } });\n break;\n\n case \"authorized\":\n this.callbacks.log.debug(\"WS authorized, subscribing to measurement\");\n this.send({ type: \"subscribe\", data: { topic: \"measurement\" } });\n this.callbacks.onConnected();\n break;\n\n case \"measurement\":\n if (msg.data) {\n this.callbacks.onMeasurement(msg.data as unknown as Measurement);\n }\n break;\n\n default:\n this.callbacks.log.debug(`WS message type: ${msg.type}`);\n break;\n }\n }\n\n /**\n * Send a message over WebSocket\n *\n * @param msg Message to send\n */\n private send(msg: WsMessage): void {\n if (this.ws?.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(msg));\n }\n }\n\n /** Close WebSocket without triggering reconnect */\n private cleanup(): void {\n if (this.ws) {\n this.ws.removeAllListeners();\n if (\n this.ws.readyState === WebSocket.OPEN ||\n this.ws.readyState === WebSocket.CONNECTING\n ) {\n this.ws.close();\n }\n this.ws = null;\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["WebSocket"]
|
|
7
|
+
}
|