iobroker.autodarts 0.8.3 → 1.0.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/README.md CHANGED
@@ -56,9 +56,9 @@ Connects to your local Autodarts Board Manager (via IP and port, e.g. `192.168.x
56
56
  - **`config.triggerResetSec`**: Auto-reset time for triple/double/bullseye/miss flags
57
57
 
58
58
  ### Tools Addon Integration
59
- - **`tools.RAW`**: Input state used to receive events from browser tools (e.g. busted, gameon, gameshot).
60
- - **`tools.busted/tools.gameon/tools.gameshot`**: Read-only trigger flags that are set when the corresponding event is received via tools.RAW.
61
- - **`tools.config.urlBusted/urlGameon/urlGameshot`**: Pre-generated HTTP URLs (simple-api calls) that can be copied into the Tools for Autodarts browser extension.
59
+ - **`tools.RAW`**: Input state used to receive events from browser tools (e.g. busted, gameon, gameshot, 180, matchshot, takeout).
60
+ - **`trigger.is180/isBusted/isGameon/isGameshot/isMatchshot/isTakeout`**: Read-only trigger flags set when corresponding events received via `tools.RAW`.
61
+ - **`tools.config.url*`**: Pre-generated HTTP URLs (simple-api calls) that can be copied into Tools for Autodarts browser extension.
62
62
 
63
63
  ## What this adapter does NOT do
64
64
 
@@ -132,6 +132,11 @@ In **HELP & FAQ** you will find general information and help about the adapter a
132
132
  <!--
133
133
  ### **WORK IN PROGRESS**
134
134
  -->
135
+ ### 1.0.0 (2026-01-11)
136
+ - (skvarel) BREAKING CHANGE: All triggers to unified trigger.is structure
137
+ - (skvarel) Manual cleanup required: Delete old autodarts.X.throw.is and tools. states after update
138
+ - (skvarel) Unchanged: tools.RAW, tools.config.url, all timers/functionality
139
+
135
140
  ### 0.8.3 (2026-01-06)
136
141
  - (skvarel) Added: CHANGELOG_OLD.md
137
142
  - (skvarel) Improved: Link to documentation added to the help section.
@@ -147,7 +152,7 @@ In **HELP & FAQ** you will find general information and help about the adapter a
147
152
  ### 0.8.0 (2026-01-04)
148
153
  - (skvarel) Added: New **TOOLS ADDON INTEGRATION** tab and runtime-generated URL states under `tools.config.*` for browser-based integrations (e.g. Tools for Autodarts).
149
154
 
150
- ### 0.7.3 (2026-01-03)
155
+ ## 0.7.3 (2026-01-03)
151
156
  - (skvarel) Fix Adapter Checker Warnings
152
157
 
153
158
  ## Older changes
@@ -174,4 +179,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
174
179
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
175
180
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
176
181
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
177
- SOFTWARE.
182
+ SOFTWARE.
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "autodarts",
4
- "version": "0.8.3",
4
+ "version": "1.0.0",
5
5
  "news": {
6
+ "1.0.0": {
7
+ "en": "BREAKING CHANGE: All triggers to unified trigger.is structure\nManual cleanup required: Delete old autodarts.X.throw.is and tools. states after update\nUnchanged: tools.RAW, tools.config.url, all timers/functionality",
8
+ "de": "BREAKING CHANGE: Alle Auslöser zum vereinheitlichten Auslöser. ist Struktur\nManuelle Reinigung erforderlich: Löschen Sie alte Autodarts. X.throw.is und Werkzeuge. Zustände nach Update\nUnverändert: Werkzeuge. RAW, tools.config.url, alle Timer/Funktionalität",
9
+ "ru": "Изменить дыхание: Все триггеры в единый триггер. структура\nТребуется ручная очистка: Удалите старые автодарты. X.throw.is и инструменты. государства после обновления\nБез изменений: инструменты. RAW, tools.config.url, все таймеры/функциональность",
10
+ "pt": "MUDANÇAS DE RISCO: Todos os gatilhos para o gatilho unificado. é estrutura\nLimpeza manual necessária: Apagar os autodarts antigos. X.throw.is e ferramentas. estados após a atualização\nInalterado: ferramentas. RAW, tools.config.url, todos os timers/funcionalidade",
11
+ "nl": "Breaking VERANDERING: Alle triggers naar uniforme trekker. is structuur\nHandmatig opruimen vereist: Verwijder oude autodarts. X.throw.is en gereedschap. staat na update\nOngewijzigd: gereedschap. RAW, tools.config.url, all timers/functionaliteit",
12
+ "fr": "CHANGEMENT DE BREAING: Tous les déclencheurs au déclencheur unifié. est la structure\nNettoyage manuel requis: Supprimer les anciens autodarts. X.throw. est et outils. États après mise à jour\nSans changement : outils. RAW, tools.config.url, toutes les minuteries/fonctionnalité",
13
+ "it": "CAMBIO DI BREAKING: Tutti i trigger per attivare unificato. è struttura\nPulizia manuale necessaria: Eliminare vecchi autodarts. X.throw.is e strumenti. stati dopo l'aggiornamento\nSvariato: strumenti. RAW, tools.config.url, tutti i timer/funzionalità",
14
+ "es": "Cambiando: Todos disparan al gatillo unificado. estructura\nLimpieza manual requerida: Eliminar viejos autodarts. X.throw.is y herramientas. estados después de la actualización\nSin cambios: herramientas. RAW, tools.config.url, todos los temporizadores/funcionalidad",
15
+ "pl": "ZMIANA ZBIORCZA: Wszystkie wyzwalacze do jednego zapalnika. jest strukturą\nWymagane jest ręczne czyszczenie: Usuń stare autodoty. X.throw.is i narzędzia. stany po aktualizacji\nBez zmian: narzędzia. RAW, narzędzia .config.url, wszystkie timery / funkcjonalność",
16
+ "uk": "БРЕАКІНГ ЗМІН: Всі тригери для уніфікованого тригера. структура\nВимоги: Видалити старі автодарти. X.throw.is та інструменти. стани після оновлення\nНезмінені: інструменти. RAW, інструменти.config.url, всі таймери/функціональність",
17
+ "zh-cn": "打破变化: 所有触发器统一触发. 是结构\n需要进行人工清理: 删除旧的自定义 。 X. throw.is和工具。 更新后状态\n未更改:工具。 RAW,工具.config.url,所有计时器/功能"
18
+ },
6
19
  "0.8.3": {
7
20
  "en": "Added: CHANGELOG_OLD.md\nImproved: Link to documentation added to the help section.",
8
21
  "de": "Hinzugefügt: CHANGELOG_OLD.md\nVerbessert: Link zur Dokumentation, die im Hilfebereich hinzugefügt wird.",
@@ -80,19 +93,6 @@
80
93
  "pl": "Napraw rok Copyright",
81
94
  "uk": "Фіксація авторського права",
82
95
  "zh-cn": "修复版权年"
83
- },
84
- "0.7.1": {
85
- "en": "Changed: Reduced reconnect delay after offline.",
86
- "de": "Geändert: Reduzierte Reconnect-Verzögerung nach Offline.",
87
- "ru": "Изменение: снижение задержки повторного подключения после офлайна.",
88
- "pt": "Alterado: Reconectar atraso reduzido após offline.",
89
- "nl": "Veranderd: Verminderde reconnect vertraging na offline.",
90
- "fr": "Changed: Réduction du délai de reconnect après hors ligne.",
91
- "it": "Cambiato: Riduzione del ritardo di ricollegamento dopo offline.",
92
- "es": "Cambio: Reducir el retraso de reconexión después de fuera de línea.",
93
- "pl": "Zmiana: Zmniejszone opóźnienie ponownego połączenia po offline.",
94
- "uk": "Змінено: Зменшення затримки відключення після вимкнення.",
95
- "zh-cn": "更改:下线后减少重联延迟."
96
96
  }
97
97
  },
98
98
  "titleLang": {
package/lib/throw.js CHANGED
@@ -1,3 +1,4 @@
1
+ /* eslint-disable jsdoc/require-param-description */
1
2
  // lib/throw.js
2
3
  "use strict";
3
4
 
@@ -10,10 +11,7 @@ async function init(adapter) {
10
11
  await adapter.extendObjectAsync("throw", {
11
12
  type: "channel",
12
13
  common: {
13
- name: {
14
- en: "Current throw",
15
- de: "Aktueller Wurf",
16
- },
14
+ name: { en: "Current throw", de: "Aktueller Wurf" },
17
15
  },
18
16
  native: {},
19
17
  });
@@ -21,92 +19,59 @@ async function init(adapter) {
21
19
  await adapter.extendObjectAsync("throw.current", {
22
20
  type: "state",
23
21
  common: {
24
- name: {
25
- en: "Current dart score",
26
- de: "Punkte aktueller Dart",
27
- },
22
+ name: { en: "Current dart score", de: "Punkte aktueller Dart" },
28
23
  type: "number",
29
24
  role: "value",
30
25
  read: true,
31
26
  write: false,
32
- desc: {
33
- en: "Score of the last dart",
34
- de: "Punktzahl des letzten Dart",
35
- },
36
27
  },
37
28
  native: {},
38
29
  });
39
30
 
40
- await adapter.extendObjectAsync("throw.isTriple", {
31
+ await adapter.extendObjectAsync("trigger.isTriple", {
41
32
  type: "state",
42
33
  common: {
43
- name: {
44
- en: "Triple hit",
45
- de: "Triple getroffen",
46
- },
34
+ name: { en: "Triple (trigger from Board)", de: "Triple (Trigger vom Board)" },
47
35
  type: "boolean",
48
36
  role: "indicator",
49
37
  read: true,
50
38
  write: false,
51
- desc: {
52
- en: "true if the dart hit a triple segment (and passes score range)",
53
- de: "true, wenn ein Dart ein Triple-Segment getroffen hat (und innerhalb der Punkterange liegt)",
54
- },
55
39
  },
56
40
  native: {},
57
41
  });
58
42
 
59
- await adapter.extendObjectAsync("throw.isBullseye", {
43
+ await adapter.extendObjectAsync("trigger.isBullseye", {
60
44
  type: "state",
61
45
  common: {
62
- name: {
63
- en: "Bullseye hit",
64
- de: "Bullseye getroffen",
65
- },
46
+ name: { en: "Bullseye (trigger from Board)", de: "Bullseye (Trigger vom Board)" },
66
47
  type: "boolean",
67
48
  role: "indicator",
68
49
  read: true,
69
50
  write: false,
70
- desc: {
71
- en: "true if the dart hit the bull or bullseye",
72
- de: "true, wenn ein Dart Bull oder Bullseye getroffen hat",
73
- },
74
51
  },
75
52
  native: {},
76
53
  });
77
- await adapter.extendObjectAsync("throw.isMiss", {
54
+
55
+ await adapter.extendObjectAsync("trigger.isMiss", {
78
56
  type: "state",
79
57
  common: {
80
- name: {
81
- en: "Miss",
82
- de: "Kein Treffer",
83
- },
58
+ name: { en: "Miss (trigger from Board)", de: "Miss (Trigger vom Board)" },
84
59
  type: "boolean",
85
60
  role: "indicator",
86
61
  read: true,
87
62
  write: false,
88
- desc: {
89
- en: "true if the dart did not hit a valid scoring segment",
90
- de: "true, wenn der Dart kein gültiges Punktesegment getroffen hat",
91
- },
92
63
  },
93
64
  native: {},
94
65
  });
95
- await adapter.extendObjectAsync("throw.isDouble", {
66
+
67
+ await adapter.extendObjectAsync("trigger.isDouble", {
96
68
  type: "state",
97
69
  common: {
98
- name: {
99
- en: "Double hit",
100
- de: "Doppel getroffen",
101
- },
70
+ name: { en: "Double (trigger from Board)", de: "Doppel (Trigger vom Board)" },
102
71
  type: "boolean",
103
72
  role: "indicator",
104
73
  read: true,
105
74
  write: false,
106
- desc: {
107
- en: "true if the dart hit a double segment",
108
- de: "true, wenn ein Dart ein Doppel-Segment getroffen hat",
109
- },
110
75
  },
111
76
  native: {},
112
77
  });
@@ -115,18 +80,18 @@ async function init(adapter) {
115
80
  /**
116
81
  * Aktualisiert die Throw-States für den letzten Dart inkl. Triple/Bull-Flags.
117
82
  *
118
- * @param {import("@iobroker/adapter-core").AdapterInstance} adapter Adapter-Instanz dieses Autodarts-Adapters
119
- * @param {any} lastDart Letzter Dart aus state.throws
83
+ * @param {import("@iobroker/adapter-core").AdapterInstance} adapter
84
+ * @param {any} lastDart
120
85
  */
121
86
  async function updateThrow(adapter, lastDart) {
122
- // @ts-expect-error - calcScore is a custom method in the Autodarts adapter class
87
+ // @ts-expect-error adapter has custom method calcScore
123
88
  const score = adapter.calcScore(lastDart);
124
89
  const segment = lastDart?.segment?.number || 0;
125
90
 
126
91
  // Score-Range aus Adapter übernehmen
127
- // @ts-expect-error - tripleMinScoreRuntime is a custom property in the Autodarts adapter class
92
+ // @ts-expect-error adapter has custom prop tripleMinScoreRuntime
128
93
  let minScore = adapter.tripleMinScoreRuntime;
129
- // @ts-expect-error - tripleMaxScoreRuntime is a custom property in the Autodarts adapter class
94
+ // @ts-expect-error adapter has custom prop tripleMaxScoreRuntime
130
95
  let maxScore = adapter.tripleMaxScoreRuntime;
131
96
 
132
97
  if (!Number.isFinite(minScore)) {
@@ -145,49 +110,46 @@ async function updateThrow(adapter, lastDart) {
145
110
  const isTriple =
146
111
  !!lastDart?.segment && lastDart.segment.multiplier === 3 && segment >= minScore && segment <= maxScore;
147
112
  const isDouble = !!lastDart?.segment && lastDart.segment.multiplier === 2;
148
-
149
113
  const segName = (lastDart?.segment?.name || "").toUpperCase();
150
114
  const isBullseye = segName.includes("BULL") || lastDart?.segment?.number === 25;
151
115
  const isMiss = !lastDart?.segment || score === 0;
152
116
 
153
117
  await adapter.setStateAsync("throw.current", { val: score, ack: true });
154
118
 
155
- // Timer für Auto-Reset abbrechen
156
- // @ts-expect-error - resetTimer is a custom property in the Autodarts adapter class
157
- if (adapter.resetTimer) {
158
- // @ts-expect-error - resetTimer is a custom property in the Autodarts adapter class
159
- clearTimeout(adapter.resetTimer);
160
- // @ts-expect-error - resetTimer is a custom property in the Autodarts adapter class
161
- adapter.resetTimer = null;
119
+ // 1. Alten Timer für Auto-Reset abbrechen
120
+ if (adapter.resetTimers["throw"]) {
121
+ clearTimeout(adapter.resetTimers["throw"]);
122
+ delete adapter.resetTimers["throw"];
162
123
  }
163
124
 
164
- await adapter.setStateAsync("throw.isTriple", { val: isTriple, ack: true });
165
- await adapter.setStateAsync("throw.isDouble", { val: isDouble, ack: true });
166
- await adapter.setStateAsync("throw.isBullseye", { val: isBullseye, ack: true });
167
- await adapter.setStateAsync("throw.isMiss", { val: isMiss, ack: true });
125
+ // 2. States auf die neuen Werte setzen
126
+ await adapter.setStateAsync("trigger.isTriple", { val: isTriple, ack: true });
127
+ await adapter.setStateAsync("trigger.isDouble", { val: isDouble, ack: true });
128
+ await adapter.setStateAsync("trigger.isBullseye", { val: isBullseye, ack: true });
129
+ await adapter.setStateAsync("trigger.isMiss", { val: isMiss, ack: true });
168
130
 
169
- // @ts-expect-error - triggerResetSecRuntime is a custom property in the Autodarts adapter class
131
+ // 3. Neuen Reset-Timer setzen
132
+ // @ts-expect-error adapter has custom prop triggerResetSecRuntime
170
133
  const timeoutMs = (Number(adapter.triggerResetSecRuntime) || 0) * 1000;
134
+
171
135
  if (timeoutMs > 0) {
172
- adapter.resetTimer = setTimeout(() => {
136
+ adapter.resetTimers["throw"] = setTimeout(() => {
173
137
  if (isTriple) {
174
- adapter.setState("throw.isTriple", { val: false, ack: true });
138
+ adapter.setState("trigger.isTriple", { val: false, ack: true });
175
139
  }
176
140
  if (isDouble) {
177
- adapter.setState("throw.isDouble", { val: false, ack: true });
141
+ adapter.setState("trigger.isDouble", { val: false, ack: true });
178
142
  }
179
143
  if (isBullseye) {
180
- adapter.setState("throw.isBullseye", { val: false, ack: true });
144
+ adapter.setState("trigger.isBullseye", { val: false, ack: true });
181
145
  }
182
146
  if (isMiss) {
183
- adapter.setState("throw.isMiss", { val: false, ack: true });
147
+ adapter.setState("trigger.isMiss", { val: false, ack: true });
184
148
  }
185
- adapter.resetTimer = null;
149
+
150
+ delete adapter.resetTimers["throw"];
186
151
  }, timeoutMs);
187
152
  }
188
153
  }
189
154
 
190
- module.exports = {
191
- init,
192
- updateThrow,
193
- };
155
+ module.exports = { init, updateThrow };
package/lib/tools.js CHANGED
@@ -1,3 +1,4 @@
1
+ // lib/tools.js
1
2
  /* eslint-disable jsdoc/require-param-description */
2
3
  "use strict";
3
4
 
@@ -10,9 +11,12 @@
10
11
  async function init(adapter) {
11
12
  // Initialzustand setzen
12
13
  await adapter.setStateAsync("tools.RAW", { val: "", ack: true });
13
- await adapter.setStateAsync("tools.busted", { val: false, ack: true });
14
- await adapter.setStateAsync("tools.gameon", { val: false, ack: true });
15
- await adapter.setStateAsync("tools.gameshot", { val: false, ack: true });
14
+ await adapter.setStateAsync("trigger.isBusted", { val: false, ack: true });
15
+ await adapter.setStateAsync("trigger.isGameon", { val: false, ack: true });
16
+ await adapter.setStateAsync("trigger.isGameshot", { val: false, ack: true });
17
+ await adapter.setStateAsync("trigger.is180", { val: false, ack: true });
18
+ await adapter.setStateAsync("trigger.isMatchshot", { val: false, ack: true });
19
+ await adapter.setStateAsync("trigger.isTakeout", { val: false, ack: true });
16
20
 
17
21
  // Auf Änderungen von tools.RAW hören
18
22
  adapter.subscribeStates("tools.RAW");
@@ -34,17 +38,27 @@ async function handleStateChange(adapter, idShort, state) {
34
38
  const val = String(state.val || "").toLowerCase();
35
39
  const timeoutMs = (adapter.triggerResetSecRuntime || 0) * 1000;
36
40
 
37
- // Alle Trigger zuerst zurücksetzen
41
+ /* Alle Trigger zuerst zurücksetzen
38
42
  await adapter.setStateAsync("tools.busted", { val: false, ack: true });
39
43
  await adapter.setStateAsync("tools.gameon", { val: false, ack: true });
40
44
  await adapter.setStateAsync("tools.gameshot", { val: false, ack: true });
45
+ await adapter.setStateAsync("tools.180", { val: false, ack: true });
46
+ await adapter.setStateAsync("tools.matchshot", { val: false, ack: true });
47
+ await adapter.setStateAsync("tools.takeout", { val: false, ack: true });
48
+ */
41
49
 
42
50
  if (val === "busted") {
43
- await setPulse(adapter, "tools.busted", timeoutMs);
51
+ await setPulse(adapter, "trigger.isBusted", timeoutMs);
44
52
  } else if (val === "gameon") {
45
- await setPulse(adapter, "tools.gameon", timeoutMs);
53
+ await setPulse(adapter, "trigger.isGameon", timeoutMs);
46
54
  } else if (val === "gameshot") {
47
- await setPulse(adapter, "tools.gameshot", timeoutMs);
55
+ await setPulse(adapter, "trigger.isGameshot", timeoutMs);
56
+ } else if (val === "180") {
57
+ await setPulse(adapter, "trigger.is180", timeoutMs);
58
+ } else if (val === "matchshot") {
59
+ await setPulse(adapter, "trigger.isMatchshot", timeoutMs);
60
+ } else if (val === "takeout") {
61
+ await setPulse(adapter, "trigger.isTakeout", timeoutMs);
48
62
  }
49
63
  }
50
64
 
@@ -58,15 +72,22 @@ async function handleStateChange(adapter, idShort, state) {
58
72
  * @param {number} timeoutMs
59
73
  */
60
74
  async function setPulse(adapter, id, timeoutMs) {
75
+ // Falls das Objekt für die Timer noch nicht existiert, kurz anlegen
76
+ adapter.resetTimers = adapter.resetTimers || {};
77
+
78
+ // 1) Auf true setzen
61
79
  await adapter.setStateAsync(id, { val: true, ack: true });
62
80
 
63
81
  if (timeoutMs > 0) {
64
- if (adapter.resetTimer) {
65
- clearTimeout(adapter.resetTimer);
82
+ // 2) Bestehenden Timer NUR für diese ID löschen
83
+ if (adapter.resetTimers[id]) {
84
+ clearTimeout(adapter.resetTimers[id]);
66
85
  }
67
- adapter.resetTimer = setTimeout(() => {
68
- adapter.setState(id, { val: false, ack: true });
69
- adapter.resetTimer = null;
86
+
87
+ // 3) Neuen Timer für diese ID starten
88
+ adapter.resetTimers[id] = setTimeout(async () => {
89
+ await adapter.setStateAsync(id, { val: false, ack: true });
90
+ delete adapter.resetTimers[id]; // Timer-Referenz nach Ablauf aufräumen
70
91
  }, timeoutMs);
71
92
  }
72
93
  }
package/main.js CHANGED
@@ -35,6 +35,7 @@ class Autodarts extends utils.Adapter {
35
35
  // Reset-Timeout + Timer für isTriple/isBullseye/isDouble/isMiss
36
36
  this.triggerResetSecRuntime = null;
37
37
  this.resetTimer = null;
38
+ this.resetTimers = {}; // NEU: Objekt für individuelle Timer initialisieren
38
39
  }
39
40
 
40
41
  async onReady() {
@@ -73,6 +74,18 @@ class Autodarts extends utils.Adapter {
73
74
  // Visit-Struktur anlegen (ausgelagert)
74
75
  await visit.init(this);
75
76
 
77
+ // Trigger-Channel für alle is*-Trigger
78
+ await this.extendObjectAsync("trigger", {
79
+ type: "channel",
80
+ common: {
81
+ name: {
82
+ en: "Trigger states",
83
+ de: "Trigger-Zustände",
84
+ },
85
+ },
86
+ native: {},
87
+ });
88
+
76
89
  // Throw-Channel und States anlegen (ausgelagert)
77
90
  await throwLogic.init(this);
78
91
 
@@ -483,12 +496,12 @@ class Autodarts extends utils.Adapter {
483
496
  native: {},
484
497
  });
485
498
 
486
- await this.extendObjectAsync("tools.busted", {
499
+ await this.extendObjectAsync("trigger.isBusted", {
487
500
  type: "state",
488
501
  common: {
489
502
  name: {
490
- en: "Busted (trigger)",
491
- de: "Busted (Trigger)",
503
+ en: "Busted (trigger from tools)",
504
+ de: "Busted (Trigger aus Tools)",
492
505
  },
493
506
  type: "boolean",
494
507
  role: "indicator",
@@ -498,12 +511,12 @@ class Autodarts extends utils.Adapter {
498
511
  native: {},
499
512
  });
500
513
 
501
- await this.extendObjectAsync("tools.gameon", {
514
+ await this.extendObjectAsync("trigger.isGameon", {
502
515
  type: "state",
503
516
  common: {
504
517
  name: {
505
- en: "Game on (trigger)",
506
- de: "Game on (Trigger)",
518
+ en: "Game on (trigger from tools)",
519
+ de: "Game on (Trigger aus Tools)",
507
520
  },
508
521
  type: "boolean",
509
522
  role: "indicator",
@@ -513,12 +526,12 @@ class Autodarts extends utils.Adapter {
513
526
  native: {},
514
527
  });
515
528
 
516
- await this.extendObjectAsync("tools.gameshot", {
529
+ await this.extendObjectAsync("trigger.isGameshot", {
517
530
  type: "state",
518
531
  common: {
519
532
  name: {
520
- en: "Gameshot (trigger)",
521
- de: "Gameshot (Trigger)",
533
+ en: "Gameshot (trigger from tools)",
534
+ de: "Gameshot (Trigger aus Tools)",
522
535
  },
523
536
  type: "boolean",
524
537
  role: "indicator",
@@ -527,14 +540,48 @@ class Autodarts extends utils.Adapter {
527
540
  },
528
541
  native: {},
529
542
  });
530
- // NEU: Unter-Channel für URL-Infos
531
- await this.extendObjectAsync("tools.config", {
532
- type: "channel",
543
+
544
+ await this.extendObjectAsync("trigger.is180", {
545
+ type: "state",
546
+ common: {
547
+ name: {
548
+ en: "180 (trigger from tools)",
549
+ de: "180 (Trigger aus Tools)",
550
+ },
551
+ type: "boolean",
552
+ role: "indicator",
553
+ read: true,
554
+ write: false,
555
+ },
556
+ native: {},
557
+ });
558
+
559
+ await this.extendObjectAsync("trigger.isMatchshot", {
560
+ type: "state",
533
561
  common: {
534
562
  name: {
535
- en: "Tools configuration",
536
- de: "Tools-Konfiguration",
563
+ en: "Matchshot (trigger from tools)",
564
+ de: "Matchshot (Trigger aus Tools)",
537
565
  },
566
+ type: "boolean",
567
+ role: "indicator",
568
+ read: true,
569
+ write: false,
570
+ },
571
+ native: {},
572
+ });
573
+
574
+ await this.extendObjectAsync("trigger.isTakeout", {
575
+ type: "state",
576
+ common: {
577
+ name: {
578
+ en: "Takeout (trigger from tools)",
579
+ de: "Takeout (Trigger aus Tools)",
580
+ },
581
+ type: "boolean",
582
+ role: "indicator",
583
+ read: true,
584
+ write: false,
538
585
  },
539
586
  native: {},
540
587
  });
@@ -584,6 +631,49 @@ class Autodarts extends utils.Adapter {
584
631
  native: {},
585
632
  });
586
633
 
634
+ await this.extendObjectAsync("tools.config.url180", {
635
+ type: "state",
636
+ common: {
637
+ name: {
638
+ en: "URL for 180",
639
+ de: "URL für 180",
640
+ },
641
+ type: "string",
642
+ role: "text.url",
643
+ read: true,
644
+ write: false,
645
+ },
646
+ native: {},
647
+ });
648
+ await this.extendObjectAsync("tools.config.urlMatchshot", {
649
+ type: "state",
650
+ common: {
651
+ name: {
652
+ en: "URL for Matchshot",
653
+ de: "URL für Matchshot",
654
+ },
655
+ type: "string",
656
+ role: "text.url",
657
+ read: true,
658
+ write: false,
659
+ },
660
+ native: {},
661
+ });
662
+ await this.extendObjectAsync("tools.config.urlTakeout", {
663
+ type: "state",
664
+ common: {
665
+ name: {
666
+ en: "URL for Takeout",
667
+ de: "URL für Takeout",
668
+ },
669
+ type: "string",
670
+ role: "text.url",
671
+ read: true,
672
+ write: false,
673
+ },
674
+ native: {},
675
+ });
676
+
587
677
  // Tools-Integration initialisieren
588
678
  await tools.init(this);
589
679
 
@@ -776,6 +866,9 @@ class Autodarts extends utils.Adapter {
776
866
  await this.setStateAsync("tools.config.urlBusted", { val: "", ack: true });
777
867
  await this.setStateAsync("tools.config.urlGameon", { val: "", ack: true });
778
868
  await this.setStateAsync("tools.config.urlGameshot", { val: "", ack: true });
869
+ await this.setStateAsync("tools.config.url180", { val: "", ack: true });
870
+ await this.setStateAsync("tools.config.urlMatchshot", { val: "", ack: true });
871
+ await this.setStateAsync("tools.config.urlTakeout", { val: "", ack: true });
779
872
  return;
780
873
  }
781
874
 
@@ -785,12 +878,20 @@ class Autodarts extends utils.Adapter {
785
878
  const urlBusted = `${base}/set/${id}.tools.RAW?value=busted`;
786
879
  const urlGameon = `${base}/set/${id}.tools.RAW?value=gameon`;
787
880
  const urlGameshot = `${base}/set/${id}.tools.RAW?value=gameshot`;
881
+ const url180 = `${base}/set/${id}.tools.RAW?value=180`;
882
+ const urlMatchshot = `${base}/set/${id}.tools.RAW?value=matchshot`;
883
+ const urlTakeout = `${base}/set/${id}.tools.RAW?value=takeout`;
788
884
 
789
885
  await this.setStateAsync("tools.config.urlBusted", { val: urlBusted, ack: true });
790
886
  await this.setStateAsync("tools.config.urlGameon", { val: urlGameon, ack: true });
791
887
  await this.setStateAsync("tools.config.urlGameshot", { val: urlGameshot, ack: true });
888
+ await this.setStateAsync("tools.config.url180", { val: url180, ack: true });
889
+ await this.setStateAsync("tools.config.urlMatchshot", { val: urlMatchshot, ack: true });
890
+ await this.setStateAsync("tools.config.urlTakeout", { val: urlTakeout, ack: true });
792
891
 
793
- this.log.debug(`Updated Tools URLs: ${urlBusted}, ${urlGameon}, ${urlGameshot}`);
892
+ this.log.debug(
893
+ `Updated Tools URLs: ${urlBusted}, ${urlGameon}, ${urlGameshot}, ${url180}, ${urlMatchshot}, ${urlTakeout}`,
894
+ );
794
895
  }
795
896
 
796
897
  /**
@@ -999,6 +1100,13 @@ class Autodarts extends utils.Adapter {
999
1100
  if (this.versionTimer) {
1000
1101
  clearInterval(this.versionTimer);
1001
1102
  }
1103
+ // NEU: Alle individuellen Tools-Timer löschen
1104
+ if (this.resetTimers) {
1105
+ for (const id in this.resetTimers) {
1106
+ clearTimeout(this.resetTimers[id]);
1107
+ }
1108
+ }
1109
+ // Den alten einzelnen Timer (falls noch genutzt) ebenfalls löschen
1002
1110
  if (this.resetTimer) {
1003
1111
  clearTimeout(this.resetTimer);
1004
1112
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.autodarts",
3
- "version": "0.8.3",
3
+ "version": "1.0.0",
4
4
  "description": "Autodarts Autoscoring",
5
5
  "author": "skvarel <skvarel@inventwo.com>",
6
6
  "contributors": [