iobroker.arylic 0.1.0 → 0.1.2

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 CHANGED
@@ -23,6 +23,12 @@ The LA50 forwards plain text on TCP port 2018 to its amplifier chip, in the form
23
23
  the same commands, but wrapped (`MCU+PAS+RAKOIT:…&`) in their TCP API. The adapter is built so that
24
24
  this can be added as a second transport — if you own such a device and can test, please open an issue.
25
25
 
26
+ ## Requirements
27
+
28
+ - Node.js 22 or newer
29
+ - js-controller 6.0.11 or newer
30
+ - admin 7.8.1 or newer
31
+
26
32
  ## Finding devices
27
33
 
28
34
  With **Find devices automatically** on, the adapter listens for AirPlay announcements (mDNS) carrying
@@ -94,6 +100,15 @@ every power cut.
94
100
  Placeholder for the next version (at the beginning of the line):
95
101
  ### **WORK IN PROGRESS**
96
102
  -->
103
+ ### 0.1.2 (2026-10-14)
104
+
105
+ - (Timo Schneider) maximum volume uses the role `level` instead of the unknown `level.volume.max`
106
+ - (Timo Schneider) names of states, channels and device manager labels in all ioBroker languages
107
+
108
+ ### 0.1.1 (2026-10-14)
109
+
110
+ - (Timo Schneider) readable names (English, German) for all states and channels; buttons start with a value
111
+
97
112
  ### 0.1.0 (2026-10-14)
98
113
 
99
114
  - (Timo Schneider) sound (balance, EQ, virtual bass, crossover), settings, playback buttons, network status
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "arylic",
4
- "version": "0.1.0",
4
+ "version": "0.1.2",
5
5
  "news": {
6
+ "0.1.2": {
7
+ "en": "maximum volume uses the role `level` instead of the unknown `level.volume.max`\nnames of states, channels and device manager labels in all ioBroker languages",
8
+ "de": "Maximum Volume verwendet die Rolle `Level` statt `level.volume.max`\nBundesnamen, Kanäle und Gerätemanager in allen ioBroker-Sprachen",
9
+ "ru": "максимальная громкость использует роль `level` вместо неизвестного `level.volume.max`\nназвания штатов, каналов и ярлыков диспетчера устройств на всех языках IOBroker",
10
+ "pt": "volume máximo usa a função `level` em vez de `level.volume.max`\nnomes de estados, canais e selos em todos os idiomas da ioBroker",
11
+ "nl": "maximum volume gebruikt de rol `level` in plaats van de onbekende `level.volume.max`\nnamen van staten, kanalen en labels voor apparaatbeheerders in alle talen van IOBroker",
12
+ "fr": "maximum volume utilise le rôle « level » au lieu de l'inconnu « level.volume.max »\nnoms des États, chaînes et labels Device Manager dans toutes les langues d'IOBroker",
13
+ "it": "maximum volume usa il ruolo `level` anziché `level.volume.max` sconosciuto\nnomi di stati, canali ed etichette Device Manager in tutte le lingue di IOBroker",
14
+ "es": "maximum volume usa el rol `level' en lugar del desconocido `level.volume.max`\nnombres de estados, canales y etiquetas de gestión de dispositivos en todos los idiomas de ioBroker",
15
+ "pl": "maksymalna objętość używa roli `level` zamiast nieznanego `level.volume.max`\nnazwy stanów, kanałów i etykiet menedżera urządzeń we wszystkich językach iOBroker",
16
+ "uk": "максимальна гучність використовує роль `level` замість невідомого `level.volume.max`\nназви станів, каналів та міток диспетчера пристроїв у всіх мовах IObroker",
17
+ "zh-cn": "最大音量使用角色 “等级” 而不是未知的 “level.volume.max”\n所有 IOBroker 语言的州、频道和设备管理器标签的名称"
18
+ },
19
+ "0.1.1": {
20
+ "en": "readable names (English, German) for all states and channels; buttons start with a value",
21
+ "de": "lesbare Namen (DE, EN) für alle Staaten und Kanäle; Buttons beginnen mit einem Wert",
22
+ "ru": "читаемые названия (английский, немецкий) для всех штатов и каналов; кнопки начинаются со значения",
23
+ "pt": "nomes legíveis (inglês, alemão) de todos os estados e canais; botões começam com um valor",
24
+ "nl": "leesbare namen (Engels, Duits) voor alle staten en kanalen; knoppen beginnen met een waarde",
25
+ "fr": "noms lisibles (anglais, allemand) pour tous les états et chaînes ; boutons commençant par une valeur",
26
+ "it": "nomi leggibili (inglese, tedesco) per tutti gli stati e canali; i tasti iniziano con un valore",
27
+ "es": "nombres legibles (inglés, alemán) para todos los estados y canales; los botones empiezan por un valor",
28
+ "pl": "czytelne nazwy (angielski, niemiecki) dla wszystkich stanów i kanałów; przyciski zaczynają się od wartości",
29
+ "uk": "читаються назви (англійська, німецька) для всіх штатів і каналів; кнопки починаються зі значення",
30
+ "zh-cn": "所有州和频道的可读名称(英语、德语);按钮以值开头"
31
+ },
6
32
  "0.1.0": {
7
33
  "en": "sound (balance, EQ, virtual bass, crossover), settings, playback buttons, network status\nstates grouped into `sound`, `settings`, `info`; outdated states are removed — **state ids changed**\nchoices for input and EQ preset come from the device\ndevice manager: found devices with status, details, refresh and a link to the web interface (admin 7.8.1 or newer)\nwritten values are checked: `\"false\"`/`\"0\"` count as false, numbers are limited to their range, text must not contain `;`\na device that stops answering is reconnected; an address change is picked up within 5 minutes\nthe device name comes from the device; quick button presses are no longer merged",
8
34
  "de": "Ton (Balance, EQ, Virtual Bass, Crossover), Einstellungen, Abspieltasten, Netzwerkstatus\nStatus gruppiert nach „Sound“, „Settings“, „Info“; veraltete Status werden entfernt — **Status-IDs geändert**\nEingabe und EQ-Preset wählen Sie vom Gerät\nGerätemanager: Geräte mit Status, Details, Refresh und Webinterface gefunden (Admin 7.8.1 oder neuer)\nWerte werden geprüft: `\"false\"`/`\"0\"` gelten als falsch, Zahlen sind begrenzt, Text darf nicht `;`\nGerät, das nicht mehr reagiert, wird neu verbunden; Adressänderung innerhalb von 5 Minuten\nDer Gerätename stammt vom Gerät; Schnelltasten sind nicht mehr vereint",
@@ -1,17 +1,18 @@
1
1
  'use strict';
2
2
 
3
3
  const { DeviceManagement } = require('@iobroker/dm-utils');
4
+ const { translate } = require('./i18n');
4
5
 
5
6
  // Shown below an expanded device, live from its states.
6
7
  const DETAILS = [
7
- ['IP address', 'info.ip'],
8
- ['Model', 'info.model'],
9
- ['Serial number', 'info.serial'],
10
- ['Firmware', 'info.firmware'],
11
- ['Amplifier chip', 'info.mcuVersion'],
12
- ['Input', 'source'],
13
- ['Volume', 'volume'],
14
- ['Maximum volume', 'maxVolume'],
8
+ [{ en: 'IP address', de: 'IP-Adresse' }, 'info.ip'],
9
+ [{ en: 'Model', de: 'Modell' }, 'info.model'],
10
+ [{ en: 'Serial number', de: 'Seriennummer' }, 'info.serial'],
11
+ [{ en: 'Firmware', de: 'Firmware' }, 'info.firmware'],
12
+ [{ en: 'Amplifier chip', de: 'Verstärker-Chip' }, 'info.mcuVersion'],
13
+ [{ en: 'Input', de: 'Eingang' }, 'source'],
14
+ [{ en: 'Volume', de: 'Lautstärke' }, 'volume'],
15
+ [{ en: 'Maximum volume', de: 'Höchstlautstärke' }, 'maxVolume'],
15
16
  ];
16
17
 
17
18
  const ICON =
@@ -28,7 +29,7 @@ class ArylicDeviceManagement extends DeviceManagement {
28
29
  getInstanceInfo() {
29
30
  return {
30
31
  ...super.getInstanceInfo(),
31
- identifierLabel: { en: 'IP address', de: 'IP-Adresse' },
32
+ identifierLabel: translate({ en: 'IP address', de: 'IP-Adresse' }),
32
33
  };
33
34
  }
34
35
 
@@ -57,7 +58,7 @@ class ArylicDeviceManagement extends DeviceManagement {
57
58
  {
58
59
  id: 'refresh',
59
60
  icon: 'refresh',
60
- description: { en: 'Read all values now', de: 'Alle Werte jetzt lesen' },
61
+ description: translate({ en: 'Read all values now', de: 'Alle Werte jetzt lesen' }),
61
62
  handler: () => {
62
63
  device.refresh();
63
64
  return { refresh: 'none' };
@@ -66,7 +67,7 @@ class ArylicDeviceManagement extends DeviceManagement {
66
67
  {
67
68
  id: 'web',
68
69
  icon: 'web',
69
- description: { en: 'Open the web interface', de: 'Weboberfläche öffnen' },
70
+ description: translate({ en: 'Open the web interface', de: 'Weboberfläche öffnen' }),
70
71
  url: `http://${device.host}`,
71
72
  },
72
73
  ],
@@ -81,7 +82,13 @@ class ArylicDeviceManagement extends DeviceManagement {
81
82
  getDeviceDetails(id) {
82
83
  const items = {};
83
84
  DETAILS.forEach(([label, stateId], i) => {
84
- items[`row${i}`] = { type: 'state', oid: `${id}.${stateId}`, label, control: 'text', sm: 12 };
85
+ items[`row${i}`] = {
86
+ type: 'state',
87
+ oid: `${id}.${stateId}`,
88
+ label: translate(label),
89
+ control: 'text',
90
+ sm: 12,
91
+ };
85
92
  });
86
93
  return { id, schema: { type: 'panel', items } };
87
94
  }
package/lib/device.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const { RawTcpTransport } = require('./transport');
4
+ const { translate } = require('./i18n');
4
5
  const {
5
6
  KINDS,
6
7
  STATES,
@@ -97,7 +98,7 @@ class ArylicDevice {
97
98
  CHANNELS.map(channel =>
98
99
  this.adapter.extendObjectAsync(`${this.id}.${channel}`, {
99
100
  type: 'channel',
100
- common: { name: CHANNEL_NAMES[channel] || channel },
101
+ common: { name: CHANNEL_NAMES[channel] ? translate(CHANNEL_NAMES[channel]) : channel },
101
102
  native: {},
102
103
  }),
103
104
  ),
@@ -108,7 +109,7 @@ class ArylicDevice {
108
109
  return this.adapter.extendObjectAsync(`${this.id}.${field.id}`, {
109
110
  type: 'state',
110
111
  common: {
111
- name: field.code || field.id.split('.').pop(),
112
+ name: translate(field.name),
112
113
  type: kind.type,
113
114
  def: kind.def,
114
115
  read: field.kind !== 'button',
@@ -120,6 +121,8 @@ class ArylicDevice {
120
121
  }),
121
122
  );
122
123
  await this.removeLeftovers();
124
+ // Buttons are never read; without a value they look unfinished in the admin.
125
+ STATES.filter(f => f.kind === 'button').forEach(f => this.adapter.setState(`${this.id}.${f.id}`, false, true));
123
126
  // Not connected yet — whatever an earlier run left there is stale.
124
127
  this.setValue('info.connected', false);
125
128
  this.setInfo(this.info);
package/lib/fields.js CHANGED
@@ -90,63 +90,67 @@ const TEXT = { role: 'text' };
90
90
  // change at runtime. statesOf: the value is the list of choices for that field.
91
91
  // prettier-ignore
92
92
  const FIELDS = [
93
- { code: 'VOL', id: 'volume', kind: 'int', write: true, common: { role: 'level.volume', min: 0, max: 100 } },
94
- { code: 'MXV', id: 'maxVolume', kind: 'int', write: true, common: { role: 'level.volume.max', min: 30, max: 100 } },
95
- { code: 'MUT', id: 'mute', kind: 'bool', write: true, common: { role: 'media.mute' } },
96
- { code: 'SRC', id: 'source', kind: 'text', write: true, common: { role: 'media.input' } },
97
- { code: 'LST', id: 'sources', kind: 'text', write: false, once: true, statesOf: 'source', common: TEXT },
98
- { code: 'PLA', id: 'playing', kind: 'bool', write: false, common: { role: 'media.state' } },
99
- { code: 'POP', id: 'playPause', kind: 'button', write: true, common: { role: 'button' } },
100
- { code: 'STP', id: 'stop', kind: 'button', write: true, common: { role: 'button.stop' } },
101
- { code: 'NXT', id: 'next', kind: 'button', write: true, common: { role: 'button.next' } },
102
- { code: 'PRE', id: 'previous', kind: 'button', write: true, common: { role: 'button.prev' } },
103
-
104
- { code: 'BAS', id: 'sound.bass', kind: 'int', write: true, common: TONE },
105
- { code: 'MID', id: 'sound.mid', kind: 'int', write: true, common: TONE },
106
- { code: 'TRE', id: 'sound.treble', kind: 'int', write: true, common: TONE },
107
- { code: 'BAL', id: 'sound.balance', kind: 'int', write: true, common: { role: 'level', min: -100, max: 100 } },
108
- { code: 'VBS', id: 'sound.virtualBass', kind: 'bool', write: true, common: SWITCH },
109
- { code: 'EQE', id: 'sound.eqEnabled', kind: 'bool', write: true, common: SWITCH },
110
- { code: 'EQS', id: 'sound.eqPreset', kind: 'int', write: true, common: { role: 'level' } },
111
- { code: 'PEQ', id: 'sound.eqPresets', kind: 'text', write: false, once: true, statesOf: 'sound.eqPreset', common: TEXT },
112
- { code: 'CFE', id: 'sound.crossover', kind: 'bool', write: true, common: SWITCH },
113
- { code: 'CFF', id: 'sound.crossoverFrequency', kind: 'int', write: true, common: { role: 'level', min: 50, max: 300, unit: 'Hz' } },
114
-
115
- { code: 'LED', id: 'settings.led', kind: 'bool', write: true, common: SWITCH },
116
- { code: 'BEP', id: 'settings.beep', kind: 'bool', write: true, common: SWITCH },
117
- { code: 'NAM', id: 'settings.name', kind: 'hex', write: true, common: { role: 'info.name' } },
118
- { code: 'DLY', id: 'settings.muteDelay', kind: 'int', write: true, common: { role: 'level', min: 0, max: 32767, unit: 's' } },
119
- { code: 'POM', id: 'settings.powerOnSource', kind: 'text', write: true, common: TEXT },
120
- { code: 'ASW', id: 'settings.autoSwitch', kind: 'bool', write: true, common: SWITCH },
121
- { code: 'VST', id: 'settings.volumeStep', kind: 'int', write: true, common: { role: 'level', min: 0, max: 10 } },
122
- { code: 'VOF', id: 'settings.fixedVolume', kind: 'int', write: true, common: { role: 'level.volume', min: 0, max: 100 } },
123
- { code: 'SOP', id: 'settings.standbyOnPower', kind: 'bool', write: true, common: SWITCH },
124
-
125
- { code: 'IPA', id: 'info.ip', kind: 'text', write: false, common: { role: 'info.ip' } },
126
- { code: 'ETH', id: 'info.ethernet', kind: 'bool', write: false, common: { role: 'indicator.connected' } },
127
- { code: 'WIF', id: 'info.wifi', kind: 'bool', write: false, common: { role: 'indicator.connected' } },
128
- { code: 'CHN', id: 'info.multiroomChannel', kind: 'text', write: false, common: TEXT },
129
- { code: 'MRM', id: 'info.multiroomMode', kind: 'text', write: false, common: TEXT },
130
- { code: 'VER', id: 'info.mcuVersion', kind: 'text', write: false, once: true, common: { role: 'info.firmware' } },
93
+ { code: 'VOL', id: 'volume', name: { en: 'Volume', de: 'Lautstärke' }, kind: 'int', write: true, common: { role: 'level.volume', min: 0, max: 100 } },
94
+ { code: 'MXV', id: 'maxVolume', name: { en: 'Maximum volume', de: 'Höchstlautstärke' }, kind: 'int', write: true, common: { role: 'level', min: 30, max: 100 } },
95
+ { code: 'MUT', id: 'mute', name: { en: 'Mute', de: 'Stumm' }, kind: 'bool', write: true, common: { role: 'media.mute' } },
96
+ { code: 'SRC', id: 'source', name: { en: 'Input', de: 'Eingang' }, kind: 'text', write: true, common: { role: 'media.input' } },
97
+ { code: 'LST', id: 'sources', name: { en: 'Available inputs', de: 'Verfügbare Eingänge' }, kind: 'text', write: false, once: true, statesOf: 'source', common: TEXT },
98
+ { code: 'PLA', id: 'playing', name: { en: 'Playing', de: 'Wiedergabe läuft' }, kind: 'bool', write: false, common: { role: 'media.state' } },
99
+ { code: 'POP', id: 'playPause', name: { en: 'Play/pause', de: 'Wiedergabe/Pause' }, kind: 'button', write: true, common: { role: 'button' } },
100
+ { code: 'STP', id: 'stop', name: { en: 'Stop', de: 'Stopp' }, kind: 'button', write: true, common: { role: 'button.stop' } },
101
+ { code: 'NXT', id: 'next', name: { en: 'Next track', de: 'Nächster Titel' }, kind: 'button', write: true, common: { role: 'button.next' } },
102
+ { code: 'PRE', id: 'previous', name: { en: 'Previous track', de: 'Vorheriger Titel' }, kind: 'button', write: true, common: { role: 'button.prev' } },
103
+
104
+ { code: 'BAS', id: 'sound.bass', name: { en: 'Bass', de: 'Bass' }, kind: 'int', write: true, common: TONE },
105
+ { code: 'MID', id: 'sound.mid', name: { en: 'Mid', de: 'Mitten' }, kind: 'int', write: true, common: TONE },
106
+ { code: 'TRE', id: 'sound.treble', name: { en: 'Treble', de: 'Höhen' }, kind: 'int', write: true, common: TONE },
107
+ { code: 'BAL', id: 'sound.balance', name: { en: 'Balance', de: 'Balance' }, kind: 'int', write: true, common: { role: 'level', min: -100, max: 100 } },
108
+ { code: 'VBS', id: 'sound.virtualBass', name: { en: 'Virtual bass', de: 'Virtueller Bass' }, kind: 'bool', write: true, common: SWITCH },
109
+ { code: 'EQE', id: 'sound.eqEnabled', name: { en: 'Equalizer on', de: 'Equalizer an' }, kind: 'bool', write: true, common: SWITCH },
110
+ { code: 'EQS', id: 'sound.eqPreset', name: { en: 'Equalizer preset', de: 'Equalizer-Voreinstellung' }, kind: 'int', write: true, common: { role: 'level' } },
111
+ { code: 'PEQ', id: 'sound.eqPresets', name: { en: 'Available equalizer presets', de: 'Verfügbare Equalizer-Voreinstellungen' }, kind: 'text', write: false, once: true, statesOf: 'sound.eqPreset', common: TEXT },
112
+ { code: 'CFE', id: 'sound.crossover', name: { en: 'Crossover on', de: 'Frequenzweiche an' }, kind: 'bool', write: true, common: SWITCH },
113
+ { code: 'CFF', id: 'sound.crossoverFrequency', name: { en: 'Crossover frequency', de: 'Übergangsfrequenz' }, kind: 'int', write: true, common: { role: 'level', min: 50, max: 300, unit: 'Hz' } },
114
+
115
+ { code: 'LED', id: 'settings.led', name: { en: 'LED', de: 'LED' }, kind: 'bool', write: true, common: SWITCH },
116
+ { code: 'BEP', id: 'settings.beep', name: { en: 'Confirmation tone', de: 'Bestätigungston' }, kind: 'bool', write: true, common: SWITCH },
117
+ { code: 'NAM', id: 'settings.name', name: { en: 'Device name', de: 'Gerätename' }, kind: 'hex', write: true, common: { role: 'info.name' } },
118
+ { code: 'DLY', id: 'settings.muteDelay', name: { en: 'Mute after silence', de: 'Stumm nach Stille' }, kind: 'int', write: true, common: { role: 'level', min: 0, max: 32767, unit: 's' } },
119
+ { code: 'POM', id: 'settings.powerOnSource', name: { en: 'Input after power-on', de: 'Eingang nach dem Einschalten' }, kind: 'text', write: true, common: TEXT },
120
+ { code: 'ASW', id: 'settings.autoSwitch', name: { en: 'Switch back to previous input', de: 'Zurück zum vorherigen Eingang' }, kind: 'bool', write: true, common: SWITCH },
121
+ { code: 'VST', id: 'settings.volumeStep', name: { en: 'Volume step', de: 'Lautstärke-Schrittweite' }, kind: 'int', write: true, common: { role: 'level', min: 0, max: 10 } },
122
+ { code: 'VOF', id: 'settings.fixedVolume', name: { en: 'Fixed output level', de: 'Fester Ausgangspegel' }, kind: 'int', write: true, common: { role: 'level.volume', min: 0, max: 100 } },
123
+ { code: 'SOP', id: 'settings.standbyOnPower', name: { en: 'Start in standby', de: 'Im Standby starten' }, kind: 'bool', write: true, common: SWITCH },
124
+
125
+ { code: 'IPA', id: 'info.ip', name: { en: 'IP address', de: 'IP-Adresse' }, kind: 'text', write: false, common: { role: 'info.ip' } },
126
+ { code: 'ETH', id: 'info.ethernet', name: { en: 'Ethernet connected', de: 'LAN verbunden' }, kind: 'bool', write: false, common: { role: 'indicator.connected' } },
127
+ { code: 'WIF', id: 'info.wifi', name: { en: 'Wi-Fi connected', de: 'WLAN verbunden' }, kind: 'bool', write: false, common: { role: 'indicator.connected' } },
128
+ { code: 'CHN', id: 'info.multiroomChannel', name: { en: 'Multiroom channel', de: 'Multiroom-Kanal' }, kind: 'text', write: false, common: TEXT },
129
+ { code: 'MRM', id: 'info.multiroomMode', name: { en: 'Multiroom mode', de: 'Multiroom-Modus' }, kind: 'text', write: false, common: TEXT },
130
+ { code: 'VER', id: 'info.mcuVersion', name: { en: 'Amplifier chip firmware', de: 'Firmware Verstärker-Chip' }, kind: 'text', write: false, once: true, common: { role: 'info.firmware' } },
131
131
 
132
132
  // ⚠️ Nothing over the network wakes the LA50 up again (no web UI, no command) — only the IR remote.
133
- { code: 'SYS', id: 'standby', kind: 'button', value: 'STANDBY', write: true, common: { role: 'button' } },
133
+ { code: 'SYS', id: 'standby', name: { en: 'Standby', de: 'Standby' }, kind: 'button', value: 'STANDBY', write: true, common: { role: 'button' } },
134
134
  ];
135
135
 
136
136
  // States that do not come from a UART command: the connection, and what the device
137
137
  // announces via mDNS.
138
138
  // prettier-ignore
139
139
  const EXTRA = [
140
- { id: 'info.connected', kind: 'bool', common: { role: 'indicator.reachable' } },
141
- { id: 'info.model', kind: 'text', common: TEXT },
142
- { id: 'info.serial', kind: 'text', common: TEXT },
143
- { id: 'info.firmware', kind: 'text', common: { role: 'info.firmware' } },
140
+ { id: 'info.connected', name: { en: 'Connected', de: 'Verbunden' }, kind: 'bool', common: { role: 'indicator.reachable' } },
141
+ { id: 'info.model', name: { en: 'Model', de: 'Modell' }, kind: 'text', common: TEXT },
142
+ { id: 'info.serial', name: { en: 'Serial number', de: 'Seriennummer' }, kind: 'text', common: TEXT },
143
+ { id: 'info.firmware', name: { en: 'Firmware', de: 'Firmware' }, kind: 'text', common: { role: 'info.firmware' } },
144
144
  ];
145
145
 
146
146
  /** Every state below a device; anything else there is a leftover of an older version. */
147
147
  const STATES = [...FIELDS, ...EXTRA];
148
148
 
149
- const CHANNEL_NAMES = { sound: 'Sound', settings: 'Settings', info: 'Information' };
149
+ const CHANNEL_NAMES = {
150
+ sound: { en: 'Sound', de: 'Klang' },
151
+ settings: { en: 'Settings', de: 'Einstellungen' },
152
+ info: { en: 'Information', de: 'Information' },
153
+ };
150
154
  /** Channels below the device: the first segment of every dotted state id. */
151
155
  const CHANNELS = [...new Set(STATES.filter(f => f.id.includes('.')).map(f => f.id.split('.')[0]))];
152
156
 
package/lib/i18n.js ADDED
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ // The languages beyond English and German, keyed by the English text. English
4
+ // and German stay next to the code that uses them.
5
+ const MORE = require('./i18n.json');
6
+
7
+ /**
8
+ * @param {{ en: string, de: string }} text text in English and German
9
+ * @returns {ioBroker.Translated} the text in all languages of ioBroker
10
+ */
11
+ function translate(text) {
12
+ return { ...text, ...MORE[text.en] };
13
+ }
14
+
15
+ module.exports = { translate, MORE };
package/lib/i18n.json ADDED
@@ -0,0 +1,508 @@
1
+ {
2
+ "Amplifier chip": {
3
+ "ru": "Чип усилителя",
4
+ "pt": "Chip do amplificador",
5
+ "nl": "Versterkerchip",
6
+ "fr": "Puce d'amplification",
7
+ "it": "Chip amplificatore",
8
+ "es": "Chip amplificador",
9
+ "pl": "Układ wzmacniacza",
10
+ "uk": "Мікросхема підсилювача",
11
+ "zh-cn": "功放芯片"
12
+ },
13
+ "Amplifier chip firmware": {
14
+ "ru": "Прошивка чипа усилителя",
15
+ "pt": "Firmware do chip do amplificador",
16
+ "nl": "Firmware van de versterkerchip",
17
+ "fr": "Firmware de la puce d'amplification",
18
+ "it": "Firmware del chip amplificatore",
19
+ "es": "Firmware del chip amplificador",
20
+ "pl": "Oprogramowanie układu wzmacniacza",
21
+ "uk": "Прошивка мікросхеми підсилювача",
22
+ "zh-cn": "功放芯片固件"
23
+ },
24
+ "Available equalizer presets": {
25
+ "ru": "Доступные предустановки эквалайзера",
26
+ "pt": "Predefinições de equalizador disponíveis",
27
+ "nl": "Beschikbare equalizer-voorinstellingen",
28
+ "fr": "Préréglages d'égaliseur disponibles",
29
+ "it": "Preimpostazioni equalizzatore disponibili",
30
+ "es": "Preajustes de ecualizador disponibles",
31
+ "pl": "Dostępne ustawienia korektora",
32
+ "uk": "Доступні передналаштування еквалайзера",
33
+ "zh-cn": "可用的均衡器预设"
34
+ },
35
+ "Available inputs": {
36
+ "ru": "Доступные входы",
37
+ "pt": "Entradas disponíveis",
38
+ "nl": "Beschikbare ingangen",
39
+ "fr": "Entrées disponibles",
40
+ "it": "Ingressi disponibili",
41
+ "es": "Entradas disponibles",
42
+ "pl": "Dostępne wejścia",
43
+ "uk": "Доступні входи",
44
+ "zh-cn": "可用输入源"
45
+ },
46
+ "Balance": {
47
+ "ru": "Баланс",
48
+ "pt": "Balanço",
49
+ "nl": "Balans",
50
+ "fr": "Balance",
51
+ "it": "Bilanciamento",
52
+ "es": "Balance",
53
+ "pl": "Balans",
54
+ "uk": "Баланс",
55
+ "zh-cn": "声道平衡"
56
+ },
57
+ "Bass": {
58
+ "ru": "Низкие частоты",
59
+ "pt": "Graves",
60
+ "nl": "Lage tonen",
61
+ "fr": "Graves",
62
+ "it": "Bassi",
63
+ "es": "Graves",
64
+ "pl": "Tony niskie",
65
+ "uk": "Низькі частоти",
66
+ "zh-cn": "低音"
67
+ },
68
+ "Confirmation tone": {
69
+ "ru": "Сигнал подтверждения",
70
+ "pt": "Sinal de confirmação",
71
+ "nl": "Bevestigingstoon",
72
+ "fr": "Bip de confirmation",
73
+ "it": "Segnale acustico di conferma",
74
+ "es": "Tono de confirmación",
75
+ "pl": "Dźwięk potwierdzenia",
76
+ "uk": "Сигнал підтвердження",
77
+ "zh-cn": "提示音"
78
+ },
79
+ "Connected": {
80
+ "ru": "Подключено",
81
+ "pt": "Conectado",
82
+ "nl": "Verbonden",
83
+ "fr": "Connecté",
84
+ "it": "Connesso",
85
+ "es": "Conectado",
86
+ "pl": "Połączono",
87
+ "uk": "Підключено",
88
+ "zh-cn": "已连接"
89
+ },
90
+ "Crossover frequency": {
91
+ "ru": "Частота разделения",
92
+ "pt": "Frequência de corte",
93
+ "nl": "Scheidingsfrequentie",
94
+ "fr": "Fréquence de coupure",
95
+ "it": "Frequenza di crossover",
96
+ "es": "Frecuencia de corte",
97
+ "pl": "Częstotliwość podziału",
98
+ "uk": "Частота розділення",
99
+ "zh-cn": "分频点"
100
+ },
101
+ "Crossover on": {
102
+ "ru": "Кроссовер включён",
103
+ "pt": "Crossover ligado",
104
+ "nl": "Scheidingsfilter aan",
105
+ "fr": "Filtre séparateur activé",
106
+ "it": "Crossover attivo",
107
+ "es": "Crossover activado",
108
+ "pl": "Zwrotnica włączona",
109
+ "uk": "Кросовер увімкнено",
110
+ "zh-cn": "分频器开启"
111
+ },
112
+ "Device name": {
113
+ "ru": "Имя устройства",
114
+ "pt": "Nome do dispositivo",
115
+ "nl": "Apparaatnaam",
116
+ "fr": "Nom de l'appareil",
117
+ "it": "Nome del dispositivo",
118
+ "es": "Nombre del dispositivo",
119
+ "pl": "Nazwa urządzenia",
120
+ "uk": "Назва пристрою",
121
+ "zh-cn": "设备名称"
122
+ },
123
+ "Equalizer on": {
124
+ "ru": "Эквалайзер включён",
125
+ "pt": "Equalizador ligado",
126
+ "nl": "Equalizer aan",
127
+ "fr": "Égaliseur activé",
128
+ "it": "Equalizzatore attivo",
129
+ "es": "Ecualizador activado",
130
+ "pl": "Korektor włączony",
131
+ "uk": "Еквалайзер увімкнено",
132
+ "zh-cn": "均衡器开启"
133
+ },
134
+ "Equalizer preset": {
135
+ "ru": "Предустановка эквалайзера",
136
+ "pt": "Predefinição do equalizador",
137
+ "nl": "Equalizer-voorinstelling",
138
+ "fr": "Préréglage de l'égaliseur",
139
+ "it": "Preimpostazione equalizzatore",
140
+ "es": "Preajuste del ecualizador",
141
+ "pl": "Ustawienie korektora",
142
+ "uk": "Передналаштування еквалайзера",
143
+ "zh-cn": "均衡器预设"
144
+ },
145
+ "Ethernet connected": {
146
+ "ru": "Ethernet подключён",
147
+ "pt": "Ethernet conectada",
148
+ "nl": "Ethernet verbonden",
149
+ "fr": "Ethernet connecté",
150
+ "it": "Ethernet connessa",
151
+ "es": "Ethernet conectada",
152
+ "pl": "Ethernet połączony",
153
+ "uk": "Ethernet підключено",
154
+ "zh-cn": "以太网已连接"
155
+ },
156
+ "Firmware": {
157
+ "ru": "Прошивка",
158
+ "pt": "Firmware",
159
+ "nl": "Firmware",
160
+ "fr": "Firmware",
161
+ "it": "Firmware",
162
+ "es": "Firmware",
163
+ "pl": "Oprogramowanie",
164
+ "uk": "Прошивка",
165
+ "zh-cn": "固件"
166
+ },
167
+ "Fixed output level": {
168
+ "ru": "Фиксированный выходной уровень",
169
+ "pt": "Nível de saída fixo",
170
+ "nl": "Vast uitgangsniveau",
171
+ "fr": "Niveau de sortie fixe",
172
+ "it": "Livello di uscita fisso",
173
+ "es": "Nivel de salida fijo",
174
+ "pl": "Stały poziom wyjściowy",
175
+ "uk": "Фіксований вихідний рівень",
176
+ "zh-cn": "固定输出电平"
177
+ },
178
+ "IP address": {
179
+ "ru": "IP-адрес",
180
+ "pt": "Endereço IP",
181
+ "nl": "IP-adres",
182
+ "fr": "Adresse IP",
183
+ "it": "Indirizzo IP",
184
+ "es": "Dirección IP",
185
+ "pl": "Adres IP",
186
+ "uk": "IP-адреса",
187
+ "zh-cn": "IP 地址"
188
+ },
189
+ "Information": {
190
+ "ru": "Информация",
191
+ "pt": "Informação",
192
+ "nl": "Informatie",
193
+ "fr": "Informations",
194
+ "it": "Informazioni",
195
+ "es": "Información",
196
+ "pl": "Informacje",
197
+ "uk": "Інформація",
198
+ "zh-cn": "信息"
199
+ },
200
+ "Input": {
201
+ "ru": "Вход",
202
+ "pt": "Entrada",
203
+ "nl": "Ingang",
204
+ "fr": "Entrée",
205
+ "it": "Ingresso",
206
+ "es": "Entrada",
207
+ "pl": "Wejście",
208
+ "uk": "Вхід",
209
+ "zh-cn": "输入源"
210
+ },
211
+ "Input after power-on": {
212
+ "ru": "Вход после включения",
213
+ "pt": "Entrada após ligar",
214
+ "nl": "Ingang na inschakelen",
215
+ "fr": "Entrée à la mise sous tension",
216
+ "it": "Ingresso all'accensione",
217
+ "es": "Entrada al encender",
218
+ "pl": "Wejście po włączeniu",
219
+ "uk": "Вхід після увімкнення",
220
+ "zh-cn": "开机输入源"
221
+ },
222
+ "LED": {
223
+ "ru": "Светодиод",
224
+ "pt": "LED",
225
+ "nl": "Led",
226
+ "fr": "LED",
227
+ "it": "LED",
228
+ "es": "LED",
229
+ "pl": "Dioda LED",
230
+ "uk": "Світлодіод",
231
+ "zh-cn": "LED 指示灯"
232
+ },
233
+ "Maximum volume": {
234
+ "ru": "Максимальная громкость",
235
+ "pt": "Volume máximo",
236
+ "nl": "Maximaal volume",
237
+ "fr": "Volume maximal",
238
+ "it": "Volume massimo",
239
+ "es": "Volumen máximo",
240
+ "pl": "Maksymalna głośność",
241
+ "uk": "Максимальна гучність",
242
+ "zh-cn": "最大音量"
243
+ },
244
+ "Mid": {
245
+ "ru": "Средние частоты",
246
+ "pt": "Médios",
247
+ "nl": "Middentonen",
248
+ "fr": "Médiums",
249
+ "it": "Medi",
250
+ "es": "Medios",
251
+ "pl": "Tony średnie",
252
+ "uk": "Середні частоти",
253
+ "zh-cn": "中音"
254
+ },
255
+ "Model": {
256
+ "ru": "Модель",
257
+ "pt": "Modelo",
258
+ "nl": "Model",
259
+ "fr": "Modèle",
260
+ "it": "Modello",
261
+ "es": "Modelo",
262
+ "pl": "Model",
263
+ "uk": "Модель",
264
+ "zh-cn": "型号"
265
+ },
266
+ "Multiroom channel": {
267
+ "ru": "Канал мультирум",
268
+ "pt": "Canal multiroom",
269
+ "nl": "Multiroom-kanaal",
270
+ "fr": "Canal multiroom",
271
+ "it": "Canale multiroom",
272
+ "es": "Canal multiroom",
273
+ "pl": "Kanał multiroom",
274
+ "uk": "Канал мультирум",
275
+ "zh-cn": "多房间声道"
276
+ },
277
+ "Multiroom mode": {
278
+ "ru": "Режим мультирум",
279
+ "pt": "Modo multiroom",
280
+ "nl": "Multiroom-modus",
281
+ "fr": "Mode multiroom",
282
+ "it": "Modalità multiroom",
283
+ "es": "Modo multiroom",
284
+ "pl": "Tryb multiroom",
285
+ "uk": "Режим мультирум",
286
+ "zh-cn": "多房间模式"
287
+ },
288
+ "Mute": {
289
+ "ru": "Без звука",
290
+ "pt": "Sem som",
291
+ "nl": "Dempen",
292
+ "fr": "Sourdine",
293
+ "it": "Muto",
294
+ "es": "Silencio",
295
+ "pl": "Wyciszenie",
296
+ "uk": "Без звуку",
297
+ "zh-cn": "静音"
298
+ },
299
+ "Mute after silence": {
300
+ "ru": "Отключение звука после тишины",
301
+ "pt": "Silenciar após silêncio",
302
+ "nl": "Dempen na stilte",
303
+ "fr": "Sourdine après silence",
304
+ "it": "Muto dopo silenzio",
305
+ "es": "Silenciar tras silencio",
306
+ "pl": "Wyciszenie po ciszy",
307
+ "uk": "Вимкнення звуку після тиші",
308
+ "zh-cn": "无信号后静音"
309
+ },
310
+ "Next track": {
311
+ "ru": "Следующий трек",
312
+ "pt": "Próxima faixa",
313
+ "nl": "Volgende track",
314
+ "fr": "Piste suivante",
315
+ "it": "Brano successivo",
316
+ "es": "Pista siguiente",
317
+ "pl": "Następny utwór",
318
+ "uk": "Наступний трек",
319
+ "zh-cn": "下一曲"
320
+ },
321
+ "Open the web interface": {
322
+ "ru": "Открыть веб-интерфейс",
323
+ "pt": "Abrir a interface web",
324
+ "nl": "Webinterface openen",
325
+ "fr": "Ouvrir l'interface web",
326
+ "it": "Apri l'interfaccia web",
327
+ "es": "Abrir la interfaz web",
328
+ "pl": "Otwórz interfejs WWW",
329
+ "uk": "Відкрити веб-інтерфейс",
330
+ "zh-cn": "打开网页界面"
331
+ },
332
+ "Play/pause": {
333
+ "ru": "Воспроизведение/пауза",
334
+ "pt": "Reproduzir/pausar",
335
+ "nl": "Afspelen/pauzeren",
336
+ "fr": "Lecture/pause",
337
+ "it": "Riproduci/pausa",
338
+ "es": "Reproducir/pausa",
339
+ "pl": "Odtwarzaj/pauza",
340
+ "uk": "Відтворення/пауза",
341
+ "zh-cn": "播放/暂停"
342
+ },
343
+ "Playing": {
344
+ "ru": "Идёт воспроизведение",
345
+ "pt": "A reproduzir",
346
+ "nl": "Speelt af",
347
+ "fr": "Lecture en cours",
348
+ "it": "In riproduzione",
349
+ "es": "Reproduciendo",
350
+ "pl": "Odtwarzanie",
351
+ "uk": "Відтворюється",
352
+ "zh-cn": "正在播放"
353
+ },
354
+ "Previous track": {
355
+ "ru": "Предыдущий трек",
356
+ "pt": "Faixa anterior",
357
+ "nl": "Vorige track",
358
+ "fr": "Piste précédente",
359
+ "it": "Brano precedente",
360
+ "es": "Pista anterior",
361
+ "pl": "Poprzedni utwór",
362
+ "uk": "Попередній трек",
363
+ "zh-cn": "上一曲"
364
+ },
365
+ "Read all values now": {
366
+ "ru": "Прочитать все значения сейчас",
367
+ "pt": "Ler todos os valores agora",
368
+ "nl": "Alle waarden nu lezen",
369
+ "fr": "Lire toutes les valeurs maintenant",
370
+ "it": "Leggi ora tutti i valori",
371
+ "es": "Leer todos los valores ahora",
372
+ "pl": "Odczytaj teraz wszystkie wartości",
373
+ "uk": "Прочитати всі значення зараз",
374
+ "zh-cn": "立即读取所有数值"
375
+ },
376
+ "Serial number": {
377
+ "ru": "Серийный номер",
378
+ "pt": "Número de série",
379
+ "nl": "Serienummer",
380
+ "fr": "Numéro de série",
381
+ "it": "Numero di serie",
382
+ "es": "Número de serie",
383
+ "pl": "Numer seryjny",
384
+ "uk": "Серійний номер",
385
+ "zh-cn": "序列号"
386
+ },
387
+ "Settings": {
388
+ "ru": "Настройки",
389
+ "pt": "Configurações",
390
+ "nl": "Instellingen",
391
+ "fr": "Paramètres",
392
+ "it": "Impostazioni",
393
+ "es": "Ajustes",
394
+ "pl": "Ustawienia",
395
+ "uk": "Налаштування",
396
+ "zh-cn": "设置"
397
+ },
398
+ "Sound": {
399
+ "ru": "Звук",
400
+ "pt": "Som",
401
+ "nl": "Geluid",
402
+ "fr": "Son",
403
+ "it": "Suono",
404
+ "es": "Sonido",
405
+ "pl": "Dźwięk",
406
+ "uk": "Звук",
407
+ "zh-cn": "音效"
408
+ },
409
+ "Standby": {
410
+ "ru": "Режим ожидания",
411
+ "pt": "Espera",
412
+ "nl": "Stand-by",
413
+ "fr": "Veille",
414
+ "it": "Standby",
415
+ "es": "Reposo",
416
+ "pl": "Czuwanie",
417
+ "uk": "Режим очікування",
418
+ "zh-cn": "待机"
419
+ },
420
+ "Start in standby": {
421
+ "ru": "Запуск в режиме ожидания",
422
+ "pt": "Iniciar em espera",
423
+ "nl": "In stand-by starten",
424
+ "fr": "Démarrer en veille",
425
+ "it": "Avvio in standby",
426
+ "es": "Iniciar en reposo",
427
+ "pl": "Uruchom w trybie czuwania",
428
+ "uk": "Запуск у режимі очікування",
429
+ "zh-cn": "通电后待机"
430
+ },
431
+ "Stop": {
432
+ "ru": "Стоп",
433
+ "pt": "Parar",
434
+ "nl": "Stoppen",
435
+ "fr": "Arrêt",
436
+ "it": "Stop",
437
+ "es": "Detener",
438
+ "pl": "Zatrzymaj",
439
+ "uk": "Стоп",
440
+ "zh-cn": "停止"
441
+ },
442
+ "Switch back to previous input": {
443
+ "ru": "Возврат к предыдущему входу",
444
+ "pt": "Voltar à entrada anterior",
445
+ "nl": "Terug naar vorige ingang",
446
+ "fr": "Revenir à l'entrée précédente",
447
+ "it": "Torna all'ingresso precedente",
448
+ "es": "Volver a la entrada anterior",
449
+ "pl": "Powrót do poprzedniego wejścia",
450
+ "uk": "Повернення до попереднього входу",
451
+ "zh-cn": "切回上一个输入源"
452
+ },
453
+ "Treble": {
454
+ "ru": "Высокие частоты",
455
+ "pt": "Agudos",
456
+ "nl": "Hoge tonen",
457
+ "fr": "Aigus",
458
+ "it": "Alti",
459
+ "es": "Agudos",
460
+ "pl": "Tony wysokie",
461
+ "uk": "Високі частоти",
462
+ "zh-cn": "高音"
463
+ },
464
+ "Virtual bass": {
465
+ "ru": "Виртуальный бас",
466
+ "pt": "Graves virtuais",
467
+ "nl": "Virtuele bas",
468
+ "fr": "Basses virtuelles",
469
+ "it": "Bassi virtuali",
470
+ "es": "Graves virtuales",
471
+ "pl": "Wirtualny bas",
472
+ "uk": "Віртуальний бас",
473
+ "zh-cn": "虚拟低音"
474
+ },
475
+ "Volume": {
476
+ "ru": "Громкость",
477
+ "pt": "Volume",
478
+ "nl": "Volume",
479
+ "fr": "Volume",
480
+ "it": "Volume",
481
+ "es": "Volumen",
482
+ "pl": "Głośność",
483
+ "uk": "Гучність",
484
+ "zh-cn": "音量"
485
+ },
486
+ "Volume step": {
487
+ "ru": "Шаг громкости",
488
+ "pt": "Passo do volume",
489
+ "nl": "Volumestap",
490
+ "fr": "Pas du volume",
491
+ "it": "Passo del volume",
492
+ "es": "Paso de volumen",
493
+ "pl": "Krok głośności",
494
+ "uk": "Крок гучності",
495
+ "zh-cn": "音量步进"
496
+ },
497
+ "Wi-Fi connected": {
498
+ "ru": "Wi-Fi подключён",
499
+ "pt": "Wi-Fi conectado",
500
+ "nl": "Wifi verbonden",
501
+ "fr": "Wi-Fi connecté",
502
+ "it": "Wi-Fi connesso",
503
+ "es": "Wi-Fi conectado",
504
+ "pl": "Wi-Fi połączone",
505
+ "uk": "Wi-Fi підключено",
506
+ "zh-cn": "Wi-Fi 已连接"
507
+ }
508
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.arylic",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Control Arylic amplifiers (LA50) over the network: volume limit, tone, input, standby",
5
5
  "author": {
6
6
  "name": "Timo Schneider",