iobroker.miele-local 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +161 -0
- package/admin/i18n/de/translations.json +44 -0
- package/admin/i18n/en/translations.json +44 -0
- package/admin/i18n/es/translations.json +44 -0
- package/admin/i18n/fr/translations.json +44 -0
- package/admin/i18n/it/translations.json +44 -0
- package/admin/i18n/nl/translations.json +44 -0
- package/admin/i18n/pl/translations.json +44 -0
- package/admin/i18n/pt/translations.json +44 -0
- package/admin/i18n/ru/translations.json +44 -0
- package/admin/i18n/uk/translations.json +44 -0
- package/admin/i18n/zh-cn/translations.json +44 -0
- package/admin/jsonConfig.json +519 -0
- package/admin/miele-local.png +0 -0
- package/io-package.json +181 -0
- package/lib/api.js +106 -0
- package/lib/cloud.js +146 -0
- package/lib/crypto.js +161 -0
- package/lib/discovery.js +102 -0
- package/lib/dop2.js +104 -0
- package/lib/enroll.js +67 -0
- package/lib/enums.js +836 -0
- package/lib/enums_de.js +237 -0
- package/lib/objects.js +285 -0
- package/lib/push.js +223 -0
- package/main.js +576 -0
- package/package.json +52 -0
package/lib/enums_de.js
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Deutsche Übersetzungen der Miele-Enums (an mielecloudservice-Begriffe angelehnt:
|
|
4
|
+
// in_use→"In Betrieb", off→"Aus", main_wash→"Waschen"). Fallback = englischer Schlüssel.
|
|
5
|
+
|
|
6
|
+
const StateStatusDe = {
|
|
7
|
+
0: 'Reserviert', 1: 'Aus', 2: 'Ein', 3: 'Programmiert', 4: 'Warten auf Start',
|
|
8
|
+
5: 'In Betrieb', 6: 'Pause', 7: 'Programm beendet', 8: 'Fehler', 9: 'Programm unterbrochen',
|
|
9
|
+
10: 'Bereit', 11: 'Spülstopp', 12: 'Service', 13: 'SuperFrost', 14: 'SuperKühlen',
|
|
10
|
+
15: 'Aufheizen', 146: 'SuperKühlen/SuperFrost', 147: 'Selbstreinigung', 255: 'Nicht verbunden',
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const StateProgramTypeDe = {
|
|
14
|
+
0: 'Normalbetrieb', 1: 'Eigenes Programm', 2: 'Automatikprogramm', 3: 'Automatikprogramm', 4: 'Wartungsprogramm',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const StateDryingStepDe = {
|
|
18
|
+
0: 'Extra trocken', 1: 'Normal plus', 2: 'Normal', 3: 'Leicht trocken', 4: 'Handtuchtrocken',
|
|
19
|
+
5: 'Bügeltrocken', 6: 'Schranktrocken', 7: 'Schranktrocken plus',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const ProgramPhaseWashingMachineDe = {
|
|
23
|
+
0: '', 256: '', 257: 'Vorwäsche', 258: 'Einweichen', 259: 'Vorwäsche', 260: 'Waschen',
|
|
24
|
+
261: 'Spülen', 262: 'Spülstopp', 263: 'Reinigung', 264: 'Abkühlen', 265: 'Abpumpen',
|
|
25
|
+
266: 'Schleudern', 267: 'Knitterschutz', 268: 'Ende', 269: 'Belüften', 270: 'Stärkestopp',
|
|
26
|
+
271: 'Auffrischen/Befeuchten', 272: 'Dampfglätten', 279: 'Hygiene', 280: 'Trocknen',
|
|
27
|
+
285: 'Desinfizieren', 295: 'Dampfglätten', 11004: 'Waschen', 11005: 'Spülen', 11010: 'Schleudern',
|
|
28
|
+
11012: 'Ende', 11029: 'Knitterschutz', 11044: 'Automatikstart', 11047: 'FlexLoad aktiv', 65535: '',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const ProgramPhaseDishwasherDe = {
|
|
32
|
+
0: '', 1792: '', 1793: 'Regenerieren', 1794: 'Vorspülen', 1795: 'Reinigen', 1796: 'Spülen',
|
|
33
|
+
1797: 'Zwischenspülen', 1798: 'Klarspülen', 1799: 'Trocknen', 1800: 'Ende', 1801: 'Vorspülen', 65535: '',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const ProgramPhaseOvenDe = {
|
|
37
|
+
0: '', 3073: 'Aufheizen', 3074: 'In Betrieb', 3078: 'Beendet', 3080: 'Anbraten',
|
|
38
|
+
3081: 'Braten', 3084: 'Energiesparen', 3099: 'Vorheizen', 65535: '',
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Programmnamen (Schlüssel = englischer Enum-Wert aus enums.js → Deutsch).
|
|
42
|
+
const ProgramNameDe = {
|
|
43
|
+
// gemeinsame
|
|
44
|
+
no_program: '',
|
|
45
|
+
// Waschmaschine
|
|
46
|
+
cottons: 'Baumwolle', minimum_iron: 'Pflegeleicht', easy_care: 'Pflegeleicht',
|
|
47
|
+
delicates: 'Feinwäsche', woollens: 'Wolle', silks: 'Seide', starch: 'Stärken',
|
|
48
|
+
rinse: 'Spülen', drain_spin: 'Abpumpen/Schleudern', curtains: 'Gardinen',
|
|
49
|
+
shirts: 'Oberhemden', denim: 'Jeans', proofing: 'Imprägnieren', sportswear: 'Sportbekleidung',
|
|
50
|
+
automatic_plus: 'Automatic Plus', outerwear: 'Outdoor', pillows: 'Kopfkissen',
|
|
51
|
+
dark_garments: 'Dunkles/Jeans', dark_jeans: 'Dunkles/Jeans', separate_rinse_starch: 'Separates Spülen/Stärken',
|
|
52
|
+
first_wash: 'Erstwäsche', cottons_hygiene: 'Baumwolle Hygiene', cottons_eco: 'Baumwolle Eco',
|
|
53
|
+
trainers: 'Sportschuhe', trainers_refresh: 'Sportschuhe auffrischen', clean_machine: 'Maschine reinigen',
|
|
54
|
+
down_duvets: 'Daunen', down_filled_items: 'Daunen', express_20: 'Express 20',
|
|
55
|
+
quick_power_wash: 'QuickPowerWash', eco_40_60: 'Eco 40-60', bed_linen: 'Bettwäsche',
|
|
56
|
+
outdoor_garments: 'Outdoor', pre_ironing: 'Vorbügeln', cottonrepair: 'CottonRepair',
|
|
57
|
+
smartmatic: 'SmartMatic', stuffed_toys: 'Kuscheltiere', game_pieces: 'Spielsachen', powerfresh: 'PowerFresh',
|
|
58
|
+
// Spülmaschine
|
|
59
|
+
intensive: 'Intensiv', maintenance: 'Maschinenpflege', eco: 'Eco', automatic: 'Automatic',
|
|
60
|
+
solar_save: 'Solarspar', gentle: 'Schonen', extra_quiet: 'Extra leise', hygiene: 'Hygiene',
|
|
61
|
+
pasta_paela: 'Pasta/Paella', tall_items: 'Große Teile', glasses_warm: 'Gläser warm',
|
|
62
|
+
normal: 'Normal', comfort_wash: 'ComfortWash', comfort_wash_plus: 'ComfortWash Plus',
|
|
63
|
+
power_wash: 'PowerWash', rinse_salt: 'Spülen/Salz',
|
|
64
|
+
// Backofen – Betriebsarten
|
|
65
|
+
conventional_heat: 'Ober-/Unterhitze', top_heat: 'Oberhitze', bottom_heat: 'Unterhitze',
|
|
66
|
+
fan_plus: 'Umluft', eco_fan_heat: 'Eco Umluft', fan_grill: 'Umluftgrill', grill: 'Grill',
|
|
67
|
+
full_grill: 'Großflächengrill', economy_grill: 'Spargrill', intensive_bake: 'Intensivbacken',
|
|
68
|
+
auto_roast: 'Automatikbraten', low_temperature_cooking: 'Niedertemperaturgaren',
|
|
69
|
+
moisture_plus_conventional_heat: 'Feuchtigkeit plus – Ober-/Unterhitze',
|
|
70
|
+
moisture_plus_fan_plus: 'Feuchtigkeit plus – Umluft',
|
|
71
|
+
moisture_plus_auto_roast: 'Feuchtigkeit plus – Automatikbraten',
|
|
72
|
+
moisture_plus_intensive_bake: 'Feuchtigkeit plus – Intensivbacken',
|
|
73
|
+
microwave: 'Mikrowelle', microwave_fan_plus: 'Mikrowelle – Umluft',
|
|
74
|
+
microwave_grill: 'Mikrowelle – Grill', microwave_fan_grill: 'Mikrowelle – Umluftgrill',
|
|
75
|
+
microwave_auto_roast: 'Mikrowelle – Automatikbraten', quick_microwave: 'Schnell-Mikrowelle',
|
|
76
|
+
steam_cooking: 'Dampfgaren', steam_bake: 'Dampfbacken', defrost: 'Auftauen',
|
|
77
|
+
defrost_meat: 'Fleisch auftauen', defrost_vegetables: 'Gemüse auftauen',
|
|
78
|
+
keeping_warm: 'Warmhalten', heat_crockery: 'Geschirr wärmen',
|
|
79
|
+
heating_bakes_gratins: 'Aufläufe/Gratins', heating_vegetables: 'Gemüse erwärmen',
|
|
80
|
+
evaporate_water: 'Wasser verdampfen', descale: 'Entkalken', pyrolytic: 'Pyrolyse',
|
|
81
|
+
drying: 'Trocknen', prove_dough: 'Teig gehen lassen', prove_15_min: 'Teig gehen (15 min)',
|
|
82
|
+
prove_30_min: 'Teig gehen (30 min)', prove_45_min: 'Teig gehen (45 min)', popcorn: 'Popcorn',
|
|
83
|
+
shabbat_program: 'Schabbat-Programm', yom_tov: 'Jom Tov',
|
|
84
|
+
// Backofen – eigene Programme
|
|
85
|
+
custom_program_1: 'Eigenes Programm 1', custom_program_2: 'Eigenes Programm 2',
|
|
86
|
+
custom_program_3: 'Eigenes Programm 3', custom_program_4: 'Eigenes Programm 4',
|
|
87
|
+
custom_program_5: 'Eigenes Programm 5', custom_program_6: 'Eigenes Programm 6',
|
|
88
|
+
custom_program_7: 'Eigenes Programm 7', custom_program_8: 'Eigenes Programm 8',
|
|
89
|
+
custom_program_9: 'Eigenes Programm 9', custom_program_10: 'Eigenes Programm 10',
|
|
90
|
+
custom_program_11: 'Eigenes Programm 11', custom_program_12: 'Eigenes Programm 12',
|
|
91
|
+
custom_program_13: 'Eigenes Programm 13', custom_program_14: 'Eigenes Programm 14',
|
|
92
|
+
custom_program_15: 'Eigenes Programm 15', custom_program_16: 'Eigenes Programm 16',
|
|
93
|
+
custom_program_17: 'Eigenes Programm 17', custom_program_18: 'Eigenes Programm 18',
|
|
94
|
+
custom_program_19: 'Eigenes Programm 19', custom_program_20: 'Eigenes Programm 20',
|
|
95
|
+
// Backofen – Brot & Brötchen
|
|
96
|
+
white_bread_baking_tin: 'Weißbrot (Kastenform)', white_bread_on_tray: 'Weißbrot (Blech)',
|
|
97
|
+
white_rolls: 'Weiße Brötchen', multigrain_rolls: 'Mehrkornbrötchen', rye_rolls: 'Roggenbrötchen',
|
|
98
|
+
mixed_rye_bread: 'Roggenmischbrot', dark_mixed_grain_bread: 'Dunkles Mehrkornbrot',
|
|
99
|
+
spelt_bread: 'Dinkelbrot', walnut_bread: 'Walnussbrot', seeded_loaf: 'Saatenbrot',
|
|
100
|
+
flat_bread: 'Fladenbrot', baguettes: 'Baguette', plaited_loaf: 'Hefezopf',
|
|
101
|
+
plaited_swiss_loaf: 'Schweizer Zopf', swiss_farmhouse_bread: 'Schweizer Bauernbrot',
|
|
102
|
+
tiger_bread: 'Tigerbrot', ginger_loaf: 'Ingwerkuchen', stollen: 'Stollen',
|
|
103
|
+
// Backofen – Kuchen & Gebäck
|
|
104
|
+
apple_pie: 'Apfelkuchen', apple_sponge: 'Apfel-Biskuit', butter_cake: 'Butterkuchen',
|
|
105
|
+
marble_cake: 'Marmorkuchen', madeira_cake: 'Sandkuchen', belgian_sponge_cake: 'Belgischer Biskuit',
|
|
106
|
+
swiss_roll: 'Biskuitrolle', sponge_base: 'Biskuitboden', sachertorte: 'Sachertorte',
|
|
107
|
+
fruit_streusel_cake: 'Obst-Streuselkuchen', fruit_flan_puff_pastry: 'Obstkuchen (Blätterteig)',
|
|
108
|
+
fruit_flan_short_crust_pastry: 'Obstkuchen (Mürbeteig)',
|
|
109
|
+
savoury_flan_puff_pastry: 'Herzhafter Kuchen (Blätterteig)',
|
|
110
|
+
savoury_flan_short_crust_pastry: 'Herzhafter Kuchen (Mürbeteig)',
|
|
111
|
+
chocolate_hazlenut_cake_one_large: 'Schoko-Nuss-Kuchen (groß)',
|
|
112
|
+
chocolate_hazlenut_cake_several_small: 'Schoko-Nuss-Kuchen (klein)',
|
|
113
|
+
viennese_apple_strudel: 'Wiener Apfelstrudel', lemon_meringue_pie: 'Zitronen-Baiser-Torte',
|
|
114
|
+
quiche_lorraine: 'Quiche Lorraine', cheese_souffle: 'Käsesoufflé', choux_buns: 'Windbeutel',
|
|
115
|
+
springform_tin_15cm: 'Springform 15 cm', springform_tin_20cm: 'Springform 20 cm',
|
|
116
|
+
springform_tin_25cm: 'Springform 25 cm',
|
|
117
|
+
// Backofen – Kekse & Kleingebäck
|
|
118
|
+
vanilla_biscuits_1_tray: 'Vanillekipferl (1 Blech)', vanilla_biscuits_2_trays: 'Vanillekipferl (2 Bleche)',
|
|
119
|
+
almond_macaroons_1_tray: 'Mandelmakronen (1 Blech)', almond_macaroons_2_trays: 'Mandelmakronen (2 Bleche)',
|
|
120
|
+
biscuits_short_crust_pastry_1_tray: 'Mürbeteigplätzchen (1 Blech)',
|
|
121
|
+
biscuits_short_crust_pastry_2_trays: 'Mürbeteigplätzchen (2 Bleche)',
|
|
122
|
+
drop_cookies_1_tray: 'Spritzgebäck (1 Blech)', drop_cookies_2_trays: 'Spritzgebäck (2 Bleche)',
|
|
123
|
+
linzer_augen_1_tray: 'Linzer Augen (1 Blech)', linzer_augen_2_trays: 'Linzer Augen (2 Bleche)',
|
|
124
|
+
baiser_one_large: 'Baiser (groß)', baiser_several_small: 'Baiser (mehrere kleine)',
|
|
125
|
+
blueberry_muffins: 'Blaubeer-Muffins', walnut_muffins: 'Walnuss-Muffins',
|
|
126
|
+
// Backofen – Pizza & Flammkuchen
|
|
127
|
+
pizza_yeast_dough_baking_tray: 'Pizza Hefeteig (Blech)', pizza_yeast_dough_round_baking_tine: 'Pizza Hefeteig (rund)',
|
|
128
|
+
pizza_oil_cheese_dough_baking_tray: 'Pizza Öl-Käse-Teig (Blech)',
|
|
129
|
+
pizza_oil_cheese_dough_round_baking_tine: 'Pizza Öl-Käse-Teig (rund)', tart_flambe: 'Flammkuchen',
|
|
130
|
+
// Backofen – Fleisch (Rind/Kalb)
|
|
131
|
+
roast_beef_roast: 'Roastbeef braten', roast_beef_low_temperature_cooking: 'Roastbeef (Niedertemperatur)',
|
|
132
|
+
beef_fillet_roast: 'Rinderfilet braten', beef_fillet_low_temperature_cooking: 'Rinderfilet (Niedertemperatur)',
|
|
133
|
+
braised_beef: 'Schmorbraten (Rind)', beef_wellington: 'Beef Wellington', beef_hash: 'Rinderhackgericht',
|
|
134
|
+
meat_loaf: 'Hackbraten', braised_veal: 'Schmorbraten (Kalb)', veal_fillet_roast: 'Kalbsfilet braten',
|
|
135
|
+
veal_fillet_low_temperature_cooking: 'Kalbsfilet (Niedertemperatur)', saddle_of_veal_roast: 'Kalbsrücken braten',
|
|
136
|
+
saddle_of_veal_low_temperature_cooking: 'Kalbsrücken (Niedertemperatur)', veal_knuckle: 'Kalbshaxe',
|
|
137
|
+
// Backofen – Fleisch (Schwein/Lamm/Wild)
|
|
138
|
+
pork_fillet_roast: 'Schweinefilet braten', pork_fillet_low_temperature_cooking: 'Schweinefilet (Niedertemperatur)',
|
|
139
|
+
pork_belly: 'Schweinebauch', pork_with_crackling: 'Krustenbraten', ham_roast: 'Schinkenbraten',
|
|
140
|
+
pork_smoked_ribs_roast: 'Kasseler braten', pork_smoked_ribs_low_temperature_cooking: 'Kasseler (Niedertemperatur)',
|
|
141
|
+
leg_of_lamb: 'Lammkeule', saddle_of_lamb_roast: 'Lammrücken braten',
|
|
142
|
+
saddle_of_lamb_low_temperature_cooking: 'Lammrücken (Niedertemperatur)',
|
|
143
|
+
rack_of_lamb_with_vegetables: 'Lammkarree mit Gemüse', saddle_of_roebuck: 'Rehrücken',
|
|
144
|
+
saddle_of_venison: 'Hirschrücken', osso_buco: 'Osso Buco', rabbit: 'Kaninchen',
|
|
145
|
+
// Backofen – Geflügel
|
|
146
|
+
chicken_whole: 'Hähnchen (ganz)', chicken_thighs: 'Hähnchenschenkel', duck: 'Ente',
|
|
147
|
+
goose_stuffed: 'Gans (gefüllt)', goose_unstuffed: 'Gans (ungefüllt)', turkey_whole: 'Pute (ganz)',
|
|
148
|
+
turkey_drumsticks: 'Putenkeulen',
|
|
149
|
+
// Backofen – Fisch
|
|
150
|
+
salmon_fillet: 'Lachsfilet', salmon_trout: 'Lachsforelle', trout: 'Forelle', carp: 'Karpfen',
|
|
151
|
+
pikeperch_fillet_with_vegetables: 'Zanderfilet mit Gemüse',
|
|
152
|
+
// Backofen – Beilagen & Sonstiges
|
|
153
|
+
potato_gratin: 'Kartoffelgratin', potato_cheese_gratin: 'Kartoffel-Käse-Gratin',
|
|
154
|
+
yorkshire_pudding: 'Yorkshire Pudding',
|
|
155
|
+
// Trockner
|
|
156
|
+
basket_program: 'Korbprogramm', cool_air: 'Kaltluft', downs_duvets: 'Daunen', express: 'Express',
|
|
157
|
+
gentle_denim: 'Schonend Jeans', gentle_smoothing: 'Schonend Glätten', large_pillows: 'Große Kopfkissen',
|
|
158
|
+
pillows_sanitize: 'Kopfkissen Hygiene', quick_hygiene: 'Schnell Hygiene', quick_power_dry: 'QuickPowerDry',
|
|
159
|
+
silks_handcare: 'Seide Handpflege', smoothing: 'Glätten', standard_pillows: 'Kopfkissen',
|
|
160
|
+
steam_smoothing: 'Dampfglätten', warm_air: 'Warmluft', woollens_handcare: 'Wolle Handpflege',
|
|
161
|
+
// Kaffeevollautomat
|
|
162
|
+
appliance_rinse: 'Gerätespülung', automatic_maintenance: 'Automatische Pflege', barista_assistant: 'Barista-Assistent',
|
|
163
|
+
black_tea: 'Schwarzer Tee', brewing_unit_degrease: 'Brüheinheit entfetten', cafe_au_lait: 'Café au Lait',
|
|
164
|
+
caffe_latte: 'Caffè Latte', cappuccino: 'Cappuccino', cappuccino_italiano: 'Cappuccino Italiano',
|
|
165
|
+
check_appliance: 'Gerät prüfen', coffee: 'Kaffee', coffee_pot: 'Kaffeekanne', descaling: 'Entkalken',
|
|
166
|
+
espresso: 'Espresso', espresso_macchiato: 'Espresso Macchiato', flat_white: 'Flat White',
|
|
167
|
+
fruit_tea: 'Früchtetee', green_tea: 'Grüner Tee', herbal_tea: 'Kräutertee', hot_milk: 'Heiße Milch',
|
|
168
|
+
hot_water: 'Heißwasser', intermediate_rinsing: 'Zwischenspülung', japanese_tea: 'Japanischer Tee',
|
|
169
|
+
latte_macchiato: 'Latte Macchiato', long_coffee: 'Langer Kaffee', milk_foam: 'Milchschaum',
|
|
170
|
+
milk_pipework_clean: 'Milchleitung reinigen', milk_pipework_rinse: 'Milchleitung spülen',
|
|
171
|
+
ristretto: 'Ristretto', very_hot_water: 'Sehr heißes Wasser', white_tea: 'Weißer Tee',
|
|
172
|
+
// Wärmeschublade
|
|
173
|
+
keep_warm: 'Warmhalten', slow_roasting: 'Niedertemperaturgaren',
|
|
174
|
+
warm_cups_glasses: 'Tassen/Gläser wärmen', warm_dishes_plates: 'Geschirr/Teller wärmen',
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Deutsche Phasennamen, keyed nach ENGLISCHEM Enum-Wert (wie ProgramNameDe) - deckt so alle
|
|
179
|
+
* Gerätetypen auf einmal ab. Wird als Fallback nach den numerischen BY_TYPE_DE-Tabellen genutzt
|
|
180
|
+
* (siehe objects.js phaseTextDe), sodass bestehende Übersetzungen unveraendert bleiben.
|
|
181
|
+
*/
|
|
182
|
+
const PhaseNameDe = {
|
|
183
|
+
not_running: '', program_running: 'In Betrieb', process_running: 'In Betrieb',
|
|
184
|
+
drying: 'Trocknen', finished: 'Ende', process_finished: 'Beendet', cooling_down: 'Abkühlen',
|
|
185
|
+
comfort_cooling: 'Komfortabkühlen', safety_cooling: 'Sicherheitsabkühlung', anti_crease: 'Knitterschutz',
|
|
186
|
+
normal: 'Normal', normal_plus: 'Normal plus', extra_dry: 'Extratrocken', slightly_dry: 'Leicht trocken',
|
|
187
|
+
hand_iron: 'Bügelfeucht', hand_iron_1: 'Handbügelfeucht 1', hand_iron_2: 'Handbügelfeucht 2',
|
|
188
|
+
machine_iron: 'Maschinenbügelfeucht', moisten: 'Befeuchten', thermo_spin: 'Thermoschleudern',
|
|
189
|
+
timed_drying: 'Zeitprogramm', warm_air: 'Warmluft', steam_smoothing: 'Dampfglätten', smoothing: 'Glätten',
|
|
190
|
+
rinse_out_lint: 'Flusen ausspülen', rinses: 'Spülen', rinse: 'Spülen', automatic_start: 'Automatikstart',
|
|
191
|
+
perfect_dry_active: 'PerfectDry aktiv',
|
|
192
|
+
// Kaffeevollautomat
|
|
193
|
+
heating_up: 'Aufheizen', espresso: 'Espresso', hot_milk: 'Heiße Milch', milk_foam: 'Milchschaum',
|
|
194
|
+
dispensing: 'Ausgabe', pre_brewing: 'Vorbrühen', grinding: 'Mahlen', second_espresso: 'Zweiter Espresso',
|
|
195
|
+
second_pre_brewing: 'Zweites Vorbrühen', second_grinding: 'Zweites Mahlen',
|
|
196
|
+
// Dampfgarer / Dampfbackofen
|
|
197
|
+
steam_reduction: 'Dampfreduktion', waiting_for_start: 'Warten auf Start', heating_up_phase: 'Aufheizphase',
|
|
198
|
+
searing: 'Anbraten', roasting: 'Braten', energy_save: 'Energiesparen', pre_heating: 'Vorheizen',
|
|
199
|
+
// Wärmeschublade
|
|
200
|
+
door_open: 'Tür offen', keeping_warm: 'Warmhalten',
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
/** Deutscher Phasenname aus englischem Enum-Wert; null wenn unbekannt (Fallback engl.). */
|
|
204
|
+
function phaseNameDe(enText) {
|
|
205
|
+
if (enText == null) return null;
|
|
206
|
+
return PhaseNameDe[enText] != null ? PhaseNameDe[enText] : null;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/** Deutscher Programmname aus englischem Enum-Wert; null wenn unbekannt (Fallback engl.). */
|
|
210
|
+
function programNameDe(enText) {
|
|
211
|
+
if (enText == null) return null;
|
|
212
|
+
return ProgramNameDe[enText] != null ? ProgramNameDe[enText] : null;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// deviceType → { statusDe, phaseDe, programDe? }
|
|
216
|
+
const BY_TYPE_DE = {
|
|
217
|
+
1: { phase: ProgramPhaseWashingMachineDe }, // Waschmaschine
|
|
218
|
+
2: { phase: ProgramPhaseWashingMachineDe }, // Trockner (nutzt DryingStep separat)
|
|
219
|
+
24: { phase: ProgramPhaseWashingMachineDe }, // Waschtrockner
|
|
220
|
+
7: { phase: ProgramPhaseDishwasherDe }, // Spülmaschine
|
|
221
|
+
12: { phase: ProgramPhaseOvenDe }, // Backofen
|
|
222
|
+
13: { phase: ProgramPhaseOvenDe },
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
function statusDe(v) { return StateStatusDe[v] != null ? StateStatusDe[v] : null; }
|
|
226
|
+
function programTypeDe(v) { return StateProgramTypeDe[v] != null ? StateProgramTypeDe[v] : null; }
|
|
227
|
+
function dryingStepDe(v) { return StateDryingStepDe[v] != null ? StateDryingStepDe[v] : null; }
|
|
228
|
+
function phaseDe(deviceType, v) {
|
|
229
|
+
const m = BY_TYPE_DE[deviceType];
|
|
230
|
+
if (m && m.phase && m.phase[v] != null) return m.phase[v];
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
module.exports = {
|
|
235
|
+
StateStatusDe, StateProgramTypeDe, StateDryingStepDe, ProgramNameDe, PhaseNameDe,
|
|
236
|
+
statusDe, programTypeDe, dryingStepDe, phaseDe, programNameDe, phaseNameDe,
|
|
237
|
+
};
|
package/lib/objects.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Deklaratives Objektmodell: /State- und /Ident-Felder → ioBroker-States.
|
|
5
|
+
* Enthält Rollen, Typen, Einheiten und Dekodierfunktionen.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const enums = require('./enums');
|
|
9
|
+
const de = require('./enums_de');
|
|
10
|
+
|
|
11
|
+
const TEMP_SENTINEL = -32768; // "nicht verfügbar"
|
|
12
|
+
|
|
13
|
+
/** [h, min] → Gesamtminuten (null bei fehlend). */
|
|
14
|
+
function timeToMinutes(arr) {
|
|
15
|
+
if (!Array.isArray(arr) || arr.length < 2) return null;
|
|
16
|
+
return arr[0] * 60 + arr[1];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** [h, min] → "H:MM"-String (wie mielecloudservice), null bei fehlend. */
|
|
20
|
+
function timeToHHMM(arr) {
|
|
21
|
+
if (!Array.isArray(arr) || arr.length < 2) return null;
|
|
22
|
+
return `${arr[0]}:${String(arr[1]).padStart(2, '0')}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Deutsch mit englischem Fallback
|
|
26
|
+
function statusTextDe(v) { return de.statusDe(v) || enums.statusText(v); }
|
|
27
|
+
function programTypeTextDe(v) { return de.programTypeDe(v) || enums.programTypeText(v); }
|
|
28
|
+
function dryingStepTextDe(v) { return de.dryingStepDe(v) || enums.dryingStepText(v); }
|
|
29
|
+
function programTextDe(dt, v) { const en = enums.programText(dt, v); return de.programNameDe(en) || en; }
|
|
30
|
+
// Phase: erst numerische DE-Tabelle (Waschen/Spülen/Backofen), dann englisch-basierte DE-Map
|
|
31
|
+
// (deckt alle uebrigen Gerätetypen ab), sonst englischer Klartext.
|
|
32
|
+
function phaseTextDe(dt, v) { const en = enums.phaseText(dt, v); return de.phaseDe(dt, v) || de.phaseNameDe(en) || en; }
|
|
33
|
+
|
|
34
|
+
/** Miele-Temperatur (Hundertstel °C) → °C, Sentinel → null. */
|
|
35
|
+
function temp(v) {
|
|
36
|
+
if (v == null || v === TEMP_SENTINEL) return null;
|
|
37
|
+
return v / 100;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Zustands-Kanäle (Rohwert + optionaler Klartext) je /State-Feld.
|
|
42
|
+
* decode(value, ctx) → { states: [{sub, val}] }
|
|
43
|
+
* ctx = { deviceType }
|
|
44
|
+
*/
|
|
45
|
+
const STATE_FIELDS = {
|
|
46
|
+
Status: {
|
|
47
|
+
states: [
|
|
48
|
+
{ sub: 'status', role: 'value', type: 'number', name: 'Status (raw)' },
|
|
49
|
+
{ sub: 'statusText', role: 'text', type: 'string', name: 'Status' },
|
|
50
|
+
],
|
|
51
|
+
decode: (v) => [{ sub: 'status', val: v }, { sub: 'statusText', val: statusTextDe(v) }],
|
|
52
|
+
},
|
|
53
|
+
ProgramType: {
|
|
54
|
+
states: [
|
|
55
|
+
{ sub: 'programType', role: 'value', type: 'number', name: 'Program type (raw)' },
|
|
56
|
+
{ sub: 'programTypeText', role: 'text', type: 'string', name: 'Program type' },
|
|
57
|
+
],
|
|
58
|
+
decode: (v) => [{ sub: 'programType', val: v }, { sub: 'programTypeText', val: programTypeTextDe(v) }],
|
|
59
|
+
},
|
|
60
|
+
ProgramID: {
|
|
61
|
+
states: [
|
|
62
|
+
{ sub: 'programId', role: 'value', type: 'number', name: 'Program (raw)' },
|
|
63
|
+
{ sub: 'programText', role: 'text', type: 'string', name: 'Program' },
|
|
64
|
+
],
|
|
65
|
+
decode: (v, ctx) => [{ sub: 'programId', val: v }, { sub: 'programText', val: programTextDe(ctx.deviceType, v) }],
|
|
66
|
+
},
|
|
67
|
+
ProgramPhase: {
|
|
68
|
+
states: [
|
|
69
|
+
{ sub: 'programPhase', role: 'value', type: 'number', name: 'Phase (raw)' },
|
|
70
|
+
{ sub: 'programPhaseText', role: 'text', type: 'string', name: 'Phase' },
|
|
71
|
+
],
|
|
72
|
+
decode: (v, ctx) => [{ sub: 'programPhase', val: v }, { sub: 'programPhaseText', val: phaseTextDe(ctx.deviceType, v) }],
|
|
73
|
+
},
|
|
74
|
+
RemainingTime: {
|
|
75
|
+
states: [
|
|
76
|
+
{ sub: 'remainingMinutes', role: 'value.interval', type: 'number', unit: 'min', name: 'Remaining time' },
|
|
77
|
+
{ sub: 'remainingHHMM', role: 'text', type: 'string', name: 'Remaining time (H:MM)' },
|
|
78
|
+
// Voraussichtliches Programmende (wie mielecloudservice.estimatedEndTime). Der Wert wird
|
|
79
|
+
// NICHT hier dekodiert (die Rohantwort kennt keine Uhrzeit), sondern in main.js aus
|
|
80
|
+
// "jetzt + Restzeit" berechnet - hier nur die Objektanlage.
|
|
81
|
+
{ sub: 'estimatedEndTime', role: 'value.time', type: 'number', name: 'Estimated end time' },
|
|
82
|
+
{ sub: 'estimatedEndTimeText', role: 'text', type: 'string', name: 'Estimated end time (HH:MM)' },
|
|
83
|
+
],
|
|
84
|
+
decode: (v) => [{ sub: 'remainingMinutes', val: timeToMinutes(v) }, { sub: 'remainingHHMM', val: timeToHHMM(v) }],
|
|
85
|
+
},
|
|
86
|
+
ElapsedTime: {
|
|
87
|
+
states: [
|
|
88
|
+
{ sub: 'elapsedMinutes', role: 'value.interval', type: 'number', unit: 'min', name: 'Elapsed time' },
|
|
89
|
+
{ sub: 'elapsedHHMM', role: 'text', type: 'string', name: 'Elapsed time (H:MM)' },
|
|
90
|
+
],
|
|
91
|
+
decode: (v) => [{ sub: 'elapsedMinutes', val: timeToMinutes(v) }, { sub: 'elapsedHHMM', val: timeToHHMM(v) }],
|
|
92
|
+
},
|
|
93
|
+
StartTime: {
|
|
94
|
+
states: [
|
|
95
|
+
{ sub: 'startInMinutes', role: 'value.interval', type: 'number', unit: 'min', name: 'Start delay' },
|
|
96
|
+
{ sub: 'startHHMM', role: 'text', type: 'string', name: 'Start delay (H:MM)' },
|
|
97
|
+
],
|
|
98
|
+
decode: (v) => [{ sub: 'startInMinutes', val: timeToMinutes(v) }, { sub: 'startHHMM', val: timeToHHMM(v) }],
|
|
99
|
+
},
|
|
100
|
+
TargetTemperature: {
|
|
101
|
+
states: [
|
|
102
|
+
{ sub: 'targetTemperature', role: 'value.temperature', type: 'number', unit: '°C', name: 'Target temperature' },
|
|
103
|
+
{ sub: 'targetTemperatureZone2', role: 'value.temperature', type: 'number', unit: '°C', name: 'Target temperature zone 2' },
|
|
104
|
+
{ sub: 'targetTemperatureZone3', role: 'value.temperature', type: 'number', unit: '°C', name: 'Target temperature zone 3' },
|
|
105
|
+
],
|
|
106
|
+
decode: (v) => [
|
|
107
|
+
{ sub: 'targetTemperature', val: temp(v && v[0]) },
|
|
108
|
+
{ sub: 'targetTemperatureZone2', val: temp(v && v[1]) },
|
|
109
|
+
{ sub: 'targetTemperatureZone3', val: temp(v && v[2]) },
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
Temperature: {
|
|
113
|
+
states: [
|
|
114
|
+
{ sub: 'temperature', role: 'value.temperature', type: 'number', unit: '°C', name: 'Temperature' },
|
|
115
|
+
{ sub: 'temperatureZone2', role: 'value.temperature', type: 'number', unit: '°C', name: 'Temperature zone 2' },
|
|
116
|
+
{ sub: 'temperatureZone3', role: 'value.temperature', type: 'number', unit: '°C', name: 'Temperature zone 3' },
|
|
117
|
+
],
|
|
118
|
+
decode: (v) => [
|
|
119
|
+
{ sub: 'temperature', val: temp(v && v[0]) },
|
|
120
|
+
{ sub: 'temperatureZone2', val: temp(v && v[1]) },
|
|
121
|
+
{ sub: 'temperatureZone3', val: temp(v && v[2]) },
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
SignalInfo: {
|
|
125
|
+
states: [{ sub: 'signalInfo', role: 'indicator', type: 'boolean', name: 'Info signal' }],
|
|
126
|
+
decode: (v) => [{ sub: 'signalInfo', val: !!v }],
|
|
127
|
+
},
|
|
128
|
+
SignalFailure: {
|
|
129
|
+
states: [{ sub: 'signalFailure', role: 'indicator.maintenance', type: 'boolean', name: 'Failure signal' }],
|
|
130
|
+
decode: (v) => [{ sub: 'signalFailure', val: !!v }],
|
|
131
|
+
},
|
|
132
|
+
SignalDoor: {
|
|
133
|
+
states: [{ sub: 'signalDoor', role: 'sensor.door', type: 'boolean', name: 'Door open' }],
|
|
134
|
+
decode: (v) => [{ sub: 'signalDoor', val: !!v }],
|
|
135
|
+
},
|
|
136
|
+
RemoteEnable: {
|
|
137
|
+
states: [
|
|
138
|
+
{ sub: 'mobileStart', role: 'indicator', type: 'boolean', name: 'MobileStart enabled' },
|
|
139
|
+
{ sub: 'remoteEnableRaw', role: 'json', type: 'string', name: 'RemoteEnable (raw)' },
|
|
140
|
+
],
|
|
141
|
+
// Element[1] = MobileStart-Freigabe (0/1). Steuerung nur möglich, wenn 1.
|
|
142
|
+
decode: (v) => [
|
|
143
|
+
{ sub: 'mobileStart', val: Array.isArray(v) ? !!v[1] : false },
|
|
144
|
+
{ sub: 'remoteEnableRaw', val: JSON.stringify(v) },
|
|
145
|
+
],
|
|
146
|
+
},
|
|
147
|
+
ProcessAction: {
|
|
148
|
+
states: [{ sub: 'processAction', role: 'value', type: 'number', name: 'Process action' }],
|
|
149
|
+
decode: (v) => [{ sub: 'processAction', val: v }],
|
|
150
|
+
},
|
|
151
|
+
DeviceAction: {
|
|
152
|
+
states: [{ sub: 'deviceAction', role: 'value', type: 'number', name: 'Device action' }],
|
|
153
|
+
decode: (v) => [{ sub: 'deviceAction', val: v }],
|
|
154
|
+
},
|
|
155
|
+
Light: {
|
|
156
|
+
states: [{ sub: 'light', role: 'switch.light', type: 'boolean', name: 'Light on' }],
|
|
157
|
+
// Light: 0 = kein Licht/aus, 1 = an, 2 = aus (gerätespezifisch); >0 && !=2 → an
|
|
158
|
+
decode: (v) => [{ sub: 'light', val: v === 1 }],
|
|
159
|
+
},
|
|
160
|
+
StandbyState: {
|
|
161
|
+
states: [{ sub: 'standbyState', role: 'value', type: 'number', name: 'Standby state' }],
|
|
162
|
+
decode: (v) => [{ sub: 'standbyState', val: v }],
|
|
163
|
+
},
|
|
164
|
+
SpinningSpeed: {
|
|
165
|
+
states: [{ sub: 'spinningSpeed', role: 'value', type: 'number', unit: 'rpm', name: 'Spin speed' }],
|
|
166
|
+
decode: (v) => [{ sub: 'spinningSpeed', val: v }],
|
|
167
|
+
},
|
|
168
|
+
DryingStep: {
|
|
169
|
+
states: [
|
|
170
|
+
{ sub: 'dryingStep', role: 'value', type: 'number', name: 'Drying step (raw)' },
|
|
171
|
+
{ sub: 'dryingStepText', role: 'text', type: 'string', name: 'Drying step' },
|
|
172
|
+
],
|
|
173
|
+
decode: (v) => [{ sub: 'dryingStep', val: v }, { sub: 'dryingStepText', val: dryingStepTextDe(v) }],
|
|
174
|
+
},
|
|
175
|
+
SyncState: {
|
|
176
|
+
states: [{ sub: 'syncState', role: 'value', type: 'number', name: 'Sync state' }],
|
|
177
|
+
decode: (v) => [{ sub: 'syncState', val: v }],
|
|
178
|
+
},
|
|
179
|
+
InternalState: {
|
|
180
|
+
states: [{ sub: 'internalState', role: 'value', type: 'number', name: 'Internal state' }],
|
|
181
|
+
decode: (v) => [{ sub: 'internalState', val: v }],
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
/** Ident-Felder → info-States (statisch). */
|
|
186
|
+
const IDENT_FIELDS = [
|
|
187
|
+
{ sub: 'techType', role: 'info.name', type: 'string', name: 'Model / TechType', path: ['DeviceIdentLabel', 'TechType'] },
|
|
188
|
+
{ sub: 'fabNumber', role: 'info.serial', type: 'string', name: 'Serial number', path: ['DeviceIdentLabel', 'FabNumber'] },
|
|
189
|
+
{ sub: 'matNumber', role: 'text', type: 'string', name: 'Material number', path: ['DeviceIdentLabel', 'MatNumber'] },
|
|
190
|
+
{ sub: 'deviceType', role: 'value', type: 'number', name: 'Device type', path: ['DeviceType'] },
|
|
191
|
+
{ sub: 'xkmType', role: 'text', type: 'string', name: 'WiFi module type', path: ['XKMIdentLabel', 'TechType'] },
|
|
192
|
+
{ sub: 'xkmVersion', role: 'info.firmware', type: 'string', name: 'WiFi module firmware', path: ['XKMIdentLabel', 'ReleaseVersion'] },
|
|
193
|
+
{ sub: 'protocolVersion', role: 'value', type: 'number', name: 'Protocol version', path: ['ProtocolVersion'] },
|
|
194
|
+
];
|
|
195
|
+
|
|
196
|
+
/** Steuer-States (beschreibbar, per Opcode). Nur angelegt, wenn allowControl. */
|
|
197
|
+
const CONTROL_STATES = [
|
|
198
|
+
{ sub: 'start', role: 'button.start', name: 'Start program', opcode: 0x01 },
|
|
199
|
+
{ sub: 'stop', role: 'button.stop', name: 'Stop program', opcode: 0x37 },
|
|
200
|
+
{ sub: 'pause', role: 'button.pause', name: 'Pause program', opcode: 0x03 },
|
|
201
|
+
{ sub: 'powerOn', role: 'button', name: 'Switch on', opcode: 0x10 },
|
|
202
|
+
{ sub: 'powerOff', role: 'button', name: 'Switch off', opcode: 0x13 },
|
|
203
|
+
{ sub: 'lightOn', role: 'button', name: 'Light on', opcode: 0x0d },
|
|
204
|
+
{ sub: 'lightOff', role: 'button', name: 'Light off', opcode: 0x0e },
|
|
205
|
+
];
|
|
206
|
+
|
|
207
|
+
// Geräteart je DeviceType (für den Objektnamen).
|
|
208
|
+
const DEVICE_CATEGORY = {
|
|
209
|
+
1: 'Waschmaschine', 2: 'Trockner', 24: 'Waschtrockner',
|
|
210
|
+
7: 'Spülmaschine', 12: 'Backofen', 13: 'Backofen mit Mikrowelle',
|
|
211
|
+
15: 'Dampfgarer', 16: 'Dampfbackofen', 17: 'Kaffeevollautomat',
|
|
212
|
+
18: 'Kühlschrank', 19: 'Gefrierschrank', 20: 'Kühl-Gefrier-Kombination',
|
|
213
|
+
21: 'Weinkühlschrank', 23: 'Dunstabzug', 25: 'Kochfeld', 27: 'Mikrowelle',
|
|
214
|
+
67: 'Wärmeschublade', 68: 'Wärmeschublade',
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
function deviceCategory(deviceType) {
|
|
218
|
+
return DEVICE_CATEGORY[deviceType] || null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Gerätespezifische STATE_FIELDS nur beim passenden Gerätetyp anlegen/schreiben - sonst stünde z. B.
|
|
222
|
+
// die Schleuderdrehzahl auch bei Spülmaschine und Backofen (sinnlos). Key = STATE_FIELDS-Schlüssel,
|
|
223
|
+
// Wert = erlaubte deviceTypes. Nicht gelistete Felder gelten für ALLE Geräte (Status, Programm, …).
|
|
224
|
+
const FIELD_DEVICE_TYPES = {
|
|
225
|
+
SpinningSpeed: [1, 24], // Schleuderdrehzahl: Waschmaschine, Waschtrockner
|
|
226
|
+
DryingStep: [2, 24], // Trockenstufe: Trockner, Waschtrockner
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
/** true, wenn das STATE_FIELDS-Feld [key] für [deviceType] angelegt/geschrieben werden soll. */
|
|
230
|
+
function fieldAllowed(key, deviceType) {
|
|
231
|
+
const allowed = FIELD_DEVICE_TYPES[key];
|
|
232
|
+
return !allowed || allowed.includes(deviceType);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Deutsche Datenpunkt-Namen (überlappende Punkte an mielecloudservice angelehnt).
|
|
236
|
+
const DE_NAMES = {
|
|
237
|
+
state: {
|
|
238
|
+
status: 'Status (Rohwert)', statusText: 'Status',
|
|
239
|
+
programType: 'Programmart (Rohwert)', programTypeText: 'Programmart',
|
|
240
|
+
programId: 'Programmbezeichnung (Rohwert)', programText: 'Programmbezeichnung',
|
|
241
|
+
programPhase: 'Programmphase (Rohwert)', programPhaseText: 'Programmphase',
|
|
242
|
+
remainingMinutes: 'Restzeit (Minuten)', remainingHHMM: 'Restzeit',
|
|
243
|
+
estimatedEndTime: 'Voraussichtliches Ende', estimatedEndTimeText: 'Voraussichtliches Ende (Uhrzeit)',
|
|
244
|
+
elapsedMinutes: 'Verstrichene Zeit (Minuten)', elapsedHHMM: 'Verstrichene Zeit',
|
|
245
|
+
startInMinutes: 'Startvorwahl (Minuten)', startHHMM: 'Startvorwahl',
|
|
246
|
+
targetTemperature: 'Zieltemperatur', targetTemperatureZone2: 'Zieltemperatur Zone 2', targetTemperatureZone3: 'Zieltemperatur Zone 3',
|
|
247
|
+
temperature: 'Temperatur', temperatureZone2: 'Temperatur Zone 2', temperatureZone3: 'Temperatur Zone 3',
|
|
248
|
+
signalInfo: 'Info-Signal', signalFailure: 'Störungssignal', signalDoor: 'Tür offen',
|
|
249
|
+
mobileStart: 'MobileStart verfügbar', remoteEnableRaw: 'Fernsteuer-Freigabe (Rohwert)',
|
|
250
|
+
processAction: 'Prozess-Aktion', deviceAction: 'Geräte-Aktion', light: 'Licht',
|
|
251
|
+
standbyState: 'Standby-Zustand', spinningSpeed: 'Schleuderdrehzahl',
|
|
252
|
+
dryingStep: 'Trockenstufe (Rohwert)', dryingStepText: 'Trockenstufe',
|
|
253
|
+
syncState: 'Sync-Zustand', internalState: 'Interner Zustand',
|
|
254
|
+
},
|
|
255
|
+
info: {
|
|
256
|
+
techType: 'Gerätetyp (Technik)', fabNumber: 'Seriennummer', matNumber: 'Materialnummer',
|
|
257
|
+
deviceType: 'Gerätetyp', xkmType: 'Kommunikationsmodul-Typ', xkmVersion: 'Kommunikationsmodul-Firmware',
|
|
258
|
+
protocolVersion: 'Protokollversion',
|
|
259
|
+
},
|
|
260
|
+
control: {
|
|
261
|
+
start: 'Programm starten', stop: 'Programm stoppen', pause: 'Programm pausieren',
|
|
262
|
+
powerOn: 'Einschalten', powerOff: 'Ausschalten', lightOn: 'Licht an', lightOff: 'Licht aus',
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* common.name für einen Datenpunkt: {en, de} wenn eine deutsche Übersetzung existiert,
|
|
268
|
+
* sonst nur der englische Name. Bei german=false wird immer nur Englisch verwendet.
|
|
269
|
+
*/
|
|
270
|
+
function nameFor(channel, sub, en, german) {
|
|
271
|
+
const de = DE_NAMES[channel] && DE_NAMES[channel][sub];
|
|
272
|
+
if (german && de) return { en, de };
|
|
273
|
+
return en;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function pathGet(obj, path) {
|
|
277
|
+
let cur = obj;
|
|
278
|
+
for (const p of path) {
|
|
279
|
+
if (cur == null) return undefined;
|
|
280
|
+
cur = cur[p];
|
|
281
|
+
}
|
|
282
|
+
return cur;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
module.exports = { STATE_FIELDS, IDENT_FIELDS, CONTROL_STATES, DE_NAMES, DEVICE_CATEGORY, deviceCategory, FIELD_DEVICE_TYPES, fieldAllowed, nameFor, timeToMinutes, temp, pathGet, TEMP_SENTINEL };
|