iobroker.parcelapp 0.2.0 → 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
@@ -22,7 +22,7 @@ ioBroker adapter that connects to the [parcel.app](https://parcelapp.net) API an
22
22
  - **Summary states** — active count, today count, combined delivery window
23
23
  - **Delivery time estimates** — today, tomorrow, in X days with combined time window
24
24
  - **Automatic polling** with configurable interval (5–60 minutes)
25
- - **Configurable cleanup** of delivered packages — auto-remove or keep as "Delivered"
25
+ - **Configurable cleanup** — auto-remove delivered packages or keep them until deleted in parcel.app
26
26
  - **Add deliveries** via sendTo message from scripts or other adapters
27
27
  - **Admin UI** with connection test, polling settings, and status language selection
28
28
  - **Multilingual status labels** (German/English)
@@ -44,7 +44,7 @@ ioBroker adapter that connects to the [parcel.app](https://parcelapp.net) API an
44
44
  |--------|-------------|---------|
45
45
  | **API Key** | Your parcel.app API key (get it at [web.parcelapp.net](https://web.parcelapp.net)) | — |
46
46
  | **Poll Interval** | How often to fetch updates (minutes) | 10 |
47
- | **Auto-remove delivered** | Remove delivered packages from states automatically | Yes |
47
+ | **Auto-remove delivered** | Remove delivered packages from states automatically. When disabled, they stay until deleted in parcel.app. | Yes |
48
48
  | **Status Language** | Language for status labels (German/English) | German |
49
49
 
50
50
  ---
@@ -94,6 +94,12 @@ parcelapp.0.
94
94
 
95
95
  ## Changelog
96
96
 
97
+ ### 0.2.2 (2026-03-28)
98
+ - Adapter-managed timers, CI on Windows/macOS, consistent i18n keys, full MIT license in README
99
+
100
+ ### 0.2.1 (2026-03-25)
101
+ - Robust error handling: rate limit detection, connection error deduplication, poll throttling
102
+
97
103
  ### 0.2.0 (2026-03-25)
98
104
  - Added option to keep delivered packages in states
99
105
  - Simplified admin UI to single page
@@ -111,12 +117,6 @@ parcelapp.0.
111
117
  ### 0.1.2 (2026-03-23)
112
118
  - Updated devDependencies
113
119
 
114
- ### 0.1.1 (2026-03-23)
115
- - Redesigned adapter logo
116
-
117
- ### 0.1.0 (2026-03-23)
118
- - Initial release
119
-
120
120
  Older changelog: [CHANGELOG.md](CHANGELOG.md)
121
121
 
122
122
  ---
@@ -137,10 +137,28 @@ This adapter is free and open source. If you find it useful, consider buying me
137
137
 
138
138
  ## License
139
139
 
140
- MIT License - see [LICENSE](LICENSE)
140
+ MIT License
141
141
 
142
142
  Copyright (c) 2026 krobi <krobi@power-dreams.com>
143
143
 
144
+ Permission is hereby granted, free of charge, to any person obtaining a copy
145
+ of this software and associated documentation files (the "Software"), to deal
146
+ in the Software without restriction, including without limitation the rights
147
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
148
+ copies of the Software, and to permit persons to whom the Software is
149
+ furnished to do so, subject to the following conditions:
150
+
151
+ The above copyright notice and this permission notice shall be included in all
152
+ copies or substantial portions of the Software.
153
+
154
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
155
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
156
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
157
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
158
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
159
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
160
+ SOFTWARE.
161
+
144
162
  ---
145
163
 
146
164
  *Developed with assistance from Claude.ai*
@@ -1,7 +1,6 @@
1
1
  {
2
- "aboutHeader": "Unterstütze diesen Adapter",
2
+ "supportHeader": "Unterstütze diesen Adapter",
3
3
  "aboutInfo": "Dieser Adapter ist kostenlos und Open Source. Wenn du ihn nützlich findest, unterstütze die Entwicklung gerne mit einer kleinen Spende.",
4
- "aboutTab": "Info",
5
4
  "apiKeyInfo": "Gib deinen parcel.app API-Schlüssel ein. Ein Premium-Abo wird benötigt. Den Schlüssel findest du unter web.parcelapp.net → API-Bereich.",
6
5
  "btn_checkConnection": "Verbindung testen",
7
6
  "donateKofi": "Unterstützen auf Ko-fi",
@@ -16,8 +16,7 @@
16
16
  "tooltip_language": "Language for delivery status labels (e.g. 'In Transit' vs 'Unterwegs')",
17
17
  "lang_de": "German",
18
18
  "lang_en": "English",
19
- "aboutTab": "About",
20
- "aboutHeader": "Support this Adapter",
19
+ "supportHeader": "Support this Adapter",
21
20
  "aboutInfo": "This adapter is free and open source. If you find it useful, please consider supporting its development with a small donation.",
22
21
  "donateKofi": "Support on Ko-fi",
23
22
  "donatePaypal": "Donate via PayPal"
@@ -1,7 +1,6 @@
1
1
  {
2
- "aboutHeader": "Apoya este adaptador",
2
+ "supportHeader": "Apoya este adaptador",
3
3
  "aboutInfo": "Este adaptador es gratuito y de código abierto. Si lo encuentras útil, considera apoyar el desarrollo con una pequeña donación.",
4
- "aboutTab": "Acerca de",
5
4
  "apiKeyInfo": "Introduce tu clave API de parcel.app. Se requiere una suscripción Premium. Obtén tu clave en web.parcelapp.net → panel API.",
6
5
  "btn_checkConnection": "Probar conexión",
7
6
  "donateKofi": "Apoyar en Ko-fi",
@@ -1,7 +1,6 @@
1
1
  {
2
- "aboutHeader": "Soutenez cet adaptateur",
2
+ "supportHeader": "Soutenez cet adaptateur",
3
3
  "aboutInfo": "Cet adaptateur est gratuit et open source. Si vous le trouvez utile, pensez à soutenir son développement par un petit don.",
4
- "aboutTab": "À propos",
5
4
  "apiKeyInfo": "Entrez votre clé API parcel.app. Un abonnement Premium est requis. Obtenez votre clé sur web.parcelapp.net → panneau API.",
6
5
  "btn_checkConnection": "Tester la connexion",
7
6
  "donateKofi": "Soutenir sur Ko-fi",
@@ -1,7 +1,6 @@
1
1
  {
2
- "aboutHeader": "Supporta questo adattatore",
2
+ "supportHeader": "Supporta questo adattatore",
3
3
  "aboutInfo": "Questo adattatore è gratuito e open source. Se lo trovi utile, considera di supportare lo sviluppo con una piccola donazione.",
4
- "aboutTab": "Info",
5
4
  "apiKeyInfo": "Inserisci la tua chiave API parcel.app. È necessario un abbonamento Premium. Ottieni la tua chiave su web.parcelapp.net → pannello API.",
6
5
  "btn_checkConnection": "Testa connessione",
7
6
  "donateKofi": "Supporta su Ko-fi",
@@ -1,7 +1,6 @@
1
1
  {
2
- "aboutHeader": "Steun deze adapter",
2
+ "supportHeader": "Steun deze adapter",
3
3
  "aboutInfo": "Deze adapter is gratis en open source. Als je hem nuttig vindt, overweeg dan de ontwikkeling te steunen met een kleine donatie.",
4
- "aboutTab": "Over",
5
4
  "apiKeyInfo": "Voer je parcel.app API-sleutel in. Een Premium-abonnement is vereist. Haal je sleutel op via web.parcelapp.net → API-paneel.",
6
5
  "btn_checkConnection": "Verbinding testen",
7
6
  "donateKofi": "Steunen op Ko-fi",
@@ -1,7 +1,6 @@
1
1
  {
2
- "aboutHeader": "Wesprzyj ten adapter",
2
+ "supportHeader": "Wesprzyj ten adapter",
3
3
  "aboutInfo": "Ten adapter jest darmowy i open source. Jeśli uważasz go za przydatny, rozważ wsparcie rozwoju niewielką darowizną.",
4
- "aboutTab": "O programie",
5
4
  "apiKeyInfo": "Wprowadź klucz API parcel.app. Wymagana subskrypcja Premium. Uzyskaj klucz na web.parcelapp.net → panel API.",
6
5
  "btn_checkConnection": "Testuj połączenie",
7
6
  "donateKofi": "Wesprzyj na Ko-fi",
@@ -1,7 +1,6 @@
1
1
  {
2
- "aboutHeader": "Apoie este adaptador",
2
+ "supportHeader": "Apoie este adaptador",
3
3
  "aboutInfo": "Este adaptador é gratuito e de código aberto. Se você o achar útil, considere apoiar o desenvolvimento com uma pequena doação.",
4
- "aboutTab": "Sobre",
5
4
  "apiKeyInfo": "Insira sua chave API do parcel.app. É necessária uma assinatura Premium. Obtenha sua chave em web.parcelapp.net → painel API.",
6
5
  "btn_checkConnection": "Testar Conexão",
7
6
  "donateKofi": "Apoiar no Ko-fi",
@@ -1,7 +1,6 @@
1
1
  {
2
- "aboutHeader": "Поддержите этот адаптер",
2
+ "supportHeader": "Поддержите этот адаптер",
3
3
  "aboutInfo": "Этот адаптер бесплатный и с открытым исходным кодом. Если он вам полезен, поддержите разработку небольшим пожертвованием.",
4
- "aboutTab": "О программе",
5
4
  "apiKeyInfo": "Введите API-ключ parcel.app. Требуется Premium-подписка. Получите ключ на web.parcelapp.net → раздел API.",
6
5
  "btn_checkConnection": "Проверить соединение",
7
6
  "donateKofi": "Поддержать на Ko-fi",
@@ -1,7 +1,6 @@
1
1
  {
2
- "aboutHeader": "Підтримайте цей адаптер",
2
+ "supportHeader": "Підтримайте цей адаптер",
3
3
  "aboutInfo": "Цей адаптер безкоштовний та з відкритим кодом. Якщо він вам корисний, підтримайте розробку невеликою пожертвою.",
4
- "aboutTab": "Про програму",
5
4
  "apiKeyInfo": "Введіть ваш API-ключ parcel.app. Потрібна Premium-підписка. Отримайте ключ на web.parcelapp.net → панель API.",
6
5
  "btn_checkConnection": "Перевірити з'єднання",
7
6
  "donateKofi": "Підтримати на Ko-fi",
@@ -1,7 +1,6 @@
1
1
  {
2
- "aboutHeader": "支持此适配器",
2
+ "supportHeader": "支持此适配器",
3
3
  "aboutInfo": "此适配器免费且开源。如果您觉得有用,请考虑通过小额捐赠支持开发。",
4
- "aboutTab": "关于",
5
4
  "apiKeyInfo": "输入你的 parcel.app API 密钥。需要 Premium 订阅。在 web.parcelapp.net → API 面板获取密钥。",
6
5
  "btn_checkConnection": "测试连接",
7
6
  "donateKofi": "在 Ko-fi 上支持",
@@ -79,13 +79,13 @@
79
79
  ],
80
80
  "xs": 12, "sm": 12, "md": 6, "lg": 6, "xl": 6
81
81
  },
82
- "aboutHeader": {
82
+ "_supportHeader": {
83
83
  "newLine": true,
84
84
  "type": "header",
85
- "text": "aboutHeader",
85
+ "text": "supportHeader",
86
86
  "size": 5
87
87
  },
88
- "aboutInfo": {
88
+ "_aboutInfo": {
89
89
  "type": "staticText",
90
90
  "text": "aboutInfo",
91
91
  "xs": 12, "sm": 12, "md": 12, "lg": 12, "xl": 12,
@@ -1 +1 @@
1
- {"version":3,"file":"parcel-client.d.ts","sourceRoot":"","sources":["../../src/lib/parcel-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACX,MAAM,SAAS,CAAC;AAKjB,yCAAyC;AACzC,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAA2B;IAE/C,2CAA2C;gBAC/B,MAAM,EAAE,MAAM;IAI1B;;;;OAIG;IACG,aAAa,CACjB,UAAU,GAAE,QAAQ,GAAG,QAAmB,GACzC,OAAO,CAAC,cAAc,EAAE,CAAC;IAqB5B;;;;OAIG;IACG,WAAW,CACf,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,mBAAmB,CAAC;IAS/B,kDAAkD;IAC5C,eAAe,IAAI,OAAO,CAAC,UAAU,CAAC;IAkB5C;;;;OAIG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK1D,mCAAmC;IAC7B,cAAc,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAatE;;;;;;;OAOG;IACH,OAAO,CAAC,OAAO;CAqEhB"}
1
+ {"version":3,"file":"parcel-client.d.ts","sourceRoot":"","sources":["../../src/lib/parcel-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACX,MAAM,SAAS,CAAC;AAKjB,yCAAyC;AACzC,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAA2B;IAE/C,2CAA2C;gBAC/B,MAAM,EAAE,MAAM;IAI1B;;;;OAIG;IACG,aAAa,CACjB,UAAU,GAAE,QAAQ,GAAG,QAAmB,GACzC,OAAO,CAAC,cAAc,EAAE,CAAC;IAqB5B;;;;OAIG;IACG,WAAW,CACf,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,mBAAmB,CAAC;IAS/B,kDAAkD;IAC5C,eAAe,IAAI,OAAO,CAAC,UAAU,CAAC;IAkB5C;;;;OAIG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK1D,mCAAmC;IAC7B,cAAc,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAatE;;;;;;;OAOG;IACH,OAAO,CAAC,OAAO;CAiFhB"}
@@ -137,6 +137,15 @@ class ParcelClient {
137
137
  const raw = Buffer.concat(chunks).toString("utf-8");
138
138
  if (res.statusCode &&
139
139
  (res.statusCode < 200 || res.statusCode >= 300)) {
140
+ if (res.statusCode === 429) {
141
+ const retryAfter = parseInt(res.headers["retry-after"] || "", 10);
142
+ const err = new Error("Rate limit exceeded");
143
+ err.code = "RATE_LIMITED";
144
+ // Use Retry-After header or default to 5 minutes
145
+ err.retryAfterSeconds = retryAfter > 0 ? retryAfter : 5 * 60;
146
+ reject(err);
147
+ return;
148
+ }
140
149
  const err = new Error(`HTTP ${res.statusCode}: ${res.statusMessage}`);
141
150
  err.code =
142
151
  res.statusCode === 401 || res.statusCode === 403
package/build/main.js CHANGED
@@ -40,12 +40,16 @@ require("./lib/types");
40
40
  const MIN_POLL_INTERVAL = 5;
41
41
  const MAX_POLL_INTERVAL = 60;
42
42
  const DEFAULT_POLL_INTERVAL = 10;
43
+ const MIN_POLL_GAP_MS = 60_000; // Minimum 60s between polls
43
44
  /** ioBroker adapter for parcel.app package tracking */
44
45
  class ParcelappAdapter extends utils.Adapter {
45
46
  client = null;
46
47
  stateManager = null;
47
- pollTimer = null;
48
+ pollTimer = undefined;
48
49
  isPolling = false;
50
+ lastPollTime = 0;
51
+ rateLimitedUntil = 0;
52
+ lastErrorCode = "";
49
53
  /** @param options Adapter options */
50
54
  constructor(options = {}) {
51
55
  super({
@@ -74,13 +78,13 @@ class ParcelappAdapter extends utils.Adapter {
74
78
  // Set up recurring poll
75
79
  const interval = Math.max(MIN_POLL_INTERVAL, Math.min(MAX_POLL_INTERVAL, this.config.pollInterval ?? DEFAULT_POLL_INTERVAL));
76
80
  const intervalMs = interval * 60 * 1000;
77
- this.pollTimer = setInterval(() => void this.poll(), intervalMs);
81
+ this.pollTimer = this.setInterval(() => void this.poll(), intervalMs);
78
82
  this.log.info(`Parcel tracking started — polling every ${interval} minutes`);
79
83
  }
80
84
  onUnload(callback) {
81
85
  if (this.pollTimer) {
82
- clearInterval(this.pollTimer);
83
- this.pollTimer = null;
86
+ this.clearInterval(this.pollTimer);
87
+ this.pollTimer = undefined;
84
88
  }
85
89
  void this.setState("info.connection", { val: false, ack: true });
86
90
  callback();
@@ -138,15 +142,59 @@ class ParcelappAdapter extends utils.Adapter {
138
142
  }
139
143
  }
140
144
  }
145
+ /**
146
+ * Classify an error for deduplication and log-level decisions.
147
+ *
148
+ * @param error The error to classify
149
+ */
150
+ classifyError(error) {
151
+ if (error.code === "RATE_LIMITED") {
152
+ return "RATE_LIMITED";
153
+ }
154
+ if (error.code === "INVALID_API_KEY") {
155
+ return "INVALID_API_KEY";
156
+ }
157
+ // Network errors: DNS, connection refused, no internet
158
+ if (error.code === "ENOTFOUND" ||
159
+ error.code === "ECONNREFUSED" ||
160
+ error.code === "ECONNRESET" ||
161
+ error.code === "ENETUNREACH" ||
162
+ error.code === "EAI_AGAIN") {
163
+ return "NETWORK";
164
+ }
165
+ if (error.message.includes("timeout") || error.code === "ETIMEDOUT") {
166
+ return "TIMEOUT";
167
+ }
168
+ return error.code || "UNKNOWN";
169
+ }
141
170
  async poll() {
142
171
  if (this.isPolling || !this.client || !this.stateManager) {
143
172
  return;
144
173
  }
174
+ const now = Date.now();
175
+ // Skip if rate limited
176
+ if (now < this.rateLimitedUntil) {
177
+ const waitMin = Math.ceil((this.rateLimitedUntil - now) / 60_000);
178
+ this.log.debug(`Skipping poll — rate limited for ${waitMin} more minute(s)`);
179
+ return;
180
+ }
181
+ // Throttle: minimum gap between polls
182
+ if (now - this.lastPollTime < MIN_POLL_GAP_MS) {
183
+ this.log.debug("Skipping poll — too soon after last poll");
184
+ return;
185
+ }
145
186
  this.isPolling = true;
187
+ this.lastPollTime = now;
146
188
  try {
147
189
  // When keeping delivered packages, use "recent" to get them from API
148
190
  const autoRemove = this.config.autoRemoveDelivered !== false;
149
191
  const deliveries = await this.client.getDeliveries(autoRemove ? "active" : "recent");
192
+ // Reset error state on success
193
+ this.rateLimitedUntil = 0;
194
+ if (this.lastErrorCode) {
195
+ this.log.info("Connection restored");
196
+ this.lastErrorCode = "";
197
+ }
150
198
  await this.setStateAsync("info.connection", { val: true, ack: true });
151
199
  // Filter deliveries based on auto-remove setting
152
200
  const visibleDeliveries = autoRemove
@@ -170,11 +218,28 @@ class ParcelappAdapter extends utils.Adapter {
170
218
  }
171
219
  catch (err) {
172
220
  const error = err;
173
- if (error.code === "INVALID_API_KEY") {
221
+ // Classify the error
222
+ const errorCode = this.classifyError(error);
223
+ const isRepeat = errorCode === this.lastErrorCode;
224
+ this.lastErrorCode = errorCode;
225
+ if (error.code === "RATE_LIMITED") {
226
+ const cooldownSec = error.retryAfterSeconds || 5 * 60;
227
+ this.rateLimitedUntil = Date.now() + cooldownSec * 1000;
228
+ this.log.warn(`Rate limit hit — pausing API requests for ${Math.ceil(cooldownSec / 60)} minute(s)`);
229
+ }
230
+ else if (error.code === "INVALID_API_KEY") {
231
+ // Always log — user must fix config
174
232
  this.log.error("Invalid API key — please check your parcel.app API key");
175
233
  }
176
- else if (error.message.includes("timeout")) {
177
- this.log.error(`API request timeout: ${error.message}`);
234
+ else if (isRepeat) {
235
+ // Same error as last time — don't spam the log
236
+ this.log.debug(`Poll failed (ongoing): ${error.message}`);
237
+ }
238
+ else if (errorCode === "NETWORK") {
239
+ this.log.warn(`Cannot reach parcel.app API — will keep retrying`);
240
+ }
241
+ else if (errorCode === "TIMEOUT") {
242
+ this.log.warn(`API request timeout — will retry next cycle`);
178
243
  }
179
244
  else {
180
245
  this.log.error(`Poll failed: ${error.message}`);
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "parcelapp",
4
- "version": "0.2.0",
4
+ "version": "0.2.2",
5
5
  "news": {
6
+ "0.2.2": {
7
+ "en": "Adapter-managed timers, CI on Windows/macOS, consistent admin UI i18n keys, full MIT license in README",
8
+ "de": "Adapter-verwaltete Timer, CI auf Windows/macOS, konsistente Admin-UI i18n-Keys, vollständige MIT-Lizenz in README",
9
+ "ru": "Таймеры, управляемые адаптером, CI на Windows/macOS, согласованные ключи i18n в Admin UI, полная лицензия MIT в README",
10
+ "pt": "Timers gerenciados pelo adaptador, CI no Windows/macOS, chaves i18n consistentes na UI admin, licença MIT completa no README",
11
+ "nl": "Adapter-beheerde timers, CI op Windows/macOS, consistente admin-UI i18n-sleutels, volledige MIT-licentie in README",
12
+ "fr": "Minuteries gérées par l adaptateur, CI sur Windows/macOS, clés i18n cohérentes dans l interface admin, licence MIT complète dans README",
13
+ "it": "Timer gestiti dall adattatore, CI su Windows/macOS, chiavi i18n coerenti nell interfaccia admin, licenza MIT completa nel README",
14
+ "es": "Temporizadores gestionados por el adaptador, CI en Windows/macOS, claves i18n consistentes en la UI de admin, licencia MIT completa en README",
15
+ "pl": "Timery zarządzane przez adapter, CI na Windows/macOS, spójne klucze i18n w admin UI, pełna licencja MIT w README",
16
+ "uk": "Таймери, керовані адаптером, CI на Windows/macOS, узгоджені ключі i18n в Admin UI, повна ліцензія MIT в README",
17
+ "zh-cn": "适配器管理的定时器,Windows/macOS CI,一致的管理界面 i18n 键,README 中的完整 MIT 许可证"
18
+ },
19
+ "0.2.1": {
20
+ "en": "Robust error handling: API rate limit detection, connection error deduplication, poll throttling",
21
+ "de": "Robuste Fehlerbehandlung: Erkennung von API-Ratenlimits, Deduplizierung von Verbindungsfehlern, Polling-Drosselung",
22
+ "ru": "Надежная обработка ошибок: обнаружение ограничения скорости API, дедупликация ошибок соединения, регулирование опроса.",
23
+ "pt": "Tratamento robusto de erros: detecção de limite de taxa de API, desduplicação de erros de conexão, otimização de pesquisa",
24
+ "nl": "Robuuste foutafhandeling: detectie van API-snelheidslimieten, deduplicatie van verbindingsfouten, poll-throttling",
25
+ "fr": "Gestion robuste des erreurs : détection de limite de débit API, déduplication des erreurs de connexion, limitation des interrogations",
26
+ "it": "Gestione efficace degli errori: rilevamento del limite di velocità dell'API, deduplicazione degli errori di connessione, limitazione del poll",
27
+ "es": "Manejo sólido de errores: detección de límite de tasa de API, deduplicación de errores de conexión, limitación de encuestas",
28
+ "pl": "Solidna obsługa błędów: wykrywanie limitów szybkości interfejsu API, deduplikacja błędów połączenia, ograniczanie odpytywania",
29
+ "uk": "Надійна обробка помилок: виявлення обмеження швидкості API, дедуплікація помилок підключення, регулювання опитування",
30
+ "zh-cn": "强大的错误处理:API 速率限制检测、连接错误重复数据删除、轮询限制"
31
+ },
6
32
  "0.2.0": {
7
33
  "en": "Added option to keep delivered packages, simplified admin UI, removed summary.json state",
8
34
  "de": "Option zum Beibehalten gelieferter Pakete hinzugefügt, Admin-Benutzeroberfläche vereinfacht, Status „summary.json“ entfernt",
@@ -67,32 +93,6 @@
67
93
  "pl": "Zaktualizowano zależności deweloperskie",
68
94
  "uk": "Оновлено залежності розробки",
69
95
  "zh-cn": "更新开发依赖"
70
- },
71
- "0.1.1": {
72
- "en": "Redesigned adapter logo, fixed repochecker issues",
73
- "de": "Adapter-Logo überarbeitet, Repochecker-Probleme behoben",
74
- "ru": "Обновлён логотип адаптера, исправлены проблемы repochecker",
75
- "pt": "Logo do adaptador redesenhado, problemas do repochecker corrigidos",
76
- "nl": "Adapter-logo opnieuw ontworpen, repochecker-problemen opgelost",
77
- "fr": "Logo de l'adaptateur redessiné, problèmes repochecker corrigés",
78
- "it": "Logo dell'adattatore ridisegnato, problemi repochecker risolti",
79
- "es": "Logo del adaptador rediseñado, problemas de repochecker corregidos",
80
- "pl": "Przeprojektowano logo adaptera, naprawiono problemy repochecker",
81
- "uk": "Оновлено логотип адаптера, виправлено проблеми repochecker",
82
- "zh-cn": "重新设计适配器图标,修复 repochecker 问题"
83
- },
84
- "0.1.0": {
85
- "en": "Initial release — track packages from 300+ carriers via parcel.app",
86
- "de": "Erstveröffentlichung — Pakete von 300+ Versandunternehmen über parcel.app verfolgen",
87
- "ru": "Первый выпуск — отслеживание посылок от 300+ перевозчиков через parcel.app",
88
- "pt": "Lançamento inicial — rastreie pacotes de mais de 300 transportadoras via parcel.app",
89
- "nl": "Eerste release — volg pakketten van 300+ vervoerders via parcel.app",
90
- "fr": "Version initiale — suivez vos colis de plus de 300 transporteurs via parcel.app",
91
- "it": "Prima versione — traccia pacchi da più di 300 corrieri tramite parcel.app",
92
- "es": "Versión inicial — rastrea paquetes de más de 300 transportistas a través de parcel.app",
93
- "pl": "Pierwsze wydanie — śledź przesyłki od 300+ przewoźników przez parcel.app",
94
- "uk": "Перший випуск — відстеження посилок від 300+ перевізників через parcel.app",
95
- "zh-cn": "初始版本 — 通过 parcel.app 追踪 300+ 快递公司的包裹"
96
96
  }
97
97
  },
98
98
  "titleLang": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.parcelapp",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "ioBroker adapter for parcel.app — track packages from 300+ carriers",
5
5
  "author": {
6
6
  "name": "krobi",