1/* Config Sample
2 *
3 * For more information on how you can configure this file
4 * see https://docs.magicmirror.builders/configuration/introduction.html
5 * and https://docs.magicmirror.builders/modules/configuration.html
6 */
7let config = {
8 address: "localhost",
9 port: 8080,
10 basePath: "/",
11 ipWhitelist: ["127.0.0.1", "192.168.178.0/24", "::ffff:192.168.178.0/24", "::1"],
12
13 useHttps: false,
14 httpsPrivateKey: "",
15 httpsCertificate: "",
16
17 language: "de",
18 locale: "de-DE",
19 logLevel: ["INFO", "LOG", "WARN", "ERROR"],
20 timeFormat: 24,
21 units: "metric",
22
23 modules: [
24 { module: "alert" },
25 { module: "updatenotification", position: "top_bar" },
26 { module: "clock", position: "top_left", config: { showWeek: true } },
27
28 // Kalender
29 {
30 module: "calendar",
31 header: "Kalender",
32 position: "top_left",
33 config: {
34 maximumEntries: 20,
35 maximumNumberOfDays: 365,
36 fetchInterval: 5 * 60 * 1000,
37 timeFormat: "relative",
38 dateFormat: "ddd, DD.MM.",
39 getRelative: 24,
40 urgency: 0,
41 showEnd: true,
42 colored: true,
43 calendars: [
44 {
45 symbol: "calendar",
46 color: "#8ab4f8",
47 url: "https://calendar.google.com/calendar/ical/DEIN_KALENDER/private-DEIN_HASH/basic.ics"
48 },
49 {
50 symbol: "calendar-check",
51 color: "#a3d977",
52 url: "https://ics.tools/Feiertage/schleswig-holstein.ics"
53 }
54 ]
55 }
56 },
57
58 // Wetterwarnungen (DWD)
59 {
60 module: "MMM-DWD-WarnWeather",
61 position: "bottom_left",
62 header: "Wetterwarnungen",
63 config: {
64 warnCellID: "701003001",
65 changeColor: true,
66 interval: 10 * 60 * 1000,
67 loadingText: "Lade Warnungen...",
68 noWarningText: "Keine Warnungen",
69 severityThreshold: 1,
70 displayRegionName: true
71 }
72 },
73
74 // Wetter aktuell
75 {
76 module: "MMM-OpenWeatherMapForecast",
77 position: "top_right",
78 header: "Schlutup",
79 config: {
80 apikey: "DEIN_OWM_KEY_HIER",
81 latitude: "53.8873",
82 longitude: "10.7977",
83 units: "metric",
84 language: "de",
85 endpoint: "https://api.openweathermap.org/data/3.0/onecall",
86 showCurrentConditions: true,
87 showExtraCurrentConditions: true,
88 showWind: true,
89 showPrecipitation: true,
90 showHourlyForecast: false,
91 showDailyForecast: false,
92 iconset: "6fa",
93 animateMainIconOnly: true,
94 colored: true
95 }
96 },
97
98 // Wettervorhersage
99 {
100 module: "MMM-OpenWeatherMapForecast",
101 position: "top_right",
102 header: "Vorhersage Schlutup",
103 config: {
104 apikey: "DEIN_OWM_KEY_HIER",
105 latitude: "53.8873",
106 longitude: "10.7977",
107 units: "metric",
108 language: "de",
109 endpoint: "https://api.openweathermap.org/data/3.0/onecall",
110 showCurrentConditions: false,
111 showHourlyForecast: false,
112 showDailyForecast: true,
113 maxDailiesToShow: 5,
114 forecastLayout: "table",
115 iconset: "6fa",
116 colored: true,
117 requestDelay: 1000,
118 label_days: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"]
119 }
120 },
121
122 // Kamera Haustür
123 {
124 module: "MMM-go2rtc",
125 position: "top_right",
126 config: {
127 host: "192.168.178.33",
128 port: 1984,
129 https: false,
130 width: "360px",
131 entity: "haustuer"
132 }
133 },
134
135 // Kamera Carport
136 {
137 module: "MMM-go2rtc",
138 position: "top_right",
139 config: {
140 host: "192.168.178.33",
141 port: 1984,
142 https: false,
143 width: "360px",
144 entity: "carport"
145 }
146 },
147
148 // Home Assistant MQTT
149 {
150 module: "MMM-HomeAssistant",
151 config: {
152 mqttServer: "mqtt://192.168.178.162",
153 mqttPort: 1883,
154 username: "XXXX",
155 password: "XXXX",
156 deviceName: "MagicMirror",
157 autodiscoveryTopic: "homeassistant",
158 monitorControl: true,
159 brightnessControl: true,
160 moduleControl: true,
161 monitorStatusCommand:
162 "wlr-randr | awk '/HDMI-A-1/ {found=1} found && /Enabled:/ {print ($2 == \"yes\") ? \"true\" : \"false\"; exit} END {if(!found) print \"false\"}'",
163 monitorOnCommand: "wlr-randr --output HDMI-A-1 --on --transform 90",
164 monitorOffCommand: "wlr-randr --output HDMI-A-1 --off",
165 pm2ProcessName: "mm",
166 refreshBrowser: true
167 }
168 },
169
170 // Temperatursensoren
171 {
172 module: "MMM-homeassistant-sensors",
173 position: "bottom_left",
174 config: {
175 title: "Temperatur",
176 host: "192.168.178.33",
177 port: "8123",
178 https: false,
179 token: "DEIN_TOKEN_HIER",
180 prettyName: true,
181 ignoreStrings: [],
182 sensorConfigs: [
183 { sensor: "sensor.outdoor_temperature", name: "Draussen", icons: [{ default: "thermometer" }] },
184 { sensor: "sensor.temp_luft_dachboden_temperature", name: "Dachboden", icons: [{ default: "thermometer" }] },
185 { sensor: "sensor.temp_luft_esszimmer_temperature", name: "Esszimmer", icons: [{ default: "thermometer" }] },
186 { sensor: "sensor.temp_luft_flur_temperature", name: "Flur", icons: [{ default: "thermometer" }] },
187 { sensor: "sensor.temp_luft_gartenhaus_temperature", name: "Gartenhaus", icons: [{ default: "thermometer" }] },
188 { sensor: "sensor.temp_luft_keller_felix_temperature", name: "Keller (Felix)", icons: [{ default: "thermometer" }] },
189 { sensor: "sensor.temp_luft_kuche_temperature", name: "Kueche", icons: [{ default: "thermometer" }] },
190 { sensor: "sensor.temp_luft_luis_temperature", name: "Luis", icons: [{ default: "thermometer" }] },
191 { sensor: "sensor.temp_luft_schlafzimmer_temperature", name: "Schlafzimmer", icons: [{ default: "thermometer" }] },
192 { sensor: "sensor.temp_luft_wohnzimmer_temperature", name: "Wohnzimmer", icons: [{ default: "thermometer" }] },
193 { sensor: "sensor.temp_luft_badezimmer_temperature", name: "Badezimmer", icons: [{ default: "thermometer" }] },
194 { sensor: "sensor.temp_luft_bad_temperature", name: "Bad", icons: [{ default: "thermometer" }] }
195 ]
196 }
197 },
198
199 // Lichter an
200 {
201 module: "MMM-HomeAssistantDisplay",
202 position: "bottom_left",
203 config: {
204 host: "192.168.178.33",
205 token: "DEIN_TOKEN_HIER",
206 port: 8123,
207 useTLS: false,
208 title: "Lichter an?",
209 useModuleTrigger: true,
210 moduleTriggerTemplate: `{{ states('light.alle_lichter') == 'on' }}`,
211 moduleTriggerEntities: ["light.alle_lichter"],
212 class: "lights-on",
213 sections: [
214 {
215 triggerEntities: ["light.alle_lichter"],
216 refreshTimer: 5,
217 displayTemplate: `
218 {% set gid = 'light.alle_lichter' %}
219 {% set members = state_attr(gid, 'entity_id') or [] %}
220 {% set on_lights = expand(members) | selectattr('state','equalto','on') | list %}
221
222 {% if on_lights | count == 0 %}
223 <div class="dimmed small">Keine Lichter an</div>
224 {% else %}
225 {% for s in on_lights | sort(attribute='name') %}
226 <i class="mdi mdi-lightbulb-on-outline" style="color: #FFD700;"></i> {{ s.name }}<br>
227 {% endfor %}
228 {% endif %}
229 `
230 }
231 ]
232 }
233 },
234
235 // Fenster/Türen offen
236 {
237 module: "MMM-HomeAssistantDisplay",
238 position: "bottom_left",
239 config: {
240 host: "192.168.178.33",
241 token: "DEIN_TOKEN_HIER",
242 port: 8123,
243 useTLS: false,
244 title: "Fenster/Tueren offen",
245 useModuleTrigger: true,
246 moduleTriggerTemplate: `{{ states('binary_sensor.fenster_turen') == 'on' }}`,
247 moduleTriggerEntities: ["binary_sensor.fenster_turen"],
248 class: "contacts-open",
249 sections: [
250 {
251 triggerEntities: ["binary_sensor.fenster_turen"],
252 refreshTimer: 5,
253 displayTemplate: `
254 {% set gid = 'binary_sensor.fenster_turen' %}
255 {% set members = state_attr(gid, 'entity_id') or [] %}
256 {% set open_contacts = expand(members) | selectattr('state','equalto','on') | list %}
257
258 {% if open_contacts | count == 0 %}
259 <div class="dimmed small">Alles geschlossen</div>
260 {% else %}
261 {% for e in open_contacts | sort(attribute='name') %}
262 {% set dc = (device_class(e.entity_id) or '') %}
263 {% if dc == 'door' %}
264 <i class="mdi mdi-door-open"></i>
265 {% elif dc == 'window' %}
266 <i class="mdi mdi-window-open"></i>
267 {% elif dc in ['garage_door','opening'] %}
268 <i class="mdi mdi-garage-open"></i>
269 {% else %}
270 <i class="mdi mdi-alert-outline"></i>
271 {% endif %}
272 {{ e.name }}<br>
273 {% endfor %}
274 {% endif %}
275 `
276 }
277 ]
278 }
279 },
280
281 // Abfallentsorgung
282 {
283 module: "MMM-HomeAssistantDisplay",
284 position: "bottom_left",
285 config: {
286 host: "192.168.178.33",
287 token: "DEIN_TOKEN_HIER",
288 port: 8123,
289 useTLS: false,
290 title: "Abfallentsorgung",
291 useModuleTrigger: true,
292 moduleTriggerTemplate: `{{ state_attr('sensor.nachster_abfall', 'tage') | int(99) <= 2 }}`,
293 moduleTriggerEntities: ["sensor.nachster_abfall"],
294 class: "waste-reminder",
295 sections: [
296 {
297 triggerEntities: ["sensor.nachster_abfall"],
298 refreshTimer: 3600,
299 displayTemplate: `
300 {% set abfall_typ = states('sensor.nachster_abfall') %}
301 {% set tage = state_attr('sensor.nachster_abfall', 'tage') | int(99) %}
302 {% set farbe = state_attr('sensor.nachster_abfall', 'farbe') | string %}
303 {% set text = state_attr('sensor.nachster_abfall', 'text') | string %}
304
305 {% if tage <= 2 and tage >= 0 %}
306 {% set color = '#FFFFFF' %}
307 {% if farbe == 'yellow' or ('Gelber Sack' in farbe) %}
308 {% set color = '#FFD700' %}
309 {% elif farbe == 'blue' or ('Papiertonne' in farbe) %}
310 {% set color = '#4169E1' %}
311 {% elif farbe == 'white' or ('Restabfall' in farbe) %}
312 {% set color = '#CCCCCC' %}
313 {% endif %}
314
315 <span style="color: {{ color }}; font-weight: bold;">{{ text | capitalize }}: {{ abfall_typ }}</span>
316 {% else %}
317 <div class="dimmed small">Keine Abholung in den naechsten 2 Tagen</div>
318 {% endif %}
319 `
320 }
321 ]
322 }
323 },
324
325 // Energie Status Karte
326 {
327 module: "MMM-HomeAssistantDisplay",
328 position: "bottom_right",
329 config: {
330 host: "192.168.178.33",
331 token: "DEIN_TOKEN_HIER",
332 port: 8123,
333 useTLS: false,
334 title: "Energie Status",
335 useModuleTrigger: false,
336 class: "energy-status",
337 sections: [
338 {
339 triggerEntities: [
340 "sensor.stromzahler_leistung_aktuell",
341 "sensor.solar_watt_alle",
342 "sensor.speicher_1_battery_percentage",
343 "sensor.speicher_2_battery_percentage",
344 "sensor.eingespeist_taglich",
345 "sensor.pv_ertrag_heute_max",
346 "sensor.speicher_1_daily_battery_charging",
347 "sensor.speicher_2_daily_battery_charging",
348 "sensor.speicher_1_daily_battery_discharging",
349 "sensor.speicher_2_daily_battery_discharging"
350 ],
351 refreshTimer: 10,
352 displayTemplate: `
353 {% set grid = states('sensor.stromzahler_leistung_aktuell') | float(0) %}
354 {% set solar_aktuell = states('sensor.solar_watt_alle') | float(0) %}
355
356 {% set bezug = (grid if grid > 0 else 0) | round(0) %}
357
358 {% set bat1 = states('sensor.speicher_1_battery_percentage') | float(0) %}
359 {% set bat2 = states('sensor.speicher_2_battery_percentage') | float(0) %}
360
361 {% set pv_kwh = states('sensor.pv_ertrag_heute_max') | float(0) | round(2) %}
362
363 {% set bch1_wh = states('sensor.speicher_1_daily_battery_charging') | float(0) %}
364 {% set bch2_wh = states('sensor.speicher_2_daily_battery_charging') | float(0) %}
365 {% set bat_laden_kwh = ((bch1_wh + bch2_wh) / 1000) | round(2) %}
366
367 {% set bdis1_wh = states('sensor.speicher_1_daily_battery_discharging') | float(0) %}
368 {% set bdis2_wh = states('sensor.speicher_2_daily_battery_discharging') | float(0) %}
369 {% set bat_entladen_kwh = ((bdis1_wh + bdis2_wh) / 1000) | round(2) %}
370
371 {% set einsp_state = states('sensor.eingespeist_taglich') %}
372 {% if einsp_state in ['unknown', 'unavailable', 'none', ''] %}
373 {% set eingespeist_heute = 0 %}
374 {% else %}
375 {% set eingespeist_heute = einsp_state | float(0) %}
376 {% endif %}
377
378 <div style="font-size:1.1em; line-height:2.2">
379 <div style="margin-bottom:16px; display:flex; justify-content:space-between;">
380 <span style="color:#FFD700; font-weight:bold;">Solar:</span>
381 <span style="font-weight:bold; margin-left:40px;">{{ solar_aktuell | round(0) }} W</span>
382 </div>
383 <div style="margin-bottom:16px; display:flex; justify-content:space-between;">
384 <span style="color:#FF6B6B; font-weight:bold;">Bezug:</span>
385 <span style="font-weight:bold; margin-left:40px;">{{ bezug }} W</span>
386 </div>
387 <div style="margin-bottom:10px; display:flex; justify-content:space-between;">
388 <span style="color:#4ECDC4; font-weight:bold;">Speicher 1:</span>
389 <span style="font-weight:bold; margin-left:40px;">{{ bat1 | round(0) }}%</span>
390 </div>
391 <div style="margin-bottom:16px; display:flex; justify-content:space-between;">
392 <span style="color:#4ECDC4; font-weight:bold;">Speicher 2:</span>
393 <span style="font-weight:bold; margin-left:40px;">{{ bat2 | round(0) }}%</span>
394 </div>
395 <div style="border-top:1px solid #555; margin:16px 0; padding-top:16px">
396 <div style="color:#AAA; font-size:0.95em; margin-bottom:10px; display:flex; justify-content:space-between;">
397 <span>Heute erzeugt (PV):</span>
398 <span style="margin-left:40px;">{{ pv_kwh }} kWh</span>
399 </div>
400 <div style="color:#AAA; font-size:0.95em; margin-bottom:10px; display:flex; justify-content:space-between;">
401 <span>Heute eingespeist:</span>
402 <span style="margin-left:40px;">{{ eingespeist_heute | round(2) }} kWh</span>
403 </div>
404 <div style="color:#AAA; font-size:0.95em; margin-bottom:10px; display:flex; justify-content:space-between;">
405 <span>Batterie geladen:</span>
406 <span style="margin-left:40px;">{{ bat_laden_kwh }} kWh</span>
407 </div>
408 <div style="color:#AAA; font-size:0.95em; display:flex; justify-content:space-between;">
409 <span>Batterie entladen:</span>
410 <span style="margin-left:40px;">{{ bat_entladen_kwh }} kWh</span>
411 </div>
412 </div>
413 </div>
414 `
415 }
416 ]
417 }
418 }
419 ]
420};
421
422if (typeof module !== "undefined") {
423 module.exports = config;
424}