iobroker.autism-support 0.2.1 → 0.2.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
@@ -92,6 +92,9 @@ npm run start
92
92
 
93
93
  See [CHANGELOG_OLD.md](CHANGELOG_OLD.md) for older entries.
94
94
 
95
+ ### 0.2.2
96
+ - Fix object structure for latest-repo review: `timer` channel, `value.interval` roles, button `read: false`
97
+
95
98
  ### 0.2.1
96
99
  - Weekly plans: weekday tabs in Config, copy to other days, named templates (save/load)
97
100
  - Admin: weekday colors + list of saved plans with active/loaded marker
package/build/main.js CHANGED
@@ -93,10 +93,15 @@ class AutismSupport extends utils.Adapter {
93
93
  return Math.max(60, Math.min(maxHours * 3600, total));
94
94
  }
95
95
  async createTimerStates() {
96
+ await this.setObjectNotExistsAsync(TIMER_CHANNEL, {
97
+ type: "channel",
98
+ common: { name: "Visual Countdown" },
99
+ native: {}
100
+ });
96
101
  const states = {
97
102
  duration: {
98
103
  type: "number",
99
- role: "timer",
104
+ role: "value.interval",
100
105
  name: "Timer duration (seconds)",
101
106
  read: true,
102
107
  write: true,
@@ -106,7 +111,7 @@ class AutismSupport extends utils.Adapter {
106
111
  },
107
112
  remaining: {
108
113
  type: "number",
109
- role: "timer",
114
+ role: "value.interval",
110
115
  name: "Timer remaining (seconds)",
111
116
  read: true,
112
117
  write: false,
@@ -114,7 +119,7 @@ class AutismSupport extends utils.Adapter {
114
119
  },
115
120
  elapsed: {
116
121
  type: "number",
117
- role: "timer",
122
+ role: "value.interval",
118
123
  name: "Timer elapsed (seconds)",
119
124
  read: true,
120
125
  write: false,
@@ -145,28 +150,28 @@ class AutismSupport extends utils.Adapter {
145
150
  type: "boolean",
146
151
  role: "button.start",
147
152
  name: "Start timer",
148
- read: true,
153
+ read: false,
149
154
  write: true
150
155
  },
151
156
  pause: {
152
157
  type: "boolean",
153
158
  role: "button.pause",
154
159
  name: "Pause timer",
155
- read: true,
160
+ read: false,
156
161
  write: true
157
162
  },
158
163
  resume: {
159
164
  type: "boolean",
160
165
  role: "button.start",
161
166
  name: "Resume timer",
162
- read: true,
167
+ read: false,
163
168
  write: true
164
169
  },
165
170
  stop: {
166
171
  type: "boolean",
167
172
  role: "button.stop",
168
173
  name: "Stop timer",
169
- read: true,
174
+ read: false,
170
175
  write: true
171
176
  },
172
177
  setDurationHours: {
@@ -206,6 +211,29 @@ class AutismSupport extends utils.Adapter {
206
211
  native: {}
207
212
  });
208
213
  }
214
+ await this.migrateTimerStateRoles();
215
+ }
216
+ /** Update roles/read flags on existing timer states (object-structure compliance). */
217
+ async migrateTimerStateRoles() {
218
+ const patches = {
219
+ duration: { role: "value.interval" },
220
+ remaining: { role: "value.interval" },
221
+ elapsed: { role: "value.interval" },
222
+ start: { read: false },
223
+ pause: { read: false },
224
+ resume: { read: false },
225
+ stop: { read: false }
226
+ };
227
+ for (const [id, patch] of Object.entries(patches)) {
228
+ const common = {};
229
+ if (patch.role) {
230
+ common.role = patch.role;
231
+ }
232
+ if (patch.read !== void 0) {
233
+ common.read = patch.read;
234
+ }
235
+ await this.extendObjectAsync(`${TIMER_CHANNEL}.${id}`, { common });
236
+ }
209
237
  }
210
238
  async createScheduleStates() {
211
239
  await this.setObjectNotExistsAsync(SCHEDULE_CHANNEL, {
package/build/main.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts"],
4
- "sourcesContent": ["/*\n * ioBroker.autism-support \u2013 Visual Countdown + Daily Schedule\n */\n\nimport * as utils from \"@iobroker/adapter-core\";\nimport { TimerManager } from \"./lib/timer-manager\";\nimport {\n\tdayPeriodsFromConfig,\n\tfindCurrentPeriod,\n\tparseTimeToMinutes,\n\ttype DayPeriodDefinition,\n} from \"./lib/day-periods\";\nimport { findCurrentItemIndex, isPlanFullyExpired, parseSchedulePlan, type SchedulePlan } from \"./lib/schedule-types\";\nimport {\n\tADAPTER_LIBRARY_FILE,\n\tPICTOGRAM_DIR,\n\tPICTOGRAM_FILE_ADAPTER,\n\tPICTOGRAM_PLACEHOLDER_FILE,\n\tLEGACY_VIS_LIBRARY_FILE,\n\temptyLibrary,\n\tisIgnoredPictogramFile,\n\tlibraryFromNativeRows,\n\tmatchesPictogramKey,\n\tmergePictogramSources,\n\tnormalizeTags,\n\tparseLibrary,\n\tpictogramPublicUrl,\n\tpictogramStoragePath,\n\tsyncCustomPictogramRows,\n\tuniquePictogramFilename,\n\ttype CustomPictogram,\n\ttype PictogramLibrary,\n} from \"./lib/pictogram-library\";\nimport {\n\tapplyWeeklyPlanRowsToLibrary,\n\tcreateEmptyWeeklyPlan,\n\tparseWeeklyPlan,\n\tparseWeeklyPlansLibrary,\n\tschedulePlansEqual,\n\tweekdayColorsFromConfig,\n\tweekdayKeyFromDate,\n\tweeklyPlanRowsFromLibrary,\n\ttype WeekdayColors,\n\ttype WeekdayKey,\n\ttype WeeklyPlanData,\n\ttype WeeklyPlansLibrary,\n} from \"./lib/weekly-plan\";\n\nconst TIMER_CHANNEL = \"timer\";\nconst SCHEDULE_CHANNEL = \"schedule\";\n\nfunction secondsToParts(totalSeconds: number): { hours: number; minutes: number } {\n\tconst safe = Math.max(0, Math.round(totalSeconds));\n\treturn {\n\t\thours: Math.floor(safe / 3600),\n\t\tminutes: Math.floor((safe % 3600) / 60),\n\t};\n}\n\nclass AutismSupport extends utils.Adapter {\n\tprivate timerManager: TimerManager | null = null;\n\tprivate scheduleTick: ioBroker.Interval | undefined | null = null;\n\tprivate dayPeriods: DayPeriodDefinition[] = [];\n\tprivate weekdayColors: WeekdayColors = weekdayColorsFromConfig({} as ioBroker.AdapterConfig);\n\tprivate lastAppliedWeekday: WeekdayKey | null = null;\n\n\tpublic constructor(options: Partial<utils.AdapterOptions> = {}) {\n\t\tsuper({\n\t\t\t...options,\n\t\t\tname: \"autism-support\",\n\t\t});\n\t\tthis.on(\"ready\", this.onReady.bind(this));\n\t\tthis.on(\"stateChange\", this.onStateChange.bind(this));\n\t\tthis.on(\"message\", this.onMessage.bind(this));\n\t\tthis.on(\"unload\", this.onUnload.bind(this));\n\t}\n\n\tprivate async onReady(): Promise<void> {\n\t\tconst maxHours = this.config.maxDurationHours ?? 24;\n\t\tconst defaultSeconds = this.getDefaultDurationSeconds(maxHours);\n\t\tthis.dayPeriods = dayPeriodsFromConfig(this.config);\n\t\tthis.weekdayColors = weekdayColorsFromConfig(this.config);\n\n\t\tawait this.createTimerStates();\n\t\tawait this.ensurePictogramStore();\n\t\tawait this.syncCustomPictogramsConfig();\n\t\tawait this.createScheduleStates();\n\t\t// Only apply Admin name/delete edits when the table already lists plans (avoid wiping on first boot).\n\t\tif (Array.isArray(this.config.weeklyPlanRows) && this.config.weeklyPlanRows.length > 0) {\n\t\t\tawait this.applyWeeklyPlanRowsFromConfig();\n\t\t}\n\t\tawait this.syncWeeklyPlansTableToNative();\n\n\t\tthis.timerManager = new TimerManager(\n\t\t\tasync snapshot => {\n\t\t\t\tawait this.publishTimerSnapshot(snapshot);\n\t\t\t},\n\t\t\t{\n\t\t\t\tsetInterval: (handler, ms) => this.setInterval(handler, ms),\n\t\t\t\tclearInterval: handle => this.clearInterval(handle as ioBroker.Interval),\n\t\t\t},\n\t\t);\n\n\t\tawait this.timerManager.setDuration(defaultSeconds, maxHours);\n\t\tawait this.publishTimerSnapshot(this.timerManager.getSnapshot());\n\t\tawait this.publishScheduleRuntime();\n\n\t\tthis.subscribeStates(`${this.namespace}.${TIMER_CHANNEL}.*`);\n\t\tthis.subscribeStates(`${this.namespace}.${SCHEDULE_CHANNEL}.*`);\n\n\t\tthis.scheduleTick = this.setInterval(() => {\n\t\t\tvoid this.publishScheduleRuntime();\n\t\t}, 30_000);\n\n\t\tthis.log.info(\"Autism Support adapter ready \u2013 Visual Countdown + Weekly Schedule\");\n\t}\n\n\tprivate getDefaultDurationSeconds(maxHours: number): number {\n\t\tconst hours = Math.min(maxHours, Math.max(0, this.config.defaultDurationHours ?? 1));\n\t\tconst minutes = Math.min(59, Math.max(0, this.config.defaultDurationMinutes ?? 0));\n\t\tconst total = hours * 3600 + minutes * 60;\n\t\treturn Math.max(60, Math.min(maxHours * 3600, total));\n\t}\n\n\tprivate async createTimerStates(): Promise<void> {\n\t\tconst states: Record<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\ttype: \"number\" | \"boolean\";\n\t\t\t\trole: string;\n\t\t\t\tname: string;\n\t\t\t\tread: boolean;\n\t\t\t\twrite: boolean;\n\t\t\t\tunit?: string;\n\t\t\t\tmin?: number;\n\t\t\t\tmax?: number;\n\t\t\t}\n\t\t> = {\n\t\t\tduration: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"timer\",\n\t\t\t\tname: \"Timer duration (seconds)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tunit: \"s\",\n\t\t\t\tmin: 60,\n\t\t\t\tmax: 86400,\n\t\t\t},\n\t\t\tremaining: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"timer\",\n\t\t\t\tname: \"Timer remaining (seconds)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tunit: \"s\",\n\t\t\t},\n\t\t\telapsed: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"timer\",\n\t\t\t\tname: \"Timer elapsed (seconds)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tunit: \"s\",\n\t\t\t},\n\t\t\trunning: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"indicator\",\n\t\t\t\tname: \"Timer running\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tpaused: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"indicator\",\n\t\t\t\tname: \"Timer paused\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tfinished: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"indicator\",\n\t\t\t\tname: \"Timer finished\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tstart: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.start\",\n\t\t\t\tname: \"Start timer\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tpause: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.pause\",\n\t\t\t\tname: \"Pause timer\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tresume: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.start\",\n\t\t\t\tname: \"Resume timer\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tstop: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.stop\",\n\t\t\t\tname: \"Stop timer\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tsetDurationHours: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"level\",\n\t\t\t\tname: \"Set timer duration (hours)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tunit: \"h\",\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 24,\n\t\t\t},\n\t\t\tsetDurationMinutes: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"level\",\n\t\t\t\tname: \"Set timer duration (minutes)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tunit: \"min\",\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 59,\n\t\t\t},\n\t\t};\n\n\t\tfor (const [id, def] of Object.entries(states)) {\n\t\t\tawait this.setObjectNotExistsAsync(`${TIMER_CHANNEL}.${id}`, {\n\t\t\t\ttype: \"state\",\n\t\t\t\tcommon: {\n\t\t\t\t\tname: def.name,\n\t\t\t\t\ttype: def.type,\n\t\t\t\t\trole: def.role,\n\t\t\t\t\tread: def.read,\n\t\t\t\t\twrite: def.write,\n\t\t\t\t\tunit: def.unit,\n\t\t\t\t\tmin: def.min,\n\t\t\t\t\tmax: def.max,\n\t\t\t\t},\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async createScheduleStates(): Promise<void> {\n\t\tawait this.setObjectNotExistsAsync(SCHEDULE_CHANNEL, {\n\t\t\ttype: \"channel\",\n\t\t\tcommon: { name: \"Daily schedule\" },\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.plan`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Schedule plan (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: JSON.stringify({ version: 1, items: [] }),\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.periods`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Day periods from admin (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.periodOverrides`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Day period on/off overrides from schedule config (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: \"{}\",\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.nowMinutes`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Minutes since midnight (local)\",\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tunit: \"min\",\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 1439,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.currentPeriod`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Current day period id\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"text\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.currentItemIndex`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Index of active schedule item (-1 = none)\",\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tmin: -1,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.clearAfterLast`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Clear plan automatically after last pictogram ends\",\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"switch\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.pictogramLibrary`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Custom pictogram library (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.weeklyPlan`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Active weekly plan (JSON, Mon\u2013Sun)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: JSON.stringify(createEmptyWeeklyPlan()),\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Saved weekly plans library (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: JSON.stringify({ version: 1, activeId: null, plans: [] }),\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Load daily plan from active weekly plan each day\",\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"switch\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.weekdayColors`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Weekday background colors from admin (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tconst planState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.plan`);\n\t\tif (planState?.val == null || planState.val === \"\") {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify({ version: 1, items: [] }), true);\n\t\t}\n\t\tconst overridesState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.periodOverrides`);\n\t\tif (overridesState?.val == null || overridesState.val === \"\") {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periodOverrides`, \"{}\", true);\n\t\t}\n\t\tconst clearAfterState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.clearAfterLast`);\n\t\tif (clearAfterState?.val == null) {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.clearAfterLast`, false, true);\n\t\t}\n\t\tconst loadDailyState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`);\n\t\tif (loadDailyState?.val == null) {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`, false, true);\n\t\t}\n\n\t\tconst weeklyState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlan`);\n\t\tif (weeklyState?.val == null || weeklyState.val === \"\") {\n\t\t\tconst seed = parseSchedulePlan(planState?.val);\n\t\t\tawait this.setState(\n\t\t\t\t`${SCHEDULE_CHANNEL}.weeklyPlan`,\n\t\t\t\tJSON.stringify(createEmptyWeeklyPlan(seed.items.length ? seed : undefined)),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t}\n\t\tconst libraryState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`);\n\t\tif (libraryState?.val == null || libraryState.val === \"\") {\n\t\t\tawait this.setState(\n\t\t\t\t`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`,\n\t\t\t\tJSON.stringify({ version: 1, activeId: null, plans: [] }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t}\n\n\t\t// Publish admin period definitions once at start (times/colors); overrides stay separate.\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periods`, JSON.stringify(this.dayPeriods), true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weekdayColors`, JSON.stringify(this.weekdayColors), true);\n\t\tawait this.publishPictogramLibrary();\n\t}\n\n\tprivate async buildCustomPictogramRows(): Promise<Array<{ file: string; label: string; tags: string }>> {\n\t\tconst files = await this.listPictogramFiles();\n\t\treturn syncCustomPictogramRows(files || [], this.config.customPictograms);\n\t}\n\n\tprivate async syncCustomPictogramsConfig(): Promise<void> {\n\t\tconst rows = await this.buildCustomPictogramRows();\n\t\tawait this.extendObject(`system.adapter.${this.namespace}`, {\n\t\t\tnative: { customPictograms: rows },\n\t\t});\n\t\tthis.config.customPictograms = rows;\n\t\tawait this.publishPictogramLibrary();\n\t}\n\n\tprivate async ensurePictogramStore(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.readFileAsync(this.namespace, ADAPTER_LIBRARY_FILE);\n\t\t} catch {\n\t\t\ttry {\n\t\t\t\tawait this.writeFileAsync(\n\t\t\t\t\tthis.namespace,\n\t\t\t\t\tADAPTER_LIBRARY_FILE,\n\t\t\t\t\tJSON.stringify(emptyLibrary(), null, 2),\n\t\t\t\t);\n\t\t\t\tthis.log.info(`Created adapter pictogram library ${this.namespace}/${ADAPTER_LIBRARY_FILE}`);\n\t\t\t} catch (error) {\n\t\t\t\tthis.log.error(`Could not create adapter pictogram library: ${(error as Error).message}`);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst legacy = await this.readFileAsync(PICTOGRAM_FILE_ADAPTER, LEGACY_VIS_LIBRARY_FILE);\n\t\t\tconst raw = typeof legacy.file === \"string\" ? legacy.file : Buffer.from(legacy.file).toString(\"utf8\");\n\t\t\tconst migrated = parseLibrary(raw);\n\t\t\tif (migrated.items.length) {\n\t\t\t\tawait this.writeFileAsync(this.namespace, ADAPTER_LIBRARY_FILE, JSON.stringify(migrated, null, 2));\n\t\t\t\tthis.log.info(`Migrated pictogram library from vis-2 to ${this.namespace}`);\n\t\t\t}\n\t\t} catch {\n\t\t\t// no legacy library in vis-2\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.unlinkAsync(PICTOGRAM_FILE_ADAPTER, LEGACY_VIS_LIBRARY_FILE);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\n\t\ttry {\n\t\t\tconst hint =\n\t\t\t\t\"Piktogramm-Bilder (PNG, JPEG, GIF, WebP, SVG) hier hochladen.\\n\" +\n\t\t\t\t\"Keine neuen Ordner anlegen (Dateimanager zeigt dann oft \u201Edoppelter Name\u201C).\\n\" +\n\t\t\t\t\"Stattdessen oben auf Hochladen klicken und Bilder in DIESEN Ordner legen.\\n\";\n\t\t\tawait this.writeFileAsync(PICTOGRAM_FILE_ADAPTER, `${PICTOGRAM_DIR}/${PICTOGRAM_PLACEHOLDER_FILE}`, hint);\n\t\t\tthis.log.info(`Ensured vis-2 pictogram folder ${PICTOGRAM_FILE_ADAPTER}/${PICTOGRAM_DIR}`);\n\t\t} catch (error) {\n\t\t\tthis.log.error(\n\t\t\t\t`Could not write ${PICTOGRAM_FILE_ADAPTER}/${PICTOGRAM_DIR}/${PICTOGRAM_PLACEHOLDER_FILE}: ${(error as Error).message}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async getPublishedPictogramLibrary(): Promise<PictogramLibrary> {\n\t\treturn mergePictogramSources(\n\t\t\tawait this.getMergedPictogramLibrary(),\n\t\t\tlibraryFromNativeRows(this.config.customPictograms),\n\t\t);\n\t}\n\n\tprivate async publishPictogramLibrary(): Promise<void> {\n\t\tconst library = await this.getPublishedPictogramLibrary();\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.pictogramLibrary`, JSON.stringify(library), true);\n\t}\n\n\tprivate async publishTimerSnapshot(snapshot: {\n\t\tduration: number;\n\t\tremaining: number;\n\t\telapsed: number;\n\t\trunning: boolean;\n\t\tpaused: boolean;\n\t\tfinished: boolean;\n\t}): Promise<void> {\n\t\tawait this.setState(`${TIMER_CHANNEL}.duration`, snapshot.duration, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.remaining`, snapshot.remaining, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.elapsed`, snapshot.elapsed, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.running`, snapshot.running, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.paused`, snapshot.paused, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.finished`, snapshot.finished, true);\n\t}\n\n\tprivate async getPlan(): Promise<SchedulePlan> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.plan`);\n\t\treturn parseSchedulePlan(state?.val);\n\t}\n\n\tprivate async getPeriodOverrides(): Promise<Record<string, boolean>> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.periodOverrides`);\n\t\ttry {\n\t\t\tconst raw = typeof state?.val === \"string\" ? JSON.parse(state.val) : state?.val;\n\t\t\treturn raw && typeof raw === \"object\" ? (raw as Record<string, boolean>) : {};\n\t\t} catch {\n\t\t\treturn {};\n\t\t}\n\t}\n\n\tprivate async getEffectivePeriods(): Promise<DayPeriodDefinition[]> {\n\t\tconst overrides = await this.getPeriodOverrides();\n\t\treturn this.dayPeriods.map(period => ({\n\t\t\t...period,\n\t\t\tenabled: overrides[period.id] === undefined ? period.enabled : Boolean(overrides[period.id]),\n\t\t}));\n\t}\n\n\tprivate async getWeeklyPlan(): Promise<WeeklyPlanData> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlan`);\n\t\treturn parseWeeklyPlan(state?.val);\n\t}\n\n\tprivate async getWeeklyPlansLibrary(): Promise<WeeklyPlansLibrary> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`);\n\t\treturn parseWeeklyPlansLibrary(state?.val);\n\t}\n\n\tprivate async syncWeeklyPlansTableToNative(): Promise<void> {\n\t\tconst library = await this.getWeeklyPlansLibrary();\n\t\tconst rows = weeklyPlanRowsFromLibrary(library);\n\t\tawait this.extendObject(`system.adapter.${this.namespace}`, {\n\t\t\tnative: { weeklyPlanRows: rows },\n\t\t});\n\t\tthis.config.weeklyPlanRows = rows;\n\t}\n\n\tprivate async applyWeeklyPlanRowsFromConfig(): Promise<void> {\n\t\tconst library = await this.getWeeklyPlansLibrary();\n\t\tconst next = applyWeeklyPlanRowsToLibrary(library, this.config.weeklyPlanRows);\n\t\tif (JSON.stringify(next) !== JSON.stringify(library)) {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`, JSON.stringify(next), true);\n\t\t}\n\t}\n\n\tprivate async maybeApplyWeeklyToDaily(): Promise<void> {\n\t\tconst loadState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`);\n\t\tif (!loadState?.val) {\n\t\t\treturn;\n\t\t}\n\t\tconst weekday = weekdayKeyFromDate(new Date());\n\t\tconst weekly = await this.getWeeklyPlan();\n\t\tconst dayPlan = weekly.days[weekday];\n\t\tconst current = await this.getPlan();\n\t\tif (this.lastAppliedWeekday === weekday && schedulePlansEqual(current, dayPlan)) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify(dayPlan), true);\n\t\tthis.lastAppliedWeekday = weekday;\n\t\tthis.log.debug(`Daily plan loaded from weekly plan (${weekday})`);\n\t}\n\n\tprivate async publishScheduleRuntime(): Promise<void> {\n\t\tawait this.maybeApplyWeeklyToDaily();\n\n\t\tconst now = new Date();\n\t\tconst minutes = now.getHours() * 60 + now.getMinutes();\n\t\tconst periods = await this.getEffectivePeriods();\n\t\tconst period = findCurrentPeriod(minutes, periods);\n\t\tlet plan = await this.getPlan();\n\n\t\tconst clearAfterState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.clearAfterLast`);\n\t\tconst clearAfterLast = Boolean(clearAfterState?.val);\n\t\tif (clearAfterLast && isPlanFullyExpired(plan, minutes, parseTimeToMinutes)) {\n\t\t\tplan = { version: 1, items: [] };\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify(plan), true);\n\t\t\tthis.log.info(\"Schedule plan cleared automatically after last pictogram ended\");\n\t\t}\n\n\t\tconst itemIndex = findCurrentItemIndex(plan, minutes, parseTimeToMinutes);\n\n\t\t// Keep admin period metadata available; do not wipe Config overrides.\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periods`, JSON.stringify(this.dayPeriods), true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weekdayColors`, JSON.stringify(this.weekdayColors), true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.nowMinutes`, minutes, true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.currentPeriod`, period?.id ?? \"\", true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.currentItemIndex`, itemIndex, true);\n\t}\n\n\tprivate async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise<void> {\n\t\tif (!state || state.ack) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (id.startsWith(`${this.namespace}.${SCHEDULE_CHANNEL}.`)) {\n\t\t\tconst localId = id.replace(`${this.namespace}.${SCHEDULE_CHANNEL}.`, \"\");\n\t\t\tif (localId === \"plan\") {\n\t\t\t\tconst plan = parseSchedulePlan(state.val);\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify(plan), true);\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t} else if (localId === \"periodOverrides\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst raw = typeof state.val === \"string\" ? JSON.parse(String(state.val)) : state.val;\n\t\t\t\t\tconst cleaned = raw && typeof raw === \"object\" ? (raw as Record<string, boolean>) : {};\n\t\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periodOverrides`, JSON.stringify(cleaned), true);\n\t\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.log.error(`Invalid periodOverrides: ${(error as Error).message}`);\n\t\t\t\t}\n\t\t\t} else if (localId === \"clearAfterLast\") {\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.clearAfterLast`, Boolean(state.val), true);\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t} else if (localId === \"weeklyPlan\") {\n\t\t\t\tconst weekly = parseWeeklyPlan(state.val);\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weeklyPlan`, JSON.stringify(weekly), true);\n\t\t\t\tthis.lastAppliedWeekday = null;\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t} else if (localId === \"weeklyPlansLibrary\") {\n\t\t\t\tconst library = parseWeeklyPlansLibrary(state.val);\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`, JSON.stringify(library), true);\n\t\t\t\tawait this.syncWeeklyPlansTableToNative();\n\t\t\t} else if (localId === \"loadDailyFromWeekly\") {\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`, Boolean(state.val), true);\n\t\t\t\tthis.lastAppliedWeekday = null;\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.timerManager || !id.startsWith(`${this.namespace}.${TIMER_CHANNEL}.`)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst localId = id.replace(`${this.namespace}.${TIMER_CHANNEL}.`, \"\");\n\t\tconst maxHours = this.config.maxDurationHours ?? 24;\n\n\t\ttry {\n\t\t\tswitch (localId) {\n\t\t\t\tcase \"start\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.start();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.start`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"pause\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.pause();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.pause`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"resume\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.resume();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.resume`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"stop\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.stop();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.stop`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"duration\":\n\t\t\t\t\tif (typeof state.val === \"number\") {\n\t\t\t\t\t\tawait this.timerManager.setDuration(state.val, maxHours);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"setDurationHours\":\n\t\t\t\t\tif (typeof state.val === \"number\") {\n\t\t\t\t\t\tawait this.applyDurationParts(Math.round(state.val), undefined, maxHours);\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.setDurationHours`, 0, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"setDurationMinutes\":\n\t\t\t\t\tif (typeof state.val === \"number\") {\n\t\t\t\t\t\tawait this.applyDurationParts(undefined, Math.round(state.val), maxHours);\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.setDurationMinutes`, 0, true);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.log.error(`Timer command failed (${localId}): ${(error as Error).message}`);\n\t\t}\n\t}\n\n\tprivate reply(obj: ioBroker.Message, payload: unknown): void {\n\t\tif (obj.callback) {\n\t\t\tthis.sendTo(obj.from, obj.command, payload, obj.callback);\n\t\t}\n\t}\n\n\tprivate async loadPictogramLibrary(): Promise<PictogramLibrary> {\n\t\ttry {\n\t\t\tconst file = await this.readFileAsync(this.namespace, ADAPTER_LIBRARY_FILE);\n\t\t\tconst raw = typeof file.file === \"string\" ? file.file : Buffer.from(file.file).toString(\"utf8\");\n\t\t\treturn parseLibrary(raw);\n\t\t} catch {\n\t\t\treturn emptyLibrary();\n\t\t}\n\t}\n\n\tprivate async savePictogramLibrary(library: PictogramLibrary): Promise<void> {\n\t\tawait this.writeFileAsync(this.namespace, ADAPTER_LIBRARY_FILE, JSON.stringify(library, null, 2));\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.pictogramLibrary`, JSON.stringify(library), true);\n\t}\n\n\tprivate async listPictogramFiles(): Promise<string[] | null> {\n\t\ttry {\n\t\t\tconst result = await this.readDirAsync(PICTOGRAM_FILE_ADAPTER, PICTOGRAM_DIR);\n\t\t\treturn (result || [])\n\t\t\t\t.filter(entry => !entry.isDir && !isIgnoredPictogramFile(entry.file))\n\t\t\t\t.map(entry => entry.file);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate async getMergedPictogramLibrary(): Promise<PictogramLibrary> {\n\t\tconst library = await this.loadPictogramLibrary();\n\t\tconst files = await this.listPictogramFiles();\n\t\tif (!files) {\n\t\t\treturn library;\n\t\t}\n\t\tconst known = new Set(library.items.map(item => item.filename));\n\t\tfor (const filename of files) {\n\t\t\tif (known.has(filename)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlibrary.items.push({\n\t\t\t\tid: filename,\n\t\t\t\tfilename,\n\t\t\t\tpath: pictogramStoragePath(filename),\n\t\t\t\tlabel: filename.replace(/\\.[^.]+$/, \"\").replace(/-\\d+$/, \"\"),\n\t\t\t\ttags: [],\n\t\t\t\toriginalName: filename,\n\t\t\t\tmime: \"\",\n\t\t\t\tuploadedAt: 0,\n\t\t\t});\n\t\t}\n\t\tlibrary.items = library.items.filter(item => files.includes(item.filename));\n\t\tlibrary.items.sort((a, b) => (b.uploadedAt || 0) - (a.uploadedAt || 0));\n\t\treturn library;\n\t}\n\n\t/**\n\t * Custom pictogram library (user-owned images only).\n\t * ARASAAC images must never be uploaded here \u2013 use external IDs only.\n\t *\n\t * @param obj\n\t */\n\tprivate async onMessage(obj: ioBroker.Message): Promise<void> {\n\t\tif (!obj?.command) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tif (obj.command === \"syncPictogramTable\") {\n\t\t\t\tawait this.ensurePictogramStore();\n\t\t\t\tconst rows = await this.buildCustomPictogramRows();\n\t\t\t\tawait this.extendObject(`system.adapter.${this.namespace}`, {\n\t\t\t\t\tnative: { customPictograms: rows },\n\t\t\t\t});\n\t\t\t\tthis.config.customPictograms = rows;\n\t\t\t\tawait this.publishPictogramLibrary();\n\t\t\t\tthis.reply(obj, { ok: true, native: { customPictograms: rows } });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"syncWeeklyPlansTable\") {\n\t\t\t\tconst nativeMsg = obj.message as {\n\t\t\t\t\tweeklyPlanRows?: Array<{ id?: string; name?: string; active?: string }>;\n\t\t\t\t};\n\t\t\t\tif (Array.isArray(nativeMsg?.weeklyPlanRows)) {\n\t\t\t\t\tthis.config.weeklyPlanRows = nativeMsg.weeklyPlanRows;\n\t\t\t\t\tawait this.applyWeeklyPlanRowsFromConfig();\n\t\t\t\t}\n\t\t\t\tawait this.syncWeeklyPlansTableToNative();\n\t\t\t\tconst library = await this.getWeeklyPlansLibrary();\n\t\t\t\tthis.reply(obj, {\n\t\t\t\t\tok: true,\n\t\t\t\t\tnative: { weeklyPlanRows: this.config.weeklyPlanRows || [] },\n\t\t\t\t\tactiveId: library.activeId,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"uploadPictogram\") {\n\t\t\t\tconst payload = obj.message as {\n\t\t\t\t\tfilename?: string;\n\t\t\t\t\tbase64?: string;\n\t\t\t\t\tmime?: string;\n\t\t\t\t\tlabel?: string;\n\t\t\t\t\ttags?: string[] | string;\n\t\t\t\t};\n\t\t\t\tconst originalName = String(payload?.filename || \"image.png\");\n\t\t\t\tconst filename = uniquePictogramFilename(originalName);\n\t\t\t\tconst base64 = String(payload?.base64 || \"\");\n\t\t\t\tif (!base64) {\n\t\t\t\t\tthrow new Error(\"filename and base64 required\");\n\t\t\t\t}\n\t\t\t\tif (!/\\.(png|jpe?g|gif|webp|svg)$/i.test(filename)) {\n\t\t\t\t\tthrow new Error(\"unsupported file type\");\n\t\t\t\t}\n\t\t\t\tconst buffer = Buffer.from(base64.replace(/^data:[^;]+;base64,/, \"\"), \"base64\");\n\t\t\t\tif (!buffer.length) {\n\t\t\t\t\tthrow new Error(\"empty file\");\n\t\t\t\t}\n\t\t\t\tif (buffer.length > 5 * 1024 * 1024) {\n\t\t\t\t\tthrow new Error(\"file too large (max 5 MB)\");\n\t\t\t\t}\n\t\t\t\tconst path = pictogramStoragePath(filename);\n\t\t\t\tawait this.writeFileAsync(PICTOGRAM_FILE_ADAPTER, path, buffer);\n\t\t\t\tconst library = await this.getMergedPictogramLibrary();\n\t\t\t\tconst entry: CustomPictogram = {\n\t\t\t\t\tid: filename,\n\t\t\t\t\tfilename,\n\t\t\t\t\tpath,\n\t\t\t\t\tlabel: String(payload?.label || originalName.replace(/\\.[^.]+$/, \"\")),\n\t\t\t\t\ttags: normalizeTags(payload?.tags),\n\t\t\t\t\toriginalName,\n\t\t\t\t\tmime: String(payload?.mime || \"\"),\n\t\t\t\t\tuploadedAt: Date.now(),\n\t\t\t\t};\n\t\t\t\tlibrary.items = [entry, ...library.items.filter(item => item.filename !== filename)];\n\t\t\t\tawait this.savePictogramLibrary(library);\n\t\t\t\tawait this.syncCustomPictogramsConfig();\n\t\t\t\tthis.log.info(`Custom pictogram stored: ${PICTOGRAM_FILE_ADAPTER}/${path} (${buffer.length} bytes)`);\n\t\t\t\tthis.reply(obj, {\n\t\t\t\t\tok: true,\n\t\t\t\t\tpath,\n\t\t\t\t\turl: pictogramPublicUrl(path),\n\t\t\t\t\titem: entry,\n\t\t\t\t\tlibrary,\n\t\t\t\t\tadapter: PICTOGRAM_FILE_ADAPTER,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"listPictograms\") {\n\t\t\t\tconst library = await this.getPublishedPictogramLibrary();\n\t\t\t\tthis.reply(obj, {\n\t\t\t\t\tok: true,\n\t\t\t\t\tfiles: library.items.map(item => item.filename),\n\t\t\t\t\tlibrary,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"updatePictogram\") {\n\t\t\t\tconst payload = obj.message as {\n\t\t\t\t\tpath?: string;\n\t\t\t\t\tfilename?: string;\n\t\t\t\t\tlabel?: string;\n\t\t\t\t\ttags?: string[] | string;\n\t\t\t\t};\n\t\t\t\tconst key = String(payload?.path || payload?.filename || \"\");\n\t\t\t\tif (!key) {\n\t\t\t\t\tthrow new Error(\"path required\");\n\t\t\t\t}\n\t\t\t\tconst library = await this.getMergedPictogramLibrary();\n\t\t\t\tconst item = library.items.find(entry => matchesPictogramKey(entry, key));\n\t\t\t\tif (!item) {\n\t\t\t\t\tthrow new Error(\"pictogram not found\");\n\t\t\t\t}\n\t\t\t\tif (payload.label !== undefined) {\n\t\t\t\t\titem.label = String(payload.label);\n\t\t\t\t}\n\t\t\t\tif (payload.tags !== undefined) {\n\t\t\t\t\titem.tags = normalizeTags(payload.tags);\n\t\t\t\t}\n\t\t\t\tawait this.savePictogramLibrary(library);\n\t\t\t\tthis.reply(obj, { ok: true, item, library });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"deletePictogram\") {\n\t\t\t\tconst payload = obj.message as { path?: string; filename?: string };\n\t\t\t\tconst key = String(payload?.path || payload?.filename || \"\");\n\t\t\t\tif (!key) {\n\t\t\t\t\tthrow new Error(\"path required\");\n\t\t\t\t}\n\t\t\t\tconst library = await this.getMergedPictogramLibrary();\n\t\t\t\tconst item = library.items.find(entry => matchesPictogramKey(entry, key));\n\t\t\t\tif (!item) {\n\t\t\t\t\tthrow new Error(\"pictogram not found\");\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait this.unlinkAsync(PICTOGRAM_FILE_ADAPTER, item.path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.log.warn(`Could not delete pictogram file ${item.path}: ${(error as Error).message}`);\n\t\t\t\t}\n\t\t\t\tlibrary.items = library.items.filter(entry => entry.filename !== item.filename);\n\t\t\t\tawait this.savePictogramLibrary(library);\n\t\t\t\tthis.reply(obj, { ok: true, library });\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.log.error(`Pictogram command ${obj.command} failed: ${(error as Error).message}`);\n\t\t\tthis.reply(obj, { ok: false, error: (error as Error).message });\n\t\t}\n\t}\n\n\tprivate async applyDurationParts(\n\t\thours: number | undefined,\n\t\tminutes: number | undefined,\n\t\tmaxHours: number,\n\t): Promise<void> {\n\t\tif (!this.timerManager) {\n\t\t\treturn;\n\t\t}\n\t\tconst snapshot = this.timerManager.getSnapshot();\n\t\tconst current = secondsToParts(snapshot.duration);\n\t\tconst nextHours = hours ?? current.hours;\n\t\tconst nextMinutes = minutes ?? current.minutes;\n\t\tconst totalSeconds = nextHours * 3600 + nextMinutes * 60;\n\t\tawait this.timerManager.setDuration(totalSeconds, maxHours);\n\t}\n\n\tprivate onUnload(callback: () => void): void {\n\t\tif (this.scheduleTick !== undefined && this.scheduleTick !== null) {\n\t\t\tthis.clearInterval(this.scheduleTick);\n\t\t\tthis.scheduleTick = null;\n\t\t}\n\t\tthis.timerManager?.destroy();\n\t\tthis.timerManager = null;\n\t\tcallback();\n\t}\n}\n\nif (require.main !== module) {\n\tmodule.exports = (options: Partial<utils.AdapterOptions> | undefined) => new AutismSupport(options);\n} else {\n\t(() => new AutismSupport())();\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/*\n * ioBroker.autism-support \u2013 Visual Countdown + Daily Schedule\n */\n\nimport * as utils from \"@iobroker/adapter-core\";\nimport { TimerManager } from \"./lib/timer-manager\";\nimport {\n\tdayPeriodsFromConfig,\n\tfindCurrentPeriod,\n\tparseTimeToMinutes,\n\ttype DayPeriodDefinition,\n} from \"./lib/day-periods\";\nimport { findCurrentItemIndex, isPlanFullyExpired, parseSchedulePlan, type SchedulePlan } from \"./lib/schedule-types\";\nimport {\n\tADAPTER_LIBRARY_FILE,\n\tPICTOGRAM_DIR,\n\tPICTOGRAM_FILE_ADAPTER,\n\tPICTOGRAM_PLACEHOLDER_FILE,\n\tLEGACY_VIS_LIBRARY_FILE,\n\temptyLibrary,\n\tisIgnoredPictogramFile,\n\tlibraryFromNativeRows,\n\tmatchesPictogramKey,\n\tmergePictogramSources,\n\tnormalizeTags,\n\tparseLibrary,\n\tpictogramPublicUrl,\n\tpictogramStoragePath,\n\tsyncCustomPictogramRows,\n\tuniquePictogramFilename,\n\ttype CustomPictogram,\n\ttype PictogramLibrary,\n} from \"./lib/pictogram-library\";\nimport {\n\tapplyWeeklyPlanRowsToLibrary,\n\tcreateEmptyWeeklyPlan,\n\tparseWeeklyPlan,\n\tparseWeeklyPlansLibrary,\n\tschedulePlansEqual,\n\tweekdayColorsFromConfig,\n\tweekdayKeyFromDate,\n\tweeklyPlanRowsFromLibrary,\n\ttype WeekdayColors,\n\ttype WeekdayKey,\n\ttype WeeklyPlanData,\n\ttype WeeklyPlansLibrary,\n} from \"./lib/weekly-plan\";\n\nconst TIMER_CHANNEL = \"timer\";\nconst SCHEDULE_CHANNEL = \"schedule\";\n\nfunction secondsToParts(totalSeconds: number): { hours: number; minutes: number } {\n\tconst safe = Math.max(0, Math.round(totalSeconds));\n\treturn {\n\t\thours: Math.floor(safe / 3600),\n\t\tminutes: Math.floor((safe % 3600) / 60),\n\t};\n}\n\nclass AutismSupport extends utils.Adapter {\n\tprivate timerManager: TimerManager | null = null;\n\tprivate scheduleTick: ioBroker.Interval | undefined | null = null;\n\tprivate dayPeriods: DayPeriodDefinition[] = [];\n\tprivate weekdayColors: WeekdayColors = weekdayColorsFromConfig({} as ioBroker.AdapterConfig);\n\tprivate lastAppliedWeekday: WeekdayKey | null = null;\n\n\tpublic constructor(options: Partial<utils.AdapterOptions> = {}) {\n\t\tsuper({\n\t\t\t...options,\n\t\t\tname: \"autism-support\",\n\t\t});\n\t\tthis.on(\"ready\", this.onReady.bind(this));\n\t\tthis.on(\"stateChange\", this.onStateChange.bind(this));\n\t\tthis.on(\"message\", this.onMessage.bind(this));\n\t\tthis.on(\"unload\", this.onUnload.bind(this));\n\t}\n\n\tprivate async onReady(): Promise<void> {\n\t\tconst maxHours = this.config.maxDurationHours ?? 24;\n\t\tconst defaultSeconds = this.getDefaultDurationSeconds(maxHours);\n\t\tthis.dayPeriods = dayPeriodsFromConfig(this.config);\n\t\tthis.weekdayColors = weekdayColorsFromConfig(this.config);\n\n\t\tawait this.createTimerStates();\n\t\tawait this.ensurePictogramStore();\n\t\tawait this.syncCustomPictogramsConfig();\n\t\tawait this.createScheduleStates();\n\t\t// Only apply Admin name/delete edits when the table already lists plans (avoid wiping on first boot).\n\t\tif (Array.isArray(this.config.weeklyPlanRows) && this.config.weeklyPlanRows.length > 0) {\n\t\t\tawait this.applyWeeklyPlanRowsFromConfig();\n\t\t}\n\t\tawait this.syncWeeklyPlansTableToNative();\n\n\t\tthis.timerManager = new TimerManager(\n\t\t\tasync snapshot => {\n\t\t\t\tawait this.publishTimerSnapshot(snapshot);\n\t\t\t},\n\t\t\t{\n\t\t\t\tsetInterval: (handler, ms) => this.setInterval(handler, ms),\n\t\t\t\tclearInterval: handle => this.clearInterval(handle as ioBroker.Interval),\n\t\t\t},\n\t\t);\n\n\t\tawait this.timerManager.setDuration(defaultSeconds, maxHours);\n\t\tawait this.publishTimerSnapshot(this.timerManager.getSnapshot());\n\t\tawait this.publishScheduleRuntime();\n\n\t\tthis.subscribeStates(`${this.namespace}.${TIMER_CHANNEL}.*`);\n\t\tthis.subscribeStates(`${this.namespace}.${SCHEDULE_CHANNEL}.*`);\n\n\t\tthis.scheduleTick = this.setInterval(() => {\n\t\t\tvoid this.publishScheduleRuntime();\n\t\t}, 30_000);\n\n\t\tthis.log.info(\"Autism Support adapter ready \u2013 Visual Countdown + Weekly Schedule\");\n\t}\n\n\tprivate getDefaultDurationSeconds(maxHours: number): number {\n\t\tconst hours = Math.min(maxHours, Math.max(0, this.config.defaultDurationHours ?? 1));\n\t\tconst minutes = Math.min(59, Math.max(0, this.config.defaultDurationMinutes ?? 0));\n\t\tconst total = hours * 3600 + minutes * 60;\n\t\treturn Math.max(60, Math.min(maxHours * 3600, total));\n\t}\n\n\tprivate async createTimerStates(): Promise<void> {\n\t\tawait this.setObjectNotExistsAsync(TIMER_CHANNEL, {\n\t\t\ttype: \"channel\",\n\t\t\tcommon: { name: \"Visual Countdown\" },\n\t\t\tnative: {},\n\t\t});\n\n\t\tconst states: Record<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\ttype: \"number\" | \"boolean\";\n\t\t\t\trole: string;\n\t\t\t\tname: string;\n\t\t\t\tread: boolean;\n\t\t\t\twrite: boolean;\n\t\t\t\tunit?: string;\n\t\t\t\tmin?: number;\n\t\t\t\tmax?: number;\n\t\t\t}\n\t\t> = {\n\t\t\tduration: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value.interval\",\n\t\t\t\tname: \"Timer duration (seconds)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tunit: \"s\",\n\t\t\t\tmin: 60,\n\t\t\t\tmax: 86400,\n\t\t\t},\n\t\t\tremaining: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value.interval\",\n\t\t\t\tname: \"Timer remaining (seconds)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tunit: \"s\",\n\t\t\t},\n\t\t\telapsed: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value.interval\",\n\t\t\t\tname: \"Timer elapsed (seconds)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tunit: \"s\",\n\t\t\t},\n\t\t\trunning: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"indicator\",\n\t\t\t\tname: \"Timer running\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tpaused: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"indicator\",\n\t\t\t\tname: \"Timer paused\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tfinished: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"indicator\",\n\t\t\t\tname: \"Timer finished\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tstart: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.start\",\n\t\t\t\tname: \"Start timer\",\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tpause: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.pause\",\n\t\t\t\tname: \"Pause timer\",\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tresume: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.start\",\n\t\t\t\tname: \"Resume timer\",\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tstop: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.stop\",\n\t\t\t\tname: \"Stop timer\",\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tsetDurationHours: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"level\",\n\t\t\t\tname: \"Set timer duration (hours)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tunit: \"h\",\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 24,\n\t\t\t},\n\t\t\tsetDurationMinutes: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"level\",\n\t\t\t\tname: \"Set timer duration (minutes)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tunit: \"min\",\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 59,\n\t\t\t},\n\t\t};\n\n\t\tfor (const [id, def] of Object.entries(states)) {\n\t\t\tawait this.setObjectNotExistsAsync(`${TIMER_CHANNEL}.${id}`, {\n\t\t\t\ttype: \"state\",\n\t\t\t\tcommon: {\n\t\t\t\t\tname: def.name,\n\t\t\t\t\ttype: def.type,\n\t\t\t\t\trole: def.role,\n\t\t\t\t\tread: def.read,\n\t\t\t\t\twrite: def.write,\n\t\t\t\t\tunit: def.unit,\n\t\t\t\t\tmin: def.min,\n\t\t\t\t\tmax: def.max,\n\t\t\t\t},\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t}\n\n\t\tawait this.migrateTimerStateRoles();\n\t}\n\n\t/** Update roles/read flags on existing timer states (object-structure compliance). */\n\tprivate async migrateTimerStateRoles(): Promise<void> {\n\t\tconst patches: Record<string, { role?: string; read?: boolean }> = {\n\t\t\tduration: { role: \"value.interval\" },\n\t\t\tremaining: { role: \"value.interval\" },\n\t\t\telapsed: { role: \"value.interval\" },\n\t\t\tstart: { read: false },\n\t\t\tpause: { read: false },\n\t\t\tresume: { read: false },\n\t\t\tstop: { read: false },\n\t\t};\n\t\tfor (const [id, patch] of Object.entries(patches)) {\n\t\t\tconst common: Partial<ioBroker.StateCommon> = {};\n\t\t\tif (patch.role) {\n\t\t\t\tcommon.role = patch.role;\n\t\t\t}\n\t\t\tif (patch.read !== undefined) {\n\t\t\t\tcommon.read = patch.read;\n\t\t\t}\n\t\t\tawait this.extendObjectAsync(`${TIMER_CHANNEL}.${id}`, { common });\n\t\t}\n\t}\n\n\tprivate async createScheduleStates(): Promise<void> {\n\t\tawait this.setObjectNotExistsAsync(SCHEDULE_CHANNEL, {\n\t\t\ttype: \"channel\",\n\t\t\tcommon: { name: \"Daily schedule\" },\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.plan`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Schedule plan (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: JSON.stringify({ version: 1, items: [] }),\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.periods`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Day periods from admin (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.periodOverrides`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Day period on/off overrides from schedule config (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: \"{}\",\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.nowMinutes`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Minutes since midnight (local)\",\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tunit: \"min\",\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 1439,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.currentPeriod`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Current day period id\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"text\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.currentItemIndex`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Index of active schedule item (-1 = none)\",\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tmin: -1,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.clearAfterLast`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Clear plan automatically after last pictogram ends\",\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"switch\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.pictogramLibrary`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Custom pictogram library (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.weeklyPlan`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Active weekly plan (JSON, Mon\u2013Sun)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: JSON.stringify(createEmptyWeeklyPlan()),\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Saved weekly plans library (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: JSON.stringify({ version: 1, activeId: null, plans: [] }),\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Load daily plan from active weekly plan each day\",\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"switch\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.weekdayColors`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Weekday background colors from admin (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tconst planState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.plan`);\n\t\tif (planState?.val == null || planState.val === \"\") {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify({ version: 1, items: [] }), true);\n\t\t}\n\t\tconst overridesState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.periodOverrides`);\n\t\tif (overridesState?.val == null || overridesState.val === \"\") {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periodOverrides`, \"{}\", true);\n\t\t}\n\t\tconst clearAfterState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.clearAfterLast`);\n\t\tif (clearAfterState?.val == null) {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.clearAfterLast`, false, true);\n\t\t}\n\t\tconst loadDailyState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`);\n\t\tif (loadDailyState?.val == null) {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`, false, true);\n\t\t}\n\n\t\tconst weeklyState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlan`);\n\t\tif (weeklyState?.val == null || weeklyState.val === \"\") {\n\t\t\tconst seed = parseSchedulePlan(planState?.val);\n\t\t\tawait this.setState(\n\t\t\t\t`${SCHEDULE_CHANNEL}.weeklyPlan`,\n\t\t\t\tJSON.stringify(createEmptyWeeklyPlan(seed.items.length ? seed : undefined)),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t}\n\t\tconst libraryState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`);\n\t\tif (libraryState?.val == null || libraryState.val === \"\") {\n\t\t\tawait this.setState(\n\t\t\t\t`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`,\n\t\t\t\tJSON.stringify({ version: 1, activeId: null, plans: [] }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t}\n\n\t\t// Publish admin period definitions once at start (times/colors); overrides stay separate.\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periods`, JSON.stringify(this.dayPeriods), true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weekdayColors`, JSON.stringify(this.weekdayColors), true);\n\t\tawait this.publishPictogramLibrary();\n\t}\n\n\tprivate async buildCustomPictogramRows(): Promise<Array<{ file: string; label: string; tags: string }>> {\n\t\tconst files = await this.listPictogramFiles();\n\t\treturn syncCustomPictogramRows(files || [], this.config.customPictograms);\n\t}\n\n\tprivate async syncCustomPictogramsConfig(): Promise<void> {\n\t\tconst rows = await this.buildCustomPictogramRows();\n\t\tawait this.extendObject(`system.adapter.${this.namespace}`, {\n\t\t\tnative: { customPictograms: rows },\n\t\t});\n\t\tthis.config.customPictograms = rows;\n\t\tawait this.publishPictogramLibrary();\n\t}\n\n\tprivate async ensurePictogramStore(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.readFileAsync(this.namespace, ADAPTER_LIBRARY_FILE);\n\t\t} catch {\n\t\t\ttry {\n\t\t\t\tawait this.writeFileAsync(\n\t\t\t\t\tthis.namespace,\n\t\t\t\t\tADAPTER_LIBRARY_FILE,\n\t\t\t\t\tJSON.stringify(emptyLibrary(), null, 2),\n\t\t\t\t);\n\t\t\t\tthis.log.info(`Created adapter pictogram library ${this.namespace}/${ADAPTER_LIBRARY_FILE}`);\n\t\t\t} catch (error) {\n\t\t\t\tthis.log.error(`Could not create adapter pictogram library: ${(error as Error).message}`);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst legacy = await this.readFileAsync(PICTOGRAM_FILE_ADAPTER, LEGACY_VIS_LIBRARY_FILE);\n\t\t\tconst raw = typeof legacy.file === \"string\" ? legacy.file : Buffer.from(legacy.file).toString(\"utf8\");\n\t\t\tconst migrated = parseLibrary(raw);\n\t\t\tif (migrated.items.length) {\n\t\t\t\tawait this.writeFileAsync(this.namespace, ADAPTER_LIBRARY_FILE, JSON.stringify(migrated, null, 2));\n\t\t\t\tthis.log.info(`Migrated pictogram library from vis-2 to ${this.namespace}`);\n\t\t\t}\n\t\t} catch {\n\t\t\t// no legacy library in vis-2\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.unlinkAsync(PICTOGRAM_FILE_ADAPTER, LEGACY_VIS_LIBRARY_FILE);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\n\t\ttry {\n\t\t\tconst hint =\n\t\t\t\t\"Piktogramm-Bilder (PNG, JPEG, GIF, WebP, SVG) hier hochladen.\\n\" +\n\t\t\t\t\"Keine neuen Ordner anlegen (Dateimanager zeigt dann oft \u201Edoppelter Name\u201C).\\n\" +\n\t\t\t\t\"Stattdessen oben auf Hochladen klicken und Bilder in DIESEN Ordner legen.\\n\";\n\t\t\tawait this.writeFileAsync(PICTOGRAM_FILE_ADAPTER, `${PICTOGRAM_DIR}/${PICTOGRAM_PLACEHOLDER_FILE}`, hint);\n\t\t\tthis.log.info(`Ensured vis-2 pictogram folder ${PICTOGRAM_FILE_ADAPTER}/${PICTOGRAM_DIR}`);\n\t\t} catch (error) {\n\t\t\tthis.log.error(\n\t\t\t\t`Could not write ${PICTOGRAM_FILE_ADAPTER}/${PICTOGRAM_DIR}/${PICTOGRAM_PLACEHOLDER_FILE}: ${(error as Error).message}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async getPublishedPictogramLibrary(): Promise<PictogramLibrary> {\n\t\treturn mergePictogramSources(\n\t\t\tawait this.getMergedPictogramLibrary(),\n\t\t\tlibraryFromNativeRows(this.config.customPictograms),\n\t\t);\n\t}\n\n\tprivate async publishPictogramLibrary(): Promise<void> {\n\t\tconst library = await this.getPublishedPictogramLibrary();\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.pictogramLibrary`, JSON.stringify(library), true);\n\t}\n\n\tprivate async publishTimerSnapshot(snapshot: {\n\t\tduration: number;\n\t\tremaining: number;\n\t\telapsed: number;\n\t\trunning: boolean;\n\t\tpaused: boolean;\n\t\tfinished: boolean;\n\t}): Promise<void> {\n\t\tawait this.setState(`${TIMER_CHANNEL}.duration`, snapshot.duration, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.remaining`, snapshot.remaining, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.elapsed`, snapshot.elapsed, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.running`, snapshot.running, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.paused`, snapshot.paused, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.finished`, snapshot.finished, true);\n\t}\n\n\tprivate async getPlan(): Promise<SchedulePlan> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.plan`);\n\t\treturn parseSchedulePlan(state?.val);\n\t}\n\n\tprivate async getPeriodOverrides(): Promise<Record<string, boolean>> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.periodOverrides`);\n\t\ttry {\n\t\t\tconst raw = typeof state?.val === \"string\" ? JSON.parse(state.val) : state?.val;\n\t\t\treturn raw && typeof raw === \"object\" ? (raw as Record<string, boolean>) : {};\n\t\t} catch {\n\t\t\treturn {};\n\t\t}\n\t}\n\n\tprivate async getEffectivePeriods(): Promise<DayPeriodDefinition[]> {\n\t\tconst overrides = await this.getPeriodOverrides();\n\t\treturn this.dayPeriods.map(period => ({\n\t\t\t...period,\n\t\t\tenabled: overrides[period.id] === undefined ? period.enabled : Boolean(overrides[period.id]),\n\t\t}));\n\t}\n\n\tprivate async getWeeklyPlan(): Promise<WeeklyPlanData> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlan`);\n\t\treturn parseWeeklyPlan(state?.val);\n\t}\n\n\tprivate async getWeeklyPlansLibrary(): Promise<WeeklyPlansLibrary> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`);\n\t\treturn parseWeeklyPlansLibrary(state?.val);\n\t}\n\n\tprivate async syncWeeklyPlansTableToNative(): Promise<void> {\n\t\tconst library = await this.getWeeklyPlansLibrary();\n\t\tconst rows = weeklyPlanRowsFromLibrary(library);\n\t\tawait this.extendObject(`system.adapter.${this.namespace}`, {\n\t\t\tnative: { weeklyPlanRows: rows },\n\t\t});\n\t\tthis.config.weeklyPlanRows = rows;\n\t}\n\n\tprivate async applyWeeklyPlanRowsFromConfig(): Promise<void> {\n\t\tconst library = await this.getWeeklyPlansLibrary();\n\t\tconst next = applyWeeklyPlanRowsToLibrary(library, this.config.weeklyPlanRows);\n\t\tif (JSON.stringify(next) !== JSON.stringify(library)) {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`, JSON.stringify(next), true);\n\t\t}\n\t}\n\n\tprivate async maybeApplyWeeklyToDaily(): Promise<void> {\n\t\tconst loadState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`);\n\t\tif (!loadState?.val) {\n\t\t\treturn;\n\t\t}\n\t\tconst weekday = weekdayKeyFromDate(new Date());\n\t\tconst weekly = await this.getWeeklyPlan();\n\t\tconst dayPlan = weekly.days[weekday];\n\t\tconst current = await this.getPlan();\n\t\tif (this.lastAppliedWeekday === weekday && schedulePlansEqual(current, dayPlan)) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify(dayPlan), true);\n\t\tthis.lastAppliedWeekday = weekday;\n\t\tthis.log.debug(`Daily plan loaded from weekly plan (${weekday})`);\n\t}\n\n\tprivate async publishScheduleRuntime(): Promise<void> {\n\t\tawait this.maybeApplyWeeklyToDaily();\n\n\t\tconst now = new Date();\n\t\tconst minutes = now.getHours() * 60 + now.getMinutes();\n\t\tconst periods = await this.getEffectivePeriods();\n\t\tconst period = findCurrentPeriod(minutes, periods);\n\t\tlet plan = await this.getPlan();\n\n\t\tconst clearAfterState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.clearAfterLast`);\n\t\tconst clearAfterLast = Boolean(clearAfterState?.val);\n\t\tif (clearAfterLast && isPlanFullyExpired(plan, minutes, parseTimeToMinutes)) {\n\t\t\tplan = { version: 1, items: [] };\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify(plan), true);\n\t\t\tthis.log.info(\"Schedule plan cleared automatically after last pictogram ended\");\n\t\t}\n\n\t\tconst itemIndex = findCurrentItemIndex(plan, minutes, parseTimeToMinutes);\n\n\t\t// Keep admin period metadata available; do not wipe Config overrides.\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periods`, JSON.stringify(this.dayPeriods), true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weekdayColors`, JSON.stringify(this.weekdayColors), true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.nowMinutes`, minutes, true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.currentPeriod`, period?.id ?? \"\", true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.currentItemIndex`, itemIndex, true);\n\t}\n\n\tprivate async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise<void> {\n\t\tif (!state || state.ack) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (id.startsWith(`${this.namespace}.${SCHEDULE_CHANNEL}.`)) {\n\t\t\tconst localId = id.replace(`${this.namespace}.${SCHEDULE_CHANNEL}.`, \"\");\n\t\t\tif (localId === \"plan\") {\n\t\t\t\tconst plan = parseSchedulePlan(state.val);\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify(plan), true);\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t} else if (localId === \"periodOverrides\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst raw = typeof state.val === \"string\" ? JSON.parse(String(state.val)) : state.val;\n\t\t\t\t\tconst cleaned = raw && typeof raw === \"object\" ? (raw as Record<string, boolean>) : {};\n\t\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periodOverrides`, JSON.stringify(cleaned), true);\n\t\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.log.error(`Invalid periodOverrides: ${(error as Error).message}`);\n\t\t\t\t}\n\t\t\t} else if (localId === \"clearAfterLast\") {\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.clearAfterLast`, Boolean(state.val), true);\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t} else if (localId === \"weeklyPlan\") {\n\t\t\t\tconst weekly = parseWeeklyPlan(state.val);\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weeklyPlan`, JSON.stringify(weekly), true);\n\t\t\t\tthis.lastAppliedWeekday = null;\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t} else if (localId === \"weeklyPlansLibrary\") {\n\t\t\t\tconst library = parseWeeklyPlansLibrary(state.val);\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`, JSON.stringify(library), true);\n\t\t\t\tawait this.syncWeeklyPlansTableToNative();\n\t\t\t} else if (localId === \"loadDailyFromWeekly\") {\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`, Boolean(state.val), true);\n\t\t\t\tthis.lastAppliedWeekday = null;\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.timerManager || !id.startsWith(`${this.namespace}.${TIMER_CHANNEL}.`)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst localId = id.replace(`${this.namespace}.${TIMER_CHANNEL}.`, \"\");\n\t\tconst maxHours = this.config.maxDurationHours ?? 24;\n\n\t\ttry {\n\t\t\tswitch (localId) {\n\t\t\t\tcase \"start\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.start();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.start`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"pause\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.pause();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.pause`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"resume\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.resume();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.resume`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"stop\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.stop();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.stop`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"duration\":\n\t\t\t\t\tif (typeof state.val === \"number\") {\n\t\t\t\t\t\tawait this.timerManager.setDuration(state.val, maxHours);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"setDurationHours\":\n\t\t\t\t\tif (typeof state.val === \"number\") {\n\t\t\t\t\t\tawait this.applyDurationParts(Math.round(state.val), undefined, maxHours);\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.setDurationHours`, 0, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"setDurationMinutes\":\n\t\t\t\t\tif (typeof state.val === \"number\") {\n\t\t\t\t\t\tawait this.applyDurationParts(undefined, Math.round(state.val), maxHours);\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.setDurationMinutes`, 0, true);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.log.error(`Timer command failed (${localId}): ${(error as Error).message}`);\n\t\t}\n\t}\n\n\tprivate reply(obj: ioBroker.Message, payload: unknown): void {\n\t\tif (obj.callback) {\n\t\t\tthis.sendTo(obj.from, obj.command, payload, obj.callback);\n\t\t}\n\t}\n\n\tprivate async loadPictogramLibrary(): Promise<PictogramLibrary> {\n\t\ttry {\n\t\t\tconst file = await this.readFileAsync(this.namespace, ADAPTER_LIBRARY_FILE);\n\t\t\tconst raw = typeof file.file === \"string\" ? file.file : Buffer.from(file.file).toString(\"utf8\");\n\t\t\treturn parseLibrary(raw);\n\t\t} catch {\n\t\t\treturn emptyLibrary();\n\t\t}\n\t}\n\n\tprivate async savePictogramLibrary(library: PictogramLibrary): Promise<void> {\n\t\tawait this.writeFileAsync(this.namespace, ADAPTER_LIBRARY_FILE, JSON.stringify(library, null, 2));\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.pictogramLibrary`, JSON.stringify(library), true);\n\t}\n\n\tprivate async listPictogramFiles(): Promise<string[] | null> {\n\t\ttry {\n\t\t\tconst result = await this.readDirAsync(PICTOGRAM_FILE_ADAPTER, PICTOGRAM_DIR);\n\t\t\treturn (result || [])\n\t\t\t\t.filter(entry => !entry.isDir && !isIgnoredPictogramFile(entry.file))\n\t\t\t\t.map(entry => entry.file);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate async getMergedPictogramLibrary(): Promise<PictogramLibrary> {\n\t\tconst library = await this.loadPictogramLibrary();\n\t\tconst files = await this.listPictogramFiles();\n\t\tif (!files) {\n\t\t\treturn library;\n\t\t}\n\t\tconst known = new Set(library.items.map(item => item.filename));\n\t\tfor (const filename of files) {\n\t\t\tif (known.has(filename)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlibrary.items.push({\n\t\t\t\tid: filename,\n\t\t\t\tfilename,\n\t\t\t\tpath: pictogramStoragePath(filename),\n\t\t\t\tlabel: filename.replace(/\\.[^.]+$/, \"\").replace(/-\\d+$/, \"\"),\n\t\t\t\ttags: [],\n\t\t\t\toriginalName: filename,\n\t\t\t\tmime: \"\",\n\t\t\t\tuploadedAt: 0,\n\t\t\t});\n\t\t}\n\t\tlibrary.items = library.items.filter(item => files.includes(item.filename));\n\t\tlibrary.items.sort((a, b) => (b.uploadedAt || 0) - (a.uploadedAt || 0));\n\t\treturn library;\n\t}\n\n\t/**\n\t * Custom pictogram library (user-owned images only).\n\t * ARASAAC images must never be uploaded here \u2013 use external IDs only.\n\t *\n\t * @param obj\n\t */\n\tprivate async onMessage(obj: ioBroker.Message): Promise<void> {\n\t\tif (!obj?.command) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tif (obj.command === \"syncPictogramTable\") {\n\t\t\t\tawait this.ensurePictogramStore();\n\t\t\t\tconst rows = await this.buildCustomPictogramRows();\n\t\t\t\tawait this.extendObject(`system.adapter.${this.namespace}`, {\n\t\t\t\t\tnative: { customPictograms: rows },\n\t\t\t\t});\n\t\t\t\tthis.config.customPictograms = rows;\n\t\t\t\tawait this.publishPictogramLibrary();\n\t\t\t\tthis.reply(obj, { ok: true, native: { customPictograms: rows } });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"syncWeeklyPlansTable\") {\n\t\t\t\tconst nativeMsg = obj.message as {\n\t\t\t\t\tweeklyPlanRows?: Array<{ id?: string; name?: string; active?: string }>;\n\t\t\t\t};\n\t\t\t\tif (Array.isArray(nativeMsg?.weeklyPlanRows)) {\n\t\t\t\t\tthis.config.weeklyPlanRows = nativeMsg.weeklyPlanRows;\n\t\t\t\t\tawait this.applyWeeklyPlanRowsFromConfig();\n\t\t\t\t}\n\t\t\t\tawait this.syncWeeklyPlansTableToNative();\n\t\t\t\tconst library = await this.getWeeklyPlansLibrary();\n\t\t\t\tthis.reply(obj, {\n\t\t\t\t\tok: true,\n\t\t\t\t\tnative: { weeklyPlanRows: this.config.weeklyPlanRows || [] },\n\t\t\t\t\tactiveId: library.activeId,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"uploadPictogram\") {\n\t\t\t\tconst payload = obj.message as {\n\t\t\t\t\tfilename?: string;\n\t\t\t\t\tbase64?: string;\n\t\t\t\t\tmime?: string;\n\t\t\t\t\tlabel?: string;\n\t\t\t\t\ttags?: string[] | string;\n\t\t\t\t};\n\t\t\t\tconst originalName = String(payload?.filename || \"image.png\");\n\t\t\t\tconst filename = uniquePictogramFilename(originalName);\n\t\t\t\tconst base64 = String(payload?.base64 || \"\");\n\t\t\t\tif (!base64) {\n\t\t\t\t\tthrow new Error(\"filename and base64 required\");\n\t\t\t\t}\n\t\t\t\tif (!/\\.(png|jpe?g|gif|webp|svg)$/i.test(filename)) {\n\t\t\t\t\tthrow new Error(\"unsupported file type\");\n\t\t\t\t}\n\t\t\t\tconst buffer = Buffer.from(base64.replace(/^data:[^;]+;base64,/, \"\"), \"base64\");\n\t\t\t\tif (!buffer.length) {\n\t\t\t\t\tthrow new Error(\"empty file\");\n\t\t\t\t}\n\t\t\t\tif (buffer.length > 5 * 1024 * 1024) {\n\t\t\t\t\tthrow new Error(\"file too large (max 5 MB)\");\n\t\t\t\t}\n\t\t\t\tconst path = pictogramStoragePath(filename);\n\t\t\t\tawait this.writeFileAsync(PICTOGRAM_FILE_ADAPTER, path, buffer);\n\t\t\t\tconst library = await this.getMergedPictogramLibrary();\n\t\t\t\tconst entry: CustomPictogram = {\n\t\t\t\t\tid: filename,\n\t\t\t\t\tfilename,\n\t\t\t\t\tpath,\n\t\t\t\t\tlabel: String(payload?.label || originalName.replace(/\\.[^.]+$/, \"\")),\n\t\t\t\t\ttags: normalizeTags(payload?.tags),\n\t\t\t\t\toriginalName,\n\t\t\t\t\tmime: String(payload?.mime || \"\"),\n\t\t\t\t\tuploadedAt: Date.now(),\n\t\t\t\t};\n\t\t\t\tlibrary.items = [entry, ...library.items.filter(item => item.filename !== filename)];\n\t\t\t\tawait this.savePictogramLibrary(library);\n\t\t\t\tawait this.syncCustomPictogramsConfig();\n\t\t\t\tthis.log.info(`Custom pictogram stored: ${PICTOGRAM_FILE_ADAPTER}/${path} (${buffer.length} bytes)`);\n\t\t\t\tthis.reply(obj, {\n\t\t\t\t\tok: true,\n\t\t\t\t\tpath,\n\t\t\t\t\turl: pictogramPublicUrl(path),\n\t\t\t\t\titem: entry,\n\t\t\t\t\tlibrary,\n\t\t\t\t\tadapter: PICTOGRAM_FILE_ADAPTER,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"listPictograms\") {\n\t\t\t\tconst library = await this.getPublishedPictogramLibrary();\n\t\t\t\tthis.reply(obj, {\n\t\t\t\t\tok: true,\n\t\t\t\t\tfiles: library.items.map(item => item.filename),\n\t\t\t\t\tlibrary,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"updatePictogram\") {\n\t\t\t\tconst payload = obj.message as {\n\t\t\t\t\tpath?: string;\n\t\t\t\t\tfilename?: string;\n\t\t\t\t\tlabel?: string;\n\t\t\t\t\ttags?: string[] | string;\n\t\t\t\t};\n\t\t\t\tconst key = String(payload?.path || payload?.filename || \"\");\n\t\t\t\tif (!key) {\n\t\t\t\t\tthrow new Error(\"path required\");\n\t\t\t\t}\n\t\t\t\tconst library = await this.getMergedPictogramLibrary();\n\t\t\t\tconst item = library.items.find(entry => matchesPictogramKey(entry, key));\n\t\t\t\tif (!item) {\n\t\t\t\t\tthrow new Error(\"pictogram not found\");\n\t\t\t\t}\n\t\t\t\tif (payload.label !== undefined) {\n\t\t\t\t\titem.label = String(payload.label);\n\t\t\t\t}\n\t\t\t\tif (payload.tags !== undefined) {\n\t\t\t\t\titem.tags = normalizeTags(payload.tags);\n\t\t\t\t}\n\t\t\t\tawait this.savePictogramLibrary(library);\n\t\t\t\tthis.reply(obj, { ok: true, item, library });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"deletePictogram\") {\n\t\t\t\tconst payload = obj.message as { path?: string; filename?: string };\n\t\t\t\tconst key = String(payload?.path || payload?.filename || \"\");\n\t\t\t\tif (!key) {\n\t\t\t\t\tthrow new Error(\"path required\");\n\t\t\t\t}\n\t\t\t\tconst library = await this.getMergedPictogramLibrary();\n\t\t\t\tconst item = library.items.find(entry => matchesPictogramKey(entry, key));\n\t\t\t\tif (!item) {\n\t\t\t\t\tthrow new Error(\"pictogram not found\");\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait this.unlinkAsync(PICTOGRAM_FILE_ADAPTER, item.path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.log.warn(`Could not delete pictogram file ${item.path}: ${(error as Error).message}`);\n\t\t\t\t}\n\t\t\t\tlibrary.items = library.items.filter(entry => entry.filename !== item.filename);\n\t\t\t\tawait this.savePictogramLibrary(library);\n\t\t\t\tthis.reply(obj, { ok: true, library });\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.log.error(`Pictogram command ${obj.command} failed: ${(error as Error).message}`);\n\t\t\tthis.reply(obj, { ok: false, error: (error as Error).message });\n\t\t}\n\t}\n\n\tprivate async applyDurationParts(\n\t\thours: number | undefined,\n\t\tminutes: number | undefined,\n\t\tmaxHours: number,\n\t): Promise<void> {\n\t\tif (!this.timerManager) {\n\t\t\treturn;\n\t\t}\n\t\tconst snapshot = this.timerManager.getSnapshot();\n\t\tconst current = secondsToParts(snapshot.duration);\n\t\tconst nextHours = hours ?? current.hours;\n\t\tconst nextMinutes = minutes ?? current.minutes;\n\t\tconst totalSeconds = nextHours * 3600 + nextMinutes * 60;\n\t\tawait this.timerManager.setDuration(totalSeconds, maxHours);\n\t}\n\n\tprivate onUnload(callback: () => void): void {\n\t\tif (this.scheduleTick !== undefined && this.scheduleTick !== null) {\n\t\t\tthis.clearInterval(this.scheduleTick);\n\t\t\tthis.scheduleTick = null;\n\t\t}\n\t\tthis.timerManager?.destroy();\n\t\tthis.timerManager = null;\n\t\tcallback();\n\t}\n}\n\nif (require.main !== module) {\n\tmodule.exports = (options: Partial<utils.AdapterOptions> | undefined) => new AutismSupport(options);\n} else {\n\t(() => new AutismSupport())();\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["localId"]
7
7
  }
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "autism-support",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "news": {
6
+ "0.2.2": {
7
+ "en": "Fix object structure: timer channel, value.interval roles, button read flags",
8
+ "de": "Objektstruktur repariert: Timer-Kanal, value.interval-Rollen, Button read-Flags",
9
+ "ru": "Исправлена структура объектов: канал timer, роли value.interval, флаги read кнопок",
10
+ "pt": "Corrigida estrutura de objetos: canal timer, roles value.interval, flags read dos botões",
11
+ "nl": "Objectstructuur gerepareerd: timer-kanaal, value.interval-rollen, button read-flags",
12
+ "fr": "Structure d'objets corrigée : canal timer, rôles value.interval, flags read des boutons",
13
+ "it": "Struttura oggetti corretta: canale timer, ruoli value.interval, flag read pulsanti",
14
+ "es": "Estructura de objetos corregida: canal timer, roles value.interval, flags read de botones",
15
+ "pl": "Naprawiono strukturę obiektów: kanał timer, role value.interval, flagi read przycisków",
16
+ "uk": "Виправлено структуру об'єктів: канал timer, ролі value.interval, прапорці read кнопок",
17
+ "zh-cn": "修复对象结构:timer 通道、value.interval 角色、按钮 read 标志"
18
+ },
6
19
  "0.2.1": {
7
20
  "en": "Weekly plans: weekday tabs, templates, Admin colors, week live overview, daily sync",
8
21
  "de": "Wochenpläne: Wochentags-Tabs, Vorlagen, Admin-Farben, Live-Wochenübersicht, Tages-Sync",
@@ -80,19 +93,6 @@
80
93
  "pl": "Podgląd piktogramu naprawiony: kodowanie ścieżki vis-2 i fallback /files",
81
94
  "uk": "Виправлено попередній перегляд піктограм: кодування шляху vis-2 і fallback /files",
82
95
  "zh-cn": "修复自定义象形图预览:编码 vis-2 路径与 /files 回退"
83
- },
84
- "0.1.22": {
85
- "en": "Fix pictogram folder: library in adapter store, placeholder in vis-2; remove broken _library.json",
86
- "de": "Piktogramm-Ordner repariert: Metadaten im Adapter, Platzhalter in vis-2; _library.json entfernt",
87
- "ru": "Папка pictogram: библиотека в adapter store, placeholder в vis-2; удалён _library.json",
88
- "pt": "Pasta pictogramas: biblioteca no adapter store, placeholder em vis-2; remove _library.json",
89
- "nl": "Pictogram-map: bibliotheek in adapter store, placeholder in vis-2; _library.json verwijderd",
90
- "fr": "Dossier pictogrammes : bibliothèque dans adapter store, placeholder vis-2 ; _library.json supprimé",
91
- "it": "Cartella pittogrammi: libreria in adapter store, placeholder in vis-2; rimosso _library.json",
92
- "es": "Carpeta pictogramas: biblioteca en adapter store, placeholder en vis-2; elimina _library.json",
93
- "pl": "Folder piktogramów: biblioteka w adapter store, placeholder w vis-2; usunięto _library.json",
94
- "uk": "Папка піктограм: бібліотека в adapter store, placeholder у vis-2; видалено _library.json",
95
- "zh-cn": "修复象形图文件夹:库在 adapter store,vis-2 占位符;移除损坏的 _library.json"
96
96
  }
97
97
  },
98
98
  "titleLang": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.autism-support",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Unterstützung für Menschen mit Autismus: Visual Countdown, Bild-Ablaufpläne und Piktogramme",
5
5
  "author": {
6
6
  "name": "Matthias Ulrich",