iobroker.sonoff 4.0.0 → 4.2.1
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/README.md +43 -43
- package/admin/i18n/de.json +26 -24
- package/admin/i18n/en.json +26 -24
- package/admin/i18n/es.json +26 -24
- package/admin/i18n/fr.json +26 -24
- package/admin/i18n/it.json +26 -24
- package/admin/i18n/nl.json +26 -24
- package/admin/i18n/pl.json +26 -24
- package/admin/i18n/pt.json +26 -24
- package/admin/i18n/ru.json +26 -24
- package/admin/i18n/uk.json +26 -24
- package/admin/i18n/zh-cn.json +26 -24
- package/admin/jsonConfig.json +423 -390
- package/build/lib/deviceManager.js +919 -0
- package/build/lib/deviceManager.js.map +1 -0
- package/build/lib/i18n/de.json +61 -0
- package/build/lib/i18n/en.json +61 -0
- package/build/lib/i18n/es.json +61 -0
- package/build/lib/i18n/fr.json +61 -0
- package/build/lib/i18n/it.json +61 -0
- package/build/lib/i18n/nl.json +61 -0
- package/build/lib/i18n/pl.json +61 -0
- package/build/lib/i18n/pt.json +61 -0
- package/build/lib/i18n/ru.json +61 -0
- package/build/lib/i18n/uk.json +61 -0
- package/build/lib/i18n/zh-cn.json +61 -0
- package/build/lib/mqttBase.js +52 -5
- package/build/lib/mqttBase.js.map +1 -1
- package/build/main.js +7 -0
- package/build/main.js.map +1 -1
- package/io-package.json +30 -27
- package/package.json +9 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deviceManager.js","sourceRoot":"","sources":["../../src/lib/deviceManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { I18n } from '@iobroker/adapter-core';\nimport {\n DeviceManagement,\n type ActionContext,\n type ConfigItemAny,\n type ControlState,\n type DeviceControl,\n type DeviceDetails,\n type DeviceInfo,\n type DeviceLoadContext,\n type DeviceRefresh,\n type InstanceDetails,\n} from '@iobroker/dm-utils';\n// Type only - the adapter gives access to the running MQTT server/bridge, see `handleRecreateDevice`\nimport type { SonoffAdapter } from '../main';\n\n/** Icon shown for every device, since the adapter does not ship per-model icons */\nconst DEVICE_ICON = 'adapter/sonoff/admin/sonoff.png';\n\n/** Group metadata: display name key (for i18n) */\nconst groupMeta: Record<string, { nameKey: string }> = {\n relay: { nameKey: 'Relays & Switches' },\n light: { nameKey: 'Lights & Dimmers' },\n cover: { nameKey: 'Shutters & Covers' },\n zigbee: { nameKey: 'Zigbee bridges' },\n meter: { nameKey: 'Energy Meters' },\n sensor: { nameKey: 'Sensors' },\n other: { nameKey: 'Other' },\n};\n\n/** Well-known sensor data points shown on the main tile */\nconst SENSOR_ITEMS: { stateId: string; label: string; unit: string; digits?: number }[] = [\n { stateId: 'Temperature', label: 'Temperature', unit: '°C', digits: 1 },\n { stateId: 'Humidity', label: 'Humidity', unit: '%', digits: 1 },\n { stateId: 'Pressure', label: 'Pressure', unit: 'hPa', digits: 1 },\n { stateId: 'Illuminance', label: 'Illuminance', unit: 'lx', digits: 0 },\n { stateId: 'CarbonDioxide', label: 'CO2', unit: 'ppm', digits: 0 },\n { stateId: 'TVOC', label: 'TVOC', unit: 'ppb', digits: 0 },\n { stateId: 'DewPoint', label: 'Dew point', unit: '°C', digits: 1 },\n];\n\n/**\n * Power-metering data points, keyed by their data point name (see `lib/datapoints.js`). Sonoff/Tasmota\n * devices have no fixed \"model\" that tells us which power values to expect, and unlike the built-in\n * `ENERGY.*` group, bridged external meters (SML smart-meter heads, PZEM sensors, ...) publish the same\n * data points nested under their own custom group name, e.g. `SML_Total_in`. So instead of only looking\n * at one fixed state ID, every state belonging to a device is matched against this table by its data\n * point name (the last path segment) - wherever it is found, the same way ioBroker.shelly reads its\n * power values from whichever states actually exist on a device (see shelly PR #1562).\n */\nconst POWER_METRIC_LABELS: Record<string, { label: string; unit: string; order: number }> = {\n Power: { label: 'Power', unit: 'W', order: 0 },\n Power_curr: { label: 'Power', unit: 'W', order: 0 },\n Leistung: { label: 'Power', unit: 'W', order: 0 },\n ApparentPower: { label: 'Apparent power', unit: 'VA', order: 1 },\n ReactivePower: { label: 'Reactive power', unit: 'var', order: 2 },\n Voltage: { label: 'Voltage', unit: 'V', order: 3 },\n Spannung: { label: 'Voltage', unit: 'V', order: 3 },\n Current: { label: 'Current', unit: 'A', order: 4 },\n Strom: { label: 'Current', unit: 'A', order: 4 },\n CurrentNeutral: { label: 'Neutral current', unit: 'A', order: 5 },\n Factor: { label: 'Power factor', unit: '', order: 6 },\n Frequency: { label: 'Frequency', unit: 'Hz', order: 7 },\n Frequenz: { label: 'Frequency', unit: 'Hz', order: 7 },\n Today: { label: 'Today', unit: 'kWh', order: 8 },\n heute: { label: 'Today', unit: 'kWh', order: 8 },\n TodaySumImport: { label: 'Today (import)', unit: 'kWh', order: 8 },\n TodaySumExport: { label: 'Today (export)', unit: 'kWh', order: 9 },\n Yesterday: { label: 'Yesterday', unit: 'kWh', order: 10 },\n gestern: { label: 'Yesterday', unit: 'kWh', order: 10 },\n Total: { label: 'Total', unit: 'kWh', order: 11 },\n Total_in: { label: 'Total (import)', unit: 'kWh', order: 11 },\n Total_out: { label: 'Total (export)', unit: 'kWh', order: 12 },\n ExportActive: { label: 'Returned energy', unit: 'kWh', order: 12 },\n PowerLow: { label: 'Power low threshold', unit: 'W', order: 14 },\n PowerHigh: { label: 'Power high threshold', unit: 'W', order: 15 },\n PowerDelta: { label: 'Power delta threshold', unit: 'W', order: 16 },\n};\n\n/** Fields taken from `INFO.*` (filled from Tasmota's `StatusNET`/`StatusFWR`) for the details panel */\nconst INFO_ITEMS: { stateId: string; label: string; copy?: boolean }[] = [\n { stateId: 'Module', label: 'Model' },\n { stateId: 'Hostname', label: 'Hostname' },\n { stateId: 'IPAddress', label: 'IP address', copy: true },\n { stateId: 'Mac', label: 'MAC address', copy: true },\n { stateId: 'Gateway', label: 'Gateway' },\n { stateId: 'Subnetmask', label: 'Subnet mask' },\n { stateId: 'Version', label: 'Firmware version' },\n { stateId: 'Hardware', label: 'Hardware' },\n { stateId: 'BuildDateTime', label: 'Build date' },\n { stateId: 'Core', label: 'Core' },\n { stateId: 'SDK', label: 'SDK' },\n];\n\n/**\n * Splits a state suffix into the group it belongs to and the data point name, e.g.\n * \"ENERGY.Voltage\" -> { channel: \"ENERGY\", key: \"Voltage\" }, \"SML_Total_in\" (a bridged external\n * meter nested under a custom \"SML\" group) -> { channel: \"SML\", key: \"Total_in\" }, and\n * \"SENSOR.ENERGY.Power\" (nested two levels deep with the \"Create object tree\" option enabled) ->\n * { channel: \"SENSOR.ENERGY\", key: \"Power\" }. A bare data point without any group, e.g. \"Voltage\",\n * resolves to `{ channel: \"\", key: \"Voltage\" }`. Returns `undefined` if the suffix's data point name\n * (last path segment, or underscore-joined tail) isn't one of `knownKeys`.\n *\n * @param suffix state ID without the device prefix\n * @param knownKeys data point names to match against, e.g. the keys of `POWER_METRIC_LABELS`\n */\nfunction splitDataPoint(suffix: string, knownKeys: readonly string[]): { channel: string; key: string } | undefined {\n const lastDotIdx = suffix.lastIndexOf('.');\n if (lastDotIdx > -1) {\n const key = suffix.substring(lastDotIdx + 1);\n return knownKeys.includes(key) ? { channel: suffix.substring(0, lastDotIdx), key } : undefined;\n }\n if (knownKeys.includes(suffix)) {\n return { channel: '', key: suffix };\n }\n for (const key of knownKeys) {\n if (suffix.endsWith(`_${key}`)) {\n return { channel: suffix.substring(0, suffix.length - key.length - 1), key };\n }\n }\n return undefined;\n}\n\n/**\n * A channel's leading \"SENSOR.\"/\"STATE.\"/\"RESULT.\"/\"WAKEUP.\" segment is only there because the\n * \"Create object tree\" (OBJ_TREE) option is/was enabled - it does not identify a different meter.\n * Stripping it gives the channel identity that is stable across that setting, so the same physical\n * meter (e.g. the built-in ENERGY group) is recognized as one meter even if its states exist twice,\n * once from before and once from after the option was toggled.\n */\nfunction canonicalizeChannel(channel: string): string {\n return channel.replace(/^(SENSOR|STATE|RESULT|WAKEUP)\\./, '');\n}\n\n/**\n * Whether a (raw, non-canonicalized) channel was nested under one of the topic-level groups created\n * by the \"Create object tree\" (OBJ_TREE) adapter option, e.g. \"SENSOR.ENERGY\" or \"STATE.Wifi\".\n */\nfunction isObjTreeStyleChannel(channel: string): boolean {\n return /^(SENSOR|STATE|RESULT|WAKEUP)\\./.test(channel);\n}\n\n/**\n * The suffix of a state as it looks with the \"Create object tree\" (OBJ_TREE) option turned off. That\n * option changes nothing about which data points a device has, it only moves them into a folder per\n * MQTT topic group and nests the payload path instead of joining it with \"_\":\n *\n * | OBJ_TREE on | OBJ_TREE off | flatName |\n * | ---------------------------- | ---------------------- | -------------------- |\n * | `RESULT.Dimmer` | `Dimmer` | `Dimmer` |\n * | `RESULT.Shutter1.Position` | `Shutter1_Position` | `Shutter1_Position` |\n * | `STATE.Wifi.RSSI` | `Wifi_RSSI` | `Wifi_RSSI` |\n * | `SENSOR.AM2301.Temperature` | `AM2301_Temperature` | `AM2301_Temperature` |\n *\n * Both settings therefore end up at the same name, so everything that recognizes a device by its data\n * points (see `getDeviceGroup` and `buildControls`) works the same with and without the option.\n */\nfunction flatName(suffix: string): string {\n return suffix.replace(/^(SENSOR|STATE|RESULT|WAKEUP)\\./, '').replace(/\\./g, '_');\n}\n\n/**\n * Data point names that make a device a sensor. Matched against the flattened suffix\n * (see `flatName`) either as the whole name or as its \"_\"-separated tail, because Tasmota puts the\n * name of the reporting sensor in front of the reading, e.g. \"AM2301_Temperature\".\n */\nconst SENSOR_KEYS = [\n 'Temperature',\n 'Humidity',\n 'Pressure',\n 'Illuminance',\n 'CarbonDioxide',\n 'TVOC',\n 'eCO2',\n 'DewPoint',\n 'AirQuality',\n 'PM2_5',\n 'PM10',\n 'UvIndex',\n 'Distance',\n 'Noise',\n];\n\n/**\n * DeviceManager Class\n */\nexport default class SonoffDeviceManagement extends DeviceManagement<SonoffAdapter> {\n private readonly ready: Promise<void>;\n private readonly states: { [id: string]: ioBroker.State } = {};\n private readonly objects: { [id: string]: ioBroker.ChannelObject | ioBroker.StateObject } = {};\n\n constructor(adapter: SonoffAdapter) {\n super(adapter);\n\n // Initialize i18n\n this.ready = I18n.init(__dirname, adapter)\n .catch(error => this.adapter.log.error(`Cannot initialize i18n: ${error}`))\n .then(() => this.init());\n }\n\n private async init(): Promise<void> {\n const channels = await this.adapter.getChannelsOfAsync();\n const stateObjects = await this.adapter.getStatesOfAsync();\n const states = await this.adapter.getStatesAsync('*');\n\n for (const channel of channels) {\n this.objects[channel._id] = channel;\n }\n for (const state of stateObjects) {\n this.objects[state._id] = state;\n }\n for (const id in states) {\n this.states[id] = states[id];\n }\n\n await this.adapter.subscribeStatesAsync('*');\n await this.adapter.subscribeObjectsAsync('*');\n }\n\n protected getInstanceInfo(): InstanceDetails {\n return {\n apiVersion: 'v3',\n smallCards: true,\n };\n }\n\n public onStateChange(id: string, state: ioBroker.State | null): void {\n if (state) {\n // Also on an unchanged value: the timestamp decides which copy of a data point that exists\n // more than once is the current one (see `buildControls` and `getPowerEntries`)\n this.states[id] = state;\n } else if (this.states[id]) {\n // trigger DM update\n delete this.states[id];\n }\n }\n\n public onObjectChange(id: string, obj: ioBroker.ChannelObject | ioBroker.StateObject | null): void {\n if (obj) {\n this.objects[id] = obj;\n } else {\n delete this.objects[id];\n }\n }\n\n /**\n * Collects the short suffixes (state ID without the device prefix) of all currently known\n * objects that belong to one device, e.g. \"POWER1\", \"ENERGY.Voltage\" or \"Shutter1_Position\".\n *\n * @param prefix `<namespace>.<deviceId>.`\n */\n private getSuffixes(prefix: string): Set<string> {\n const suffixes = new Set<string>();\n for (const id in this.objects) {\n if (id.startsWith(prefix)) {\n suffixes.add(id.substring(prefix.length));\n }\n }\n return suffixes;\n }\n\n /**\n * Finds a state whose data point name (its last path segment) is `key`, regardless of which group\n * it is nested under - a data point can end up at very different state IDs depending on the\n * \"Create object tree\" (OBJ_TREE) adapter option and on which MQTT topic published it, e.g. RSSI is\n * \"Wifi_RSSI\" with OBJ_TREE off but \"STATE.Wifi.RSSI\" with it on. Returns the matching suffix (state\n * ID without the device prefix), or `undefined` if the device has no such data point.\n *\n * A key can exist under more than one group at once, e.g. Tasmota echoes \"Uptime\" as part of a\n * one-off command response (\"RESULT.Uptime\") in addition to reporting it with every regular\n * \"STATE\" telemetry message - only the latter keeps being updated, so when both exist, the periodic\n * telemetry groups (STATE, then SENSOR) are preferred over anything else.\n *\n * @param prefix `<namespace>.<deviceId>.`\n * @param key data point name, e.g. \"RSSI\" or \"Temperature\"\n */\n private findDataPointSuffix(prefix: string, key: string): string | undefined {\n const matches: string[] = [];\n for (const stateId of Object.keys(this.states)) {\n if (!stateId.startsWith(prefix)) {\n continue;\n }\n const suffix = stateId.substring(prefix.length);\n if (suffix === key || suffix.endsWith(`.${key}`) || suffix.endsWith(`_${key}`)) {\n matches.push(suffix);\n }\n }\n if (matches.length > 1) {\n for (const group of ['STATE', 'SENSOR']) {\n const preferred = matches.find(s => s.startsWith(`${group}.`));\n if (preferred) {\n return preferred;\n }\n }\n }\n return matches[0];\n }\n\n /**\n * Splits a state suffix into the group it belongs to and the power-metering data point name.\n * Thin wrapper around `splitDataPoint` fixed to the keys of `POWER_METRIC_LABELS`, see there.\n *\n * @param suffix state ID without the device prefix\n */\n private splitPowerSuffix(suffix: string): { channel: string; key: string } | undefined {\n return splitDataPoint(suffix, Object.keys(POWER_METRIC_LABELS));\n }\n\n /**\n * Human-readable label for a (canonicalized) power-metering channel, used when a device has more\n * than one meter and each one needs to be told apart. The built-in Tasmota group is translated\n * (\"ENERGY\" -> \"Power\"/\"Leistung\"/...); a bridged external meter has no fixed translation - its\n * group name comes directly from the MQTT payload (e.g. \"SML\", \"PZEM\"), so it is shown as-is.\n */\n private channelLabel(channel: string): ioBroker.StringOrTranslated {\n if (channel === 'ENERGY') {\n return I18n.getTranslatedObject('Power');\n }\n // Not a second meter, but the alarm thresholds Tasmota reports for the built-in one\n if (channel === 'MARGINS') {\n return I18n.getTranslatedObject('Thresholds');\n }\n return channel.replace(/[._]/g, ' ');\n }\n\n /**\n * Finds all power-metering data points of a device, wherever they are: in the built-in `ENERGY.*`\n * group, in a custom group of a bridged external meter, or as a bare top-level data point.\n *\n * The same reading can end up under more than one state ID for the same meter and metric (channel +\n * label): toggling \"Create object tree\" moves a data point without deleting the old one, and some\n * Tasmota firmware reports energy readings both nested inside its periodic \"SENSOR\" telemetry *and*\n * via its own dedicated \"ENERGY\" topic (both handled by `mqttBase.ts`, see there). Whenever a copy\n * nested under SENSOR/STATE/RESULT/WAKEUP (see `isObjTreeStyleChannel`) exists, it is the\n * authoritative one - a device that also sends its own dedicated topic still sends the regular\n * telemetry that ends up nested, so the bare, non-nested copy is always redundant when a nested one\n * exists. Only as a fallback, when no nested copy exists (or several do, e.g. two aliased data point\n * names), the entry whose state was updated most recently wins - stale leftovers stop being updated,\n * so their timestamp falls behind.\n *\n * @param prefix `<namespace>.<deviceId>.`\n */\n private getPowerEntries(\n prefix: string,\n ): { suffix: string; channel: string; key: string; label: string; unit: string; order: number }[] {\n const entries: { suffix: string; channel: string; key: string; label: string; unit: string; order: number }[] =\n [];\n for (const stateId of Object.keys(this.states)) {\n if (!stateId.startsWith(prefix)) {\n continue;\n }\n const suffix = stateId.substring(prefix.length);\n const common = (this.objects[stateId] as ioBroker.StateObject | undefined)?.common;\n if (!common || common.write === true) {\n continue;\n }\n const split = this.splitPowerSuffix(suffix);\n if (!split) {\n continue;\n }\n const meta = POWER_METRIC_LABELS[split.key];\n entries.push({\n suffix,\n channel: split.channel,\n key: split.key,\n label: meta.label,\n unit: meta.unit,\n order: meta.order,\n });\n }\n\n const byMeter = new Map<string, typeof entries>();\n for (const entry of entries) {\n const groupKey = `${canonicalizeChannel(entry.channel)} ${entry.label}`;\n const group = byMeter.get(groupKey);\n if (group) {\n group.push(entry);\n } else {\n byMeter.set(groupKey, [entry]);\n }\n }\n\n const deduped: typeof entries = [];\n for (const group of byMeter.values()) {\n const nested = group.filter(e => isObjTreeStyleChannel(e.channel));\n const candidates = nested.length ? nested : group;\n const preferred = candidates.reduce((newest, entry) => {\n const newestTs = this.states[`${prefix}${newest.suffix}`]?.ts ?? 0;\n const entryTs = this.states[`${prefix}${entry.suffix}`]?.ts ?? 0;\n return entryTs > newestTs ? entry : newest;\n });\n deduped.push({ ...preferred, channel: canonicalizeChannel(preferred.channel) });\n }\n\n return deduped.sort((a, b) => a.channel.localeCompare(b.channel) || a.order - b.order);\n }\n\n /**\n * Load all sonoff/Tasmota devices\n *\n * @param context context used to report the found devices to the backend\n */\n async loadDevices(context: DeviceLoadContext<string>): Promise<void> {\n // Wait that i18n is initialized\n await this.ready;\n\n const ns = this.adapter.namespace;\n\n for (const deviceId in this.objects) {\n const device = this.objects[deviceId];\n if (device.type !== 'channel') {\n continue;\n }\n const shortDeviceId = device._id.substring(ns.length + 1);\n // Only direct children of the namespace are devices, \"info\" is the adapter's own channel\n if (!shortDeviceId || shortDeviceId.includes('.') || shortDeviceId === 'info') {\n continue;\n }\n\n try {\n const prefix = `${device._id}.`;\n const suffixes = this.getSuffixes(prefix);\n\n const alive = this.states[`${device._id}.alive`]?.val === true;\n const hostname = this.states[`${prefix}INFO.Hostname`]?.val as string | undefined;\n const ip = this.states[`${prefix}INFO.IPAddress`]?.val as string | undefined;\n const model = (this.states[`${prefix}INFO.Module`]?.val as string) || undefined;\n const rssiSuffix = this.findDataPointSuffix(prefix, 'RSSI');\n const rssi = rssiSuffix\n ? (this.states[`${prefix}${rssiSuffix}`]?.val as number | undefined)\n : undefined;\n const batterySuffix = this.findDataPointSuffix(prefix, 'BatteryPercentage');\n const battery = batterySuffix\n ? (this.states[`${prefix}${batterySuffix}`]?.val as number | undefined)\n : undefined;\n const clientId = (device.native as { clientId?: string } | undefined)?.clientId;\n const group = this.getDeviceGroup(suffixes);\n\n const res: DeviceInfo<string> = {\n id: device._id,\n identifier: hostname || ip || clientId || undefined,\n name: device.common?.name || shortDeviceId,\n icon: DEVICE_ICON,\n color: !alive ? '#fff' : undefined,\n backgroundColor: !alive ? '#f44336' : undefined,\n group,\n model,\n status: {\n connection: alive ? 'connected' : 'disconnected',\n rssi,\n battery,\n },\n hasDetails: true,\n customInfo: this.buildCustomInfo(device._id, prefix),\n controls: this.buildControls(shortDeviceId, prefix),\n actions: [\n {\n id: 'rename',\n icon: 'edit',\n description: I18n.getTranslatedObject('Rename this device'),\n handler: async (\n deviceId: string,\n context: ActionContext,\n ): Promise<{ refresh: DeviceRefresh }> => await this.handleRenameDevice(deviceId, context),\n },\n {\n id: 'recreate',\n icon: 'refresh',\n description: I18n.getTranslatedObject('Delete and recreate all data points of this device'),\n confirmation: I18n.getTranslatedObject(\n 'This deletes all data points of this device (except its name). They will be recreated automatically the next time the device reports its state. Continue?',\n ),\n handler: async (\n deviceId: string,\n context: ActionContext,\n ): Promise<{ refresh: DeviceRefresh }> =>\n await this.handleRecreateDevice(deviceId, context),\n },\n ...(hostname || ip\n ? [\n {\n id: 'web',\n icon: 'web' as const,\n description: I18n.getTranslatedObject('Open device web interface'),\n url: `http://${hostname || ip}`,\n },\n ]\n : []),\n ],\n };\n\n context.addDevice(res);\n } catch (error) {\n // One malformed/leftover data point (e.g. a state object without \"common\", as can happen\n // with data points from a much older adapter version) must not hide every other device\n this.adapter.log.warn(`Cannot load device ${device._id} into the Device Manager: ${error}`);\n }\n }\n }\n\n async getDeviceDetails(deviceId: string): Promise<DeviceDetails<string> | null> {\n // Wait that i18n is initialized\n await this.ready;\n\n const device = this.objects[deviceId];\n if (device?.type !== 'channel') {\n return null;\n }\n\n const ns = this.adapter.namespace;\n const shortDeviceId = device._id.substring(ns.length + 1);\n const prefix = `${deviceId}.`;\n const items: Record<string, ConfigItemAny> = {};\n\n const clientId = (device.native as { clientId?: string } | undefined)?.clientId;\n items._clientId = {\n type: 'staticInfo',\n label: I18n.getTranslatedObject('Device ID'),\n data: clientId || shortDeviceId,\n addColon: true,\n copyToClipboard: true,\n };\n\n const hostname = this.states[`${prefix}INFO.Hostname`]?.val as string | undefined;\n const ip = this.states[`${prefix}INFO.IPAddress`]?.val as string | undefined;\n if (hostname || ip) {\n items._deviceLink = {\n // @ts-expect-error staticLink is OK\n type: 'staticLink',\n href: `http://${hostname || ip}`,\n label: I18n.getTranslatedObject('Open device web interface'),\n button: true,\n icon: 'web',\n newLine: true,\n };\n }\n\n for (const info of INFO_ITEMS) {\n const val = this.states[`${prefix}INFO.${info.stateId}`]?.val;\n if (val === undefined || val === null || val === '') {\n continue;\n }\n items[`info_${info.stateId}`] = {\n type: 'staticInfo',\n label: I18n.getTranslatedObject(info.label),\n data: val,\n addColon: true,\n copyToClipboard: info.copy,\n };\n }\n\n const rssiSuffix = this.findDataPointSuffix(prefix, 'RSSI');\n const rssi = rssiSuffix ? (this.states[`${prefix}${rssiSuffix}`]?.val as number | undefined) : undefined;\n if (rssi !== undefined) {\n items._rssi = {\n type: 'staticInfo',\n label: I18n.getTranslatedObject('RSSI'),\n data: rssi,\n unit: 'dBm',\n addColon: true,\n };\n }\n\n const uptimeSuffix = this.findDataPointSuffix(prefix, 'Uptime');\n const uptime = uptimeSuffix ? this.states[`${prefix}${uptimeSuffix}`]?.val : undefined;\n if (uptime !== undefined && uptime !== null && uptime !== '') {\n items._uptime = {\n type: 'staticInfo',\n label: I18n.getTranslatedObject('Uptime'),\n data: uptime,\n addColon: true,\n };\n }\n\n // Power metering section – only shown when power data points exist. Bridged external meters\n // (SML, PZEM, ...) are shown as their own sub-section when a device has more than one meter.\n const powerEntries = this.getPowerEntries(prefix);\n if (powerEntries.length) {\n items._energyHeader = {\n type: 'header',\n text: I18n.getTranslatedObject('Power metering'),\n size: 6,\n newLine: true,\n };\n\n const channels = [...new Set(powerEntries.map(e => e.channel))];\n const multiChannel = channels.length > 1;\n\n for (const channel of channels) {\n if (multiChannel && channel) {\n items[`energy_ch_${channel.replace(/[.:]/g, '_')}`] = {\n type: 'staticInfo',\n label: this.channelLabel(channel),\n data: '',\n newLine: true,\n };\n }\n for (const entry of powerEntries.filter(e => e.channel === channel)) {\n const val = this.states[`${prefix}${entry.suffix}`]?.val;\n items[`energy_${entry.suffix.replace(/[.:]/g, '_')}`] = {\n type: 'staticInfo',\n label: I18n.getTranslatedObject(entry.label),\n data: typeof val === 'number' ? Math.round(val * 100) / 100 : String(val ?? '—'),\n unit: entry.unit || undefined,\n addColon: true,\n };\n }\n }\n }\n\n // Digital inputs (physical switches/buttons wired to the device)\n const inputEntries: { suffix: string; label: string }[] = [];\n for (const stateId of Object.keys(this.states)) {\n if (!stateId.startsWith(prefix)) {\n continue;\n }\n const suffix = stateId.substring(prefix.length);\n // Only the last path segment is the actual data point name (may be nested, e.g. \"STATE.Switch1\")\n const lastSegment = suffix.substring(suffix.lastIndexOf('.') + 1);\n const match = lastSegment.match(/^(Switch|Button)(\\d+)$/);\n if (match) {\n inputEntries.push({ suffix, label: `${match[1]} ${match[2]}` });\n }\n }\n if (inputEntries.length) {\n items._inputsHeader = {\n type: 'header',\n text: I18n.getTranslatedObject('Digital inputs'),\n size: 6,\n newLine: true,\n };\n inputEntries.sort((a, b) => a.suffix.localeCompare(b.suffix));\n for (const entry of inputEntries) {\n const val = this.states[`${prefix}${entry.suffix}`]?.val;\n items[`input_${entry.suffix}`] = {\n type: 'staticInfo',\n label: entry.label,\n data: val ? '✓' : '✗',\n addColon: true,\n };\n }\n }\n\n return {\n id: deviceId,\n schema: {\n type: 'panel',\n items,\n },\n };\n }\n\n private getDeviceGroup(suffixes: Set<string>): { key: string; name: ioBroker.StringOrTranslated } {\n const list = [...suffixes].map(flatName);\n const test = (re: RegExp): boolean => list.some(s => re.test(s));\n\n let key = 'other';\n if (test(/^Shutter\\d+_Position$/)) {\n key = 'cover';\n } else if (test(/^(Color|CT|led_basecolor_rgb|led_basecolor_rgbcw|Dimmer|led_dimmer)$/)) {\n key = 'light';\n } else if (test(/^(POWER\\d*|led_enableAll)$/)) {\n key = 'relay';\n } else if (test(/^(ZbReceived_|ZbPower)/)) {\n key = 'zigbee';\n } else if (list.some(s => this.splitPowerSuffix(s) !== undefined)) {\n key = 'meter';\n } else if (list.some(s => SENSOR_KEYS.some(k => s === k || s.endsWith(`_${k}`)))) {\n key = 'sensor';\n }\n\n const meta = groupMeta[key] || groupMeta.other;\n return { key, name: I18n.getTranslatedObject(meta.nameKey) };\n }\n\n private buildCustomInfo(deviceId: string, prefix: string): DeviceDetails<string> | undefined {\n const shortDeviceId = deviceId.substring(this.adapter.namespace.length + 1);\n const items: Record<string, ConfigItemAny> = {};\n\n for (const sensor of SENSOR_ITEMS) {\n const suffix = this.findDataPointSuffix(prefix, sensor.stateId);\n if (suffix !== undefined) {\n items[sensor.stateId] = {\n type: 'state',\n oid: `${shortDeviceId}.${suffix}`,\n control: 'text',\n unit: sensor.unit,\n digits: sensor.digits,\n label: I18n.getTranslatedObject(sensor.label),\n addColon: true,\n style: { opacity: 0.7 },\n };\n }\n }\n\n // Power on the main tile: only the actual \"Power\" (W) readings, never voltage/current/energy\n const powerItems = this.getPowerEntries(prefix).filter(e => e.label === 'Power');\n const multiPower = powerItems.length > 1;\n for (const entry of powerItems) {\n const label = multiPower ? this.channelLabel(entry.channel) : I18n.getTranslatedObject('Power');\n items[`power_${entry.suffix.replace(/[.:]/g, '_')}`] = {\n type: 'state',\n oid: `${shortDeviceId}.${entry.suffix}`,\n control: 'text',\n unit: 'W',\n digits: 1,\n label,\n addColon: true,\n style: { opacity: 0.7 },\n };\n }\n if (powerItems.length) {\n items._powerSpacer = {\n type: 'divider',\n color: 'transparent',\n height: 2,\n };\n }\n\n if (Object.keys(items).length === 0) {\n return undefined;\n }\n\n return {\n id: deviceId,\n schema: {\n type: 'panel',\n items,\n },\n };\n }\n\n /**\n * Builds the controls of a device from its writable data points. Every data point is matched by its\n * flattened name (see `flatName`), so the same control shows up with and without the \"Create object\n * tree\" option. The current values come from the cached states instead of a request per control -\n * the cache holds all states of the adapter anyway (see `init`).\n */\n private buildControls(shortDeviceId: string, prefix: string): DeviceControl<string>[] {\n const controls: DeviceControl<string>[] = [];\n const used = new Set<string>();\n const rawStates: { id: string; suffix: string; name: string; common: ioBroker.StateCommon }[] = [];\n\n for (const id in this.objects) {\n if (id.startsWith(prefix) && this.objects[id].type === 'state') {\n const suffix = id.substring(prefix.length);\n rawStates.push({\n id,\n suffix,\n name: flatName(suffix),\n common: this.objects[id].common,\n });\n }\n }\n\n // Two state objects can flatten to the same name at once - e.g. a bare \"POWER\" next to a\n // leftover \"RESULT.POWER\" from before \"Create object tree\" was toggled. Both would end up as\n // a control with the same ID, which the Device Manager rejects as a duplicate - so only the\n // most recently updated copy of each name is kept (a leftover stops being updated, so its\n // timestamp falls behind, the same fallback rule as `getPowerEntries` uses).\n const byName = new Map<string, (typeof rawStates)[number]>();\n for (const state of rawStates) {\n const existing = byName.get(state.name);\n if (!existing || (this.states[state.id]?.ts ?? 0) > (this.states[existing.id]?.ts ?? 0)) {\n byName.set(state.name, state);\n }\n }\n const ownStates = [...byName.values()];\n\n const stateHandler =\n (fullId: string) =>\n async (_deviceId: string, _actionId: string, state: ControlState): Promise<ioBroker.State> => {\n await this.adapter.setForeignStateAsync(fullId, state);\n return { val: state, ts: Date.now(), ack: true } as ioBroker.State;\n };\n\n const currentState = (fullId: string): ioBroker.State =>\n this.states[fullId] || ({ val: null, ts: Date.now(), ack: true } as ioBroker.State);\n\n // A control is named after the data point it belongs to, not after where that data point is\n // stored, so its ID stays the same when \"Create object tree\" is toggled\n const controlId = (name: string): string => name.replace(/[.:]/g, '_');\n\n // Primary switches: POWER, POWER1..29, Zigbee bridge relays, OpenBeken LED enable\n const switchRe = /^(POWER\\d*|ZbReceived_.+_Power|led_enableAll)$/;\n for (const state of ownStates) {\n if (state.common?.type !== 'boolean' || state.common.write === false || !switchRe.test(state.name)) {\n continue;\n }\n used.add(state.id);\n const label =\n state.name === 'POWER'\n ? 'Power'\n : state.name.startsWith('POWER')\n ? `Power ${state.name.substring(5)}`\n : state.name.replace(/_/g, ' ');\n controls.push({\n id: controlId(state.name),\n type: 'switch',\n stateId: `${shortDeviceId}.${state.suffix}`,\n label: I18n.getTranslatedObject(label),\n state: currentState(state.id),\n handler: stateHandler(state.id),\n });\n }\n\n // Sliders: dimmer, color temperature, shutter position/tilt\n const sliderDefs: {\n re: RegExp;\n label: (m: RegExpMatchArray) => string;\n min: number;\n max: number;\n unit?: string;\n }[] = [\n { re: /^Dimmer$/, label: () => 'Dimmer', min: 0, max: 100, unit: '%' },\n { re: /^led_dimmer$/, label: () => 'Dimmer', min: 0, max: 100, unit: '%' },\n { re: /^CT$/, label: () => 'Color temperature', min: 153, max: 500 },\n { re: /^led_temperature$/, label: () => 'Color temperature', min: 154, max: 500 },\n { re: /^Shutter(\\d+)_Position$/, label: m => `Shutter ${m[1]} position`, min: 0, max: 100, unit: '%' },\n { re: /^Shutter(\\d+)_Tilt$/, label: m => `Shutter ${m[1]} tilt`, min: 0, max: 100, unit: '%' },\n ];\n for (const state of ownStates) {\n if (used.has(state.id) || state.common?.type !== 'number' || state.common.write === false) {\n continue;\n }\n for (const def of sliderDefs) {\n const match = state.name.match(def.re);\n if (!match) {\n continue;\n }\n used.add(state.id);\n controls.push({\n id: controlId(state.name),\n type: 'slider',\n stateId: `${shortDeviceId}.${state.suffix}`,\n min: state.common.min ?? def.min,\n max: state.common.max ?? def.max,\n unit: state.common.unit || def.unit,\n label: I18n.getTranslatedObject(def.label(match)),\n state: currentState(state.id),\n handler: stateHandler(state.id),\n });\n break;\n }\n }\n\n // Color controls\n const colorRe = /^(Color|led_basecolor_rgb|led_basecolor_rgbcw)$/;\n for (const state of ownStates) {\n if (\n used.has(state.id) ||\n state.common?.type !== 'string' ||\n !state.common.write ||\n !colorRe.test(state.name)\n ) {\n continue;\n }\n used.add(state.id);\n controls.push({\n id: controlId(state.name),\n type: 'color',\n stateId: `${shortDeviceId}.${state.suffix}`,\n label: I18n.getTranslatedObject('Color'),\n state: currentState(state.id),\n handler: stateHandler(state.id),\n });\n }\n\n // Everything else: writable settings not shown elsewhere. INFO/ENERGY/MARGINS are read-only\n // anyway, \"Time\" is the timestamp of the telemetry message a group of data points came with\n const skipRe = /^(INFO_|ENERGY_|MARGINS_|Wifi_|Time$|alive$)/;\n let group: DeviceControl<string> | null = {\n id: 'group_settings',\n type: 'group',\n label: I18n.getTranslatedObject('Settings'),\n };\n\n // Writable numbers/strings first, then the leftover booleans (toggles like Fade, LED exor\n // mode, ...) as buttons\n for (const pass of ['value', 'button'] as const) {\n for (const state of ownStates) {\n if (used.has(state.id) || skipRe.test(state.name) || !state.common || state.common.write === false) {\n continue;\n }\n const type = state.common.type;\n if (pass === 'value' ? type !== 'number' && type !== 'string' : type !== 'boolean') {\n continue;\n }\n used.add(state.id);\n\n if (group) {\n controls.push(group);\n group = null;\n }\n\n if (pass === 'button') {\n controls.push({\n group: 'group_settings',\n id: controlId(state.name),\n type: 'button',\n stateId: `${shortDeviceId}.${state.suffix}`,\n label: state.name.replace(/_/g, ' '),\n variant: 'outlined',\n handler: stateHandler(state.id),\n });\n continue;\n }\n\n let options: { label: string; value: string }[] | undefined;\n const commonStates = state.common.states;\n if (commonStates) {\n options = Array.isArray(commonStates)\n ? commonStates.map((s: string) => ({ value: s, label: s }))\n : Object.keys(commonStates).map(k => ({\n value: k,\n label: String((commonStates as Record<string, string>)[k]),\n }));\n }\n\n controls.push({\n group: 'group_settings',\n id: controlId(state.name),\n type: options ? 'select' : type === 'number' ? 'number' : 'text',\n stateId: `${shortDeviceId}.${state.suffix}`,\n min: state.common.min,\n max: state.common.max,\n unit: state.common.unit,\n options,\n label: state.name.replace(/_/g, ' '),\n state: currentState(state.id),\n handler: stateHandler(state.id),\n });\n }\n }\n\n return controls;\n }\n\n /**\n * @param id ID to rename\n * @param context context sent from backend\n */\n async handleRenameDevice(id: string, context: ActionContext): Promise<{ refresh: DeviceRefresh }> {\n const result = await context.showForm(\n {\n type: 'panel',\n items: {\n newName: {\n type: 'text',\n trim: false,\n placeholder: '',\n },\n },\n },\n {\n data: {\n newName: '',\n },\n title: I18n.getTranslatedObject('Enter new name'),\n },\n );\n if (result?.newName === undefined || result?.newName === '') {\n return { refresh: 'none' };\n }\n const obj = {\n common: {\n name: result.newName,\n },\n };\n\n const res = await this.adapter.extendForeignObjectAsync(id, obj);\n if (res === null) {\n this.adapter.log.warn(`Can not rename device ${id}: ${JSON.stringify(res)}`);\n return { refresh: 'none' };\n }\n return { refresh: 'device' as DeviceRefresh };\n }\n\n /**\n * Deletes every data point of a device - its channel object (and therefore a custom name set via\n * `rename`) is kept, everything else gets recreated automatically the next time the device reports\n * its state. This is a manual, user-triggered fix for data points stuck in an outdated structure,\n * e.g. leftovers from before the \"Create object tree\" adapter option was changed.\n *\n * `alive` is kept as well: it is not reported by the device but written by the adapter when the\n * MQTT client connects (see `createClient` in `mqttBase.ts`), so a deleted `alive` would only come\n * back the next time the device reconnects - which can take days for a device that is simply up.\n *\n * @param id device (channel) ID to recreate\n * @param _context unused - the destructive confirmation is handled declaratively by the action itself\n */\n async handleRecreateDevice(id: string, _context: ActionContext): Promise<{ refresh: DeviceRefresh }> {\n const prefix = `${id}.`;\n let removed = 0;\n for (const stateId in this.objects) {\n if (!stateId.startsWith(prefix) || this.objects[stateId].type !== 'state') {\n continue;\n }\n if (stateId === `${prefix}alive`) {\n continue;\n }\n try {\n await this.adapter.delForeignStateAsync(stateId);\n await this.adapter.delForeignObjectAsync(stateId);\n delete this.objects[stateId];\n delete this.states[stateId];\n removed++;\n } catch (error) {\n this.adapter.log.warn(`Cannot remove data point ${stateId}: ${error}`);\n }\n }\n\n // The server/bridge remembers which objects it has already created and would not create them a\n // second time within this adapter run, so the deleted data points have to be forgotten there\n // too - otherwise they only come back after a restart of the adapter\n this.adapter.server?.forgetObjects(id);\n\n this.adapter.log.info(`Removed ${removed} data point(s) of ${id}, they will be recreated automatically`);\n return { refresh: 'device' as DeviceRefresh };\n }\n}\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Relays & Switches": "Relais & Schalter",
|
|
3
|
+
"Lights & Dimmers": "Lichter & Dimmer",
|
|
4
|
+
"Shutters & Covers": "Rollläden & Abdeckungen",
|
|
5
|
+
"Zigbee bridges": "Zigbee-Gateways",
|
|
6
|
+
"Energy Meters": "Energiezähler",
|
|
7
|
+
"Sensors": "Sensoren",
|
|
8
|
+
"Other": "Sonstige",
|
|
9
|
+
"Settings": "Einstellungen",
|
|
10
|
+
"Rename this device": "Dieses Gerät umbenennen",
|
|
11
|
+
"Enter new name": "Neuen Namen eingeben",
|
|
12
|
+
"Delete and recreate all data points of this device": "Alle Datenpunkte dieses Geräts löschen und neu anlegen",
|
|
13
|
+
"This deletes all data points of this device (except its name). They will be recreated automatically the next time the device reports its state. Continue?": "Dadurch werden alle Datenpunkte dieses Geräts gelöscht (außer dem Namen). Sie werden automatisch neu angelegt, sobald das Gerät das nächste Mal seinen Status meldet. Fortfahren?",
|
|
14
|
+
"Open device web interface": "Weboberfläche des Geräts öffnen",
|
|
15
|
+
"Device ID": "Geräte-ID",
|
|
16
|
+
"RSSI": "RSSI",
|
|
17
|
+
"Uptime": "Laufzeit",
|
|
18
|
+
"Power": "Leistung",
|
|
19
|
+
"Power metering": "Leistungsmessung",
|
|
20
|
+
"Thresholds": "Schwellwerte",
|
|
21
|
+
"Digital inputs": "Digitale Eingänge",
|
|
22
|
+
"Color": "Farbe",
|
|
23
|
+
"Dimmer": "Dimmer",
|
|
24
|
+
"Color temperature": "Farbtemperatur",
|
|
25
|
+
"Temperature": "Temperatur",
|
|
26
|
+
"Humidity": "Luftfeuchtigkeit",
|
|
27
|
+
"Pressure": "Luftdruck",
|
|
28
|
+
"Illuminance": "Beleuchtungsstärke",
|
|
29
|
+
"CO2": "CO2",
|
|
30
|
+
"TVOC": "TVOC",
|
|
31
|
+
"Dew point": "Taupunkt",
|
|
32
|
+
"Voltage": "Spannung",
|
|
33
|
+
"Current": "Strom",
|
|
34
|
+
"Neutral current": "Neutralleiterstrom",
|
|
35
|
+
"Apparent power": "Scheinleistung",
|
|
36
|
+
"Reactive power": "Blindleistung",
|
|
37
|
+
"Power factor": "Leistungsfaktor",
|
|
38
|
+
"Frequency": "Frequenz",
|
|
39
|
+
"Today": "Heute",
|
|
40
|
+
"Today (import)": "Heute (Bezug)",
|
|
41
|
+
"Today (export)": "Heute (Einspeisung)",
|
|
42
|
+
"Yesterday": "Gestern",
|
|
43
|
+
"Total": "Gesamt",
|
|
44
|
+
"Total (import)": "Gesamt (Bezug)",
|
|
45
|
+
"Total (export)": "Gesamt (Einspeisung)",
|
|
46
|
+
"Returned energy": "Eingespeiste Energie",
|
|
47
|
+
"Power low threshold": "Leistungs-Schwellwert (min)",
|
|
48
|
+
"Power high threshold": "Leistungs-Schwellwert (max)",
|
|
49
|
+
"Power delta threshold": "Leistungs-Schwellwert (Delta)",
|
|
50
|
+
"Model": "Modell",
|
|
51
|
+
"Hostname": "Hostname",
|
|
52
|
+
"IP address": "IP-Adresse",
|
|
53
|
+
"MAC address": "MAC-Adresse",
|
|
54
|
+
"Gateway": "Gateway",
|
|
55
|
+
"Subnet mask": "Subnetzmaske",
|
|
56
|
+
"Firmware version": "Firmware-Version",
|
|
57
|
+
"Hardware": "Hardware",
|
|
58
|
+
"Build date": "Build-Datum",
|
|
59
|
+
"Core": "Core",
|
|
60
|
+
"SDK": "SDK"
|
|
61
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Relays & Switches": "Relays & Switches",
|
|
3
|
+
"Lights & Dimmers": "Lights & Dimmers",
|
|
4
|
+
"Shutters & Covers": "Shutters & Covers",
|
|
5
|
+
"Zigbee bridges": "Zigbee bridges",
|
|
6
|
+
"Energy Meters": "Energy Meters",
|
|
7
|
+
"Sensors": "Sensors",
|
|
8
|
+
"Other": "Other",
|
|
9
|
+
"Settings": "Settings",
|
|
10
|
+
"Rename this device": "Rename this device",
|
|
11
|
+
"Enter new name": "Enter new name",
|
|
12
|
+
"Delete and recreate all data points of this device": "Delete and recreate all data points of this device",
|
|
13
|
+
"This deletes all data points of this device (except its name). They will be recreated automatically the next time the device reports its state. Continue?": "This deletes all data points of this device (except its name). They will be recreated automatically the next time the device reports its state. Continue?",
|
|
14
|
+
"Open device web interface": "Open device web interface",
|
|
15
|
+
"Device ID": "Device ID",
|
|
16
|
+
"RSSI": "RSSI",
|
|
17
|
+
"Uptime": "Uptime",
|
|
18
|
+
"Power": "Power",
|
|
19
|
+
"Power metering": "Power metering",
|
|
20
|
+
"Thresholds": "Thresholds",
|
|
21
|
+
"Digital inputs": "Digital inputs",
|
|
22
|
+
"Color": "Color",
|
|
23
|
+
"Dimmer": "Dimmer",
|
|
24
|
+
"Color temperature": "Color temperature",
|
|
25
|
+
"Temperature": "Temperature",
|
|
26
|
+
"Humidity": "Humidity",
|
|
27
|
+
"Pressure": "Pressure",
|
|
28
|
+
"Illuminance": "Illuminance",
|
|
29
|
+
"CO2": "CO2",
|
|
30
|
+
"TVOC": "TVOC",
|
|
31
|
+
"Dew point": "Dew point",
|
|
32
|
+
"Voltage": "Voltage",
|
|
33
|
+
"Current": "Current",
|
|
34
|
+
"Neutral current": "Neutral current",
|
|
35
|
+
"Apparent power": "Apparent power",
|
|
36
|
+
"Reactive power": "Reactive power",
|
|
37
|
+
"Power factor": "Power factor",
|
|
38
|
+
"Frequency": "Frequency",
|
|
39
|
+
"Today": "Today",
|
|
40
|
+
"Today (import)": "Today (import)",
|
|
41
|
+
"Today (export)": "Today (export)",
|
|
42
|
+
"Yesterday": "Yesterday",
|
|
43
|
+
"Total": "Total",
|
|
44
|
+
"Total (import)": "Total (import)",
|
|
45
|
+
"Total (export)": "Total (export)",
|
|
46
|
+
"Returned energy": "Returned energy",
|
|
47
|
+
"Power low threshold": "Power low threshold",
|
|
48
|
+
"Power high threshold": "Power high threshold",
|
|
49
|
+
"Power delta threshold": "Power delta threshold",
|
|
50
|
+
"Model": "Model",
|
|
51
|
+
"Hostname": "Hostname",
|
|
52
|
+
"IP address": "IP address",
|
|
53
|
+
"MAC address": "MAC address",
|
|
54
|
+
"Gateway": "Gateway",
|
|
55
|
+
"Subnet mask": "Subnet mask",
|
|
56
|
+
"Firmware version": "Firmware version",
|
|
57
|
+
"Hardware": "Hardware",
|
|
58
|
+
"Build date": "Build date",
|
|
59
|
+
"Core": "Core",
|
|
60
|
+
"SDK": "SDK"
|
|
61
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Relays & Switches": "Relés e interruptores",
|
|
3
|
+
"Lights & Dimmers": "Luces y reguladores",
|
|
4
|
+
"Shutters & Covers": "Persianas y toldos",
|
|
5
|
+
"Zigbee bridges": "Puentes Zigbee",
|
|
6
|
+
"Energy Meters": "Contadores de energía",
|
|
7
|
+
"Sensors": "Sensores",
|
|
8
|
+
"Other": "Otros",
|
|
9
|
+
"Settings": "Ajustes",
|
|
10
|
+
"Rename this device": "Renombrar este dispositivo",
|
|
11
|
+
"Enter new name": "Introducir nuevo nombre",
|
|
12
|
+
"Delete and recreate all data points of this device": "Eliminar y volver a crear todos los puntos de datos de este dispositivo",
|
|
13
|
+
"This deletes all data points of this device (except its name). They will be recreated automatically the next time the device reports its state. Continue?": "Esto elimina todos los puntos de datos de este dispositivo (excepto su nombre). Se volverán a crear automáticamente la próxima vez que el dispositivo informe de su estado. ¿Continuar?",
|
|
14
|
+
"Open device web interface": "Abrir la interfaz web del dispositivo",
|
|
15
|
+
"Device ID": "ID del dispositivo",
|
|
16
|
+
"RSSI": "RSSI",
|
|
17
|
+
"Uptime": "Tiempo de actividad",
|
|
18
|
+
"Power": "Potencia",
|
|
19
|
+
"Power metering": "Medición de potencia",
|
|
20
|
+
"Thresholds": "Umbrales",
|
|
21
|
+
"Digital inputs": "Entradas digitales",
|
|
22
|
+
"Color": "Color",
|
|
23
|
+
"Dimmer": "Regulador",
|
|
24
|
+
"Color temperature": "Temperatura de color",
|
|
25
|
+
"Temperature": "Temperatura",
|
|
26
|
+
"Humidity": "Humedad",
|
|
27
|
+
"Pressure": "Presión",
|
|
28
|
+
"Illuminance": "Iluminancia",
|
|
29
|
+
"CO2": "CO2",
|
|
30
|
+
"TVOC": "TVOC",
|
|
31
|
+
"Dew point": "Punto de rocío",
|
|
32
|
+
"Voltage": "Tensión",
|
|
33
|
+
"Current": "Corriente",
|
|
34
|
+
"Neutral current": "Corriente de neutro",
|
|
35
|
+
"Apparent power": "Potencia aparente",
|
|
36
|
+
"Reactive power": "Potencia reactiva",
|
|
37
|
+
"Power factor": "Factor de potencia",
|
|
38
|
+
"Frequency": "Frecuencia",
|
|
39
|
+
"Today": "Hoy",
|
|
40
|
+
"Today (import)": "Hoy (consumo)",
|
|
41
|
+
"Today (export)": "Hoy (inyección)",
|
|
42
|
+
"Yesterday": "Ayer",
|
|
43
|
+
"Total": "Total",
|
|
44
|
+
"Total (import)": "Total (consumo)",
|
|
45
|
+
"Total (export)": "Total (inyección)",
|
|
46
|
+
"Returned energy": "Energía inyectada",
|
|
47
|
+
"Power low threshold": "Umbral inferior de potencia",
|
|
48
|
+
"Power high threshold": "Umbral superior de potencia",
|
|
49
|
+
"Power delta threshold": "Umbral delta de potencia",
|
|
50
|
+
"Model": "Modelo",
|
|
51
|
+
"Hostname": "Nombre de host",
|
|
52
|
+
"IP address": "Dirección IP",
|
|
53
|
+
"MAC address": "Dirección MAC",
|
|
54
|
+
"Gateway": "Puerta de enlace",
|
|
55
|
+
"Subnet mask": "Máscara de subred",
|
|
56
|
+
"Firmware version": "Versión de firmware",
|
|
57
|
+
"Hardware": "Hardware",
|
|
58
|
+
"Build date": "Fecha de compilación",
|
|
59
|
+
"Core": "Core",
|
|
60
|
+
"SDK": "SDK"
|
|
61
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Relays & Switches": "Relais et interrupteurs",
|
|
3
|
+
"Lights & Dimmers": "Lumières et variateurs",
|
|
4
|
+
"Shutters & Covers": "Volets et stores",
|
|
5
|
+
"Zigbee bridges": "Passerelles Zigbee",
|
|
6
|
+
"Energy Meters": "Compteurs d'énergie",
|
|
7
|
+
"Sensors": "Capteurs",
|
|
8
|
+
"Other": "Autres",
|
|
9
|
+
"Settings": "Paramètres",
|
|
10
|
+
"Rename this device": "Renommer cet appareil",
|
|
11
|
+
"Enter new name": "Saisir un nouveau nom",
|
|
12
|
+
"Delete and recreate all data points of this device": "Supprimer et recréer tous les points de données de cet appareil",
|
|
13
|
+
"This deletes all data points of this device (except its name). They will be recreated automatically the next time the device reports its state. Continue?": "Ceci supprime tous les points de données de cet appareil (sauf son nom). Ils seront recréés automatiquement à la prochaine remontée d'état de l'appareil. Continuer ?",
|
|
14
|
+
"Open device web interface": "Ouvrir l'interface web de l'appareil",
|
|
15
|
+
"Device ID": "ID de l'appareil",
|
|
16
|
+
"RSSI": "RSSI",
|
|
17
|
+
"Uptime": "Durée de fonctionnement",
|
|
18
|
+
"Power": "Puissance",
|
|
19
|
+
"Power metering": "Mesure de puissance",
|
|
20
|
+
"Thresholds": "Seuils",
|
|
21
|
+
"Digital inputs": "Entrées numériques",
|
|
22
|
+
"Color": "Couleur",
|
|
23
|
+
"Dimmer": "Variateur",
|
|
24
|
+
"Color temperature": "Température de couleur",
|
|
25
|
+
"Temperature": "Température",
|
|
26
|
+
"Humidity": "Humidité",
|
|
27
|
+
"Pressure": "Pression",
|
|
28
|
+
"Illuminance": "Éclairement",
|
|
29
|
+
"CO2": "CO2",
|
|
30
|
+
"TVOC": "TVOC",
|
|
31
|
+
"Dew point": "Point de rosée",
|
|
32
|
+
"Voltage": "Tension",
|
|
33
|
+
"Current": "Courant",
|
|
34
|
+
"Neutral current": "Courant de neutre",
|
|
35
|
+
"Apparent power": "Puissance apparente",
|
|
36
|
+
"Reactive power": "Puissance réactive",
|
|
37
|
+
"Power factor": "Facteur de puissance",
|
|
38
|
+
"Frequency": "Fréquence",
|
|
39
|
+
"Today": "Aujourd'hui",
|
|
40
|
+
"Today (import)": "Aujourd'hui (soutirage)",
|
|
41
|
+
"Today (export)": "Aujourd'hui (injection)",
|
|
42
|
+
"Yesterday": "Hier",
|
|
43
|
+
"Total": "Total",
|
|
44
|
+
"Total (import)": "Total (soutirage)",
|
|
45
|
+
"Total (export)": "Total (injection)",
|
|
46
|
+
"Returned energy": "Énergie injectée",
|
|
47
|
+
"Power low threshold": "Seuil de puissance bas",
|
|
48
|
+
"Power high threshold": "Seuil de puissance haut",
|
|
49
|
+
"Power delta threshold": "Seuil de variation de puissance",
|
|
50
|
+
"Model": "Modèle",
|
|
51
|
+
"Hostname": "Nom d'hôte",
|
|
52
|
+
"IP address": "Adresse IP",
|
|
53
|
+
"MAC address": "Adresse MAC",
|
|
54
|
+
"Gateway": "Passerelle",
|
|
55
|
+
"Subnet mask": "Masque de sous-réseau",
|
|
56
|
+
"Firmware version": "Version du micrologiciel",
|
|
57
|
+
"Hardware": "Matériel",
|
|
58
|
+
"Build date": "Date de compilation",
|
|
59
|
+
"Core": "Core",
|
|
60
|
+
"SDK": "SDK"
|
|
61
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Relays & Switches": "Relè e interruttori",
|
|
3
|
+
"Lights & Dimmers": "Luci e dimmer",
|
|
4
|
+
"Shutters & Covers": "Tapparelle e tende",
|
|
5
|
+
"Zigbee bridges": "Bridge Zigbee",
|
|
6
|
+
"Energy Meters": "Contatori di energia",
|
|
7
|
+
"Sensors": "Sensori",
|
|
8
|
+
"Other": "Altro",
|
|
9
|
+
"Settings": "Impostazioni",
|
|
10
|
+
"Rename this device": "Rinomina questo dispositivo",
|
|
11
|
+
"Enter new name": "Inserisci un nuovo nome",
|
|
12
|
+
"Delete and recreate all data points of this device": "Elimina e ricrea tutti i punti dati di questo dispositivo",
|
|
13
|
+
"This deletes all data points of this device (except its name). They will be recreated automatically the next time the device reports its state. Continue?": "Questa operazione elimina tutti i punti dati di questo dispositivo (tranne il nome). Verranno ricreati automaticamente alla prossima segnalazione di stato del dispositivo. Continuare?",
|
|
14
|
+
"Open device web interface": "Apri l'interfaccia web del dispositivo",
|
|
15
|
+
"Device ID": "ID dispositivo",
|
|
16
|
+
"RSSI": "RSSI",
|
|
17
|
+
"Uptime": "Tempo di attività",
|
|
18
|
+
"Power": "Potenza",
|
|
19
|
+
"Power metering": "Misurazione della potenza",
|
|
20
|
+
"Thresholds": "Soglie",
|
|
21
|
+
"Digital inputs": "Ingressi digitali",
|
|
22
|
+
"Color": "Colore",
|
|
23
|
+
"Dimmer": "Dimmer",
|
|
24
|
+
"Color temperature": "Temperatura del colore",
|
|
25
|
+
"Temperature": "Temperatura",
|
|
26
|
+
"Humidity": "Umidità",
|
|
27
|
+
"Pressure": "Pressione",
|
|
28
|
+
"Illuminance": "Illuminamento",
|
|
29
|
+
"CO2": "CO2",
|
|
30
|
+
"TVOC": "TVOC",
|
|
31
|
+
"Dew point": "Punto di rugiada",
|
|
32
|
+
"Voltage": "Tensione",
|
|
33
|
+
"Current": "Corrente",
|
|
34
|
+
"Neutral current": "Corrente di neutro",
|
|
35
|
+
"Apparent power": "Potenza apparente",
|
|
36
|
+
"Reactive power": "Potenza reattiva",
|
|
37
|
+
"Power factor": "Fattore di potenza",
|
|
38
|
+
"Frequency": "Frequenza",
|
|
39
|
+
"Today": "Oggi",
|
|
40
|
+
"Today (import)": "Oggi (prelievo)",
|
|
41
|
+
"Today (export)": "Oggi (immissione)",
|
|
42
|
+
"Yesterday": "Ieri",
|
|
43
|
+
"Total": "Totale",
|
|
44
|
+
"Total (import)": "Totale (prelievo)",
|
|
45
|
+
"Total (export)": "Totale (immissione)",
|
|
46
|
+
"Returned energy": "Energia immessa",
|
|
47
|
+
"Power low threshold": "Soglia di potenza minima",
|
|
48
|
+
"Power high threshold": "Soglia di potenza massima",
|
|
49
|
+
"Power delta threshold": "Soglia delta di potenza",
|
|
50
|
+
"Model": "Modello",
|
|
51
|
+
"Hostname": "Nome host",
|
|
52
|
+
"IP address": "Indirizzo IP",
|
|
53
|
+
"MAC address": "Indirizzo MAC",
|
|
54
|
+
"Gateway": "Gateway",
|
|
55
|
+
"Subnet mask": "Maschera di sottorete",
|
|
56
|
+
"Firmware version": "Versione del firmware",
|
|
57
|
+
"Hardware": "Hardware",
|
|
58
|
+
"Build date": "Data di build",
|
|
59
|
+
"Core": "Core",
|
|
60
|
+
"SDK": "SDK"
|
|
61
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Relays & Switches": "Relais & schakelaars",
|
|
3
|
+
"Lights & Dimmers": "Lampen & dimmers",
|
|
4
|
+
"Shutters & Covers": "Rolluiken & zonwering",
|
|
5
|
+
"Zigbee bridges": "Zigbee-bridges",
|
|
6
|
+
"Energy Meters": "Energiemeters",
|
|
7
|
+
"Sensors": "Sensoren",
|
|
8
|
+
"Other": "Overig",
|
|
9
|
+
"Settings": "Instellingen",
|
|
10
|
+
"Rename this device": "Dit apparaat hernoemen",
|
|
11
|
+
"Enter new name": "Nieuwe naam invoeren",
|
|
12
|
+
"Delete and recreate all data points of this device": "Alle datapunten van dit apparaat verwijderen en opnieuw aanmaken",
|
|
13
|
+
"This deletes all data points of this device (except its name). They will be recreated automatically the next time the device reports its state. Continue?": "Hiermee worden alle datapunten van dit apparaat verwijderd (behalve de naam). Ze worden automatisch opnieuw aangemaakt zodra het apparaat de volgende keer zijn status meldt. Doorgaan?",
|
|
14
|
+
"Open device web interface": "Webinterface van het apparaat openen",
|
|
15
|
+
"Device ID": "Apparaat-ID",
|
|
16
|
+
"RSSI": "RSSI",
|
|
17
|
+
"Uptime": "Bedrijfstijd",
|
|
18
|
+
"Power": "Vermogen",
|
|
19
|
+
"Power metering": "Vermogensmeting",
|
|
20
|
+
"Thresholds": "Drempelwaarden",
|
|
21
|
+
"Digital inputs": "Digitale ingangen",
|
|
22
|
+
"Color": "Kleur",
|
|
23
|
+
"Dimmer": "Dimmer",
|
|
24
|
+
"Color temperature": "Kleurtemperatuur",
|
|
25
|
+
"Temperature": "Temperatuur",
|
|
26
|
+
"Humidity": "Luchtvochtigheid",
|
|
27
|
+
"Pressure": "Luchtdruk",
|
|
28
|
+
"Illuminance": "Verlichtingssterkte",
|
|
29
|
+
"CO2": "CO2",
|
|
30
|
+
"TVOC": "TVOC",
|
|
31
|
+
"Dew point": "Dauwpunt",
|
|
32
|
+
"Voltage": "Spanning",
|
|
33
|
+
"Current": "Stroom",
|
|
34
|
+
"Neutral current": "Nulleiderstroom",
|
|
35
|
+
"Apparent power": "Schijnbaar vermogen",
|
|
36
|
+
"Reactive power": "Blindvermogen",
|
|
37
|
+
"Power factor": "Arbeidsfactor",
|
|
38
|
+
"Frequency": "Frequentie",
|
|
39
|
+
"Today": "Vandaag",
|
|
40
|
+
"Today (import)": "Vandaag (afname)",
|
|
41
|
+
"Today (export)": "Vandaag (teruglevering)",
|
|
42
|
+
"Yesterday": "Gisteren",
|
|
43
|
+
"Total": "Totaal",
|
|
44
|
+
"Total (import)": "Totaal (afname)",
|
|
45
|
+
"Total (export)": "Totaal (teruglevering)",
|
|
46
|
+
"Returned energy": "Teruggeleverde energie",
|
|
47
|
+
"Power low threshold": "Ondergrens vermogen",
|
|
48
|
+
"Power high threshold": "Bovengrens vermogen",
|
|
49
|
+
"Power delta threshold": "Deltadrempel vermogen",
|
|
50
|
+
"Model": "Model",
|
|
51
|
+
"Hostname": "Hostnaam",
|
|
52
|
+
"IP address": "IP-adres",
|
|
53
|
+
"MAC address": "MAC-adres",
|
|
54
|
+
"Gateway": "Gateway",
|
|
55
|
+
"Subnet mask": "Subnetmasker",
|
|
56
|
+
"Firmware version": "Firmwareversie",
|
|
57
|
+
"Hardware": "Hardware",
|
|
58
|
+
"Build date": "Builddatum",
|
|
59
|
+
"Core": "Core",
|
|
60
|
+
"SDK": "SDK"
|
|
61
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Relays & Switches": "Przekaźniki i przełączniki",
|
|
3
|
+
"Lights & Dimmers": "Światła i ściemniacze",
|
|
4
|
+
"Shutters & Covers": "Rolety i markizy",
|
|
5
|
+
"Zigbee bridges": "Bramki Zigbee",
|
|
6
|
+
"Energy Meters": "Liczniki energii",
|
|
7
|
+
"Sensors": "Czujniki",
|
|
8
|
+
"Other": "Inne",
|
|
9
|
+
"Settings": "Ustawienia",
|
|
10
|
+
"Rename this device": "Zmień nazwę tego urządzenia",
|
|
11
|
+
"Enter new name": "Wprowadź nową nazwę",
|
|
12
|
+
"Delete and recreate all data points of this device": "Usuń i utwórz ponownie wszystkie punkty danych tego urządzenia",
|
|
13
|
+
"This deletes all data points of this device (except its name). They will be recreated automatically the next time the device reports its state. Continue?": "Spowoduje to usunięcie wszystkich punktów danych tego urządzenia (z wyjątkiem jego nazwy). Zostaną one utworzone ponownie automatycznie, gdy urządzenie następnym razem zgłosi swój stan. Kontynuować?",
|
|
14
|
+
"Open device web interface": "Otwórz interfejs webowy urządzenia",
|
|
15
|
+
"Device ID": "ID urządzenia",
|
|
16
|
+
"RSSI": "RSSI",
|
|
17
|
+
"Uptime": "Czas pracy",
|
|
18
|
+
"Power": "Moc",
|
|
19
|
+
"Power metering": "Pomiar mocy",
|
|
20
|
+
"Thresholds": "Progi",
|
|
21
|
+
"Digital inputs": "Wejścia cyfrowe",
|
|
22
|
+
"Color": "Kolor",
|
|
23
|
+
"Dimmer": "Ściemniacz",
|
|
24
|
+
"Color temperature": "Temperatura barwowa",
|
|
25
|
+
"Temperature": "Temperatura",
|
|
26
|
+
"Humidity": "Wilgotność",
|
|
27
|
+
"Pressure": "Ciśnienie",
|
|
28
|
+
"Illuminance": "Natężenie oświetlenia",
|
|
29
|
+
"CO2": "CO2",
|
|
30
|
+
"TVOC": "TVOC",
|
|
31
|
+
"Dew point": "Punkt rosy",
|
|
32
|
+
"Voltage": "Napięcie",
|
|
33
|
+
"Current": "Prąd",
|
|
34
|
+
"Neutral current": "Prąd w przewodzie neutralnym",
|
|
35
|
+
"Apparent power": "Moc pozorna",
|
|
36
|
+
"Reactive power": "Moc bierna",
|
|
37
|
+
"Power factor": "Współczynnik mocy",
|
|
38
|
+
"Frequency": "Częstotliwość",
|
|
39
|
+
"Today": "Dzisiaj",
|
|
40
|
+
"Today (import)": "Dzisiaj (pobór)",
|
|
41
|
+
"Today (export)": "Dzisiaj (oddanie)",
|
|
42
|
+
"Yesterday": "Wczoraj",
|
|
43
|
+
"Total": "Łącznie",
|
|
44
|
+
"Total (import)": "Łącznie (pobór)",
|
|
45
|
+
"Total (export)": "Łącznie (oddanie)",
|
|
46
|
+
"Returned energy": "Energia oddana",
|
|
47
|
+
"Power low threshold": "Dolny próg mocy",
|
|
48
|
+
"Power high threshold": "Górny próg mocy",
|
|
49
|
+
"Power delta threshold": "Próg zmiany mocy",
|
|
50
|
+
"Model": "Model",
|
|
51
|
+
"Hostname": "Nazwa hosta",
|
|
52
|
+
"IP address": "Adres IP",
|
|
53
|
+
"MAC address": "Adres MAC",
|
|
54
|
+
"Gateway": "Brama",
|
|
55
|
+
"Subnet mask": "Maska podsieci",
|
|
56
|
+
"Firmware version": "Wersja oprogramowania układowego",
|
|
57
|
+
"Hardware": "Sprzęt",
|
|
58
|
+
"Build date": "Data kompilacji",
|
|
59
|
+
"Core": "Core",
|
|
60
|
+
"SDK": "SDK"
|
|
61
|
+
}
|