New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

iobroker.accuweather

Package Overview
Dependencies
Maintainers
0
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

iobroker.accuweather - npm Package Compare versions

Comparing version 2.0.0 to 2.0.1

admin/i18n/de/translations.json

99

admin/words.js
/*global systemDictionary:true */
"use strict";
/*
+===================== DO NOT MODIFY ======================+
| This file was generated by translate-adapter, please use |
| `translate-adapter adminLanguages2words` to update it. |
+===================== DO NOT MODIFY ======================+
*/
'use strict';
systemDictionary = {
"accuweather adapter settings": {
"en": "Adapter settings for accuweather",
"de": "Adaptereinstellungen für accuweather",
"ru": "Настройки адаптера для accuweather",
"pt": "Configurações do adaptador para accuweather",
"nl": "Adapterinstellingen voor accuweather",
"fr": "Paramètres d'adaptateur pour accuweather",
"it": "Impostazioni dell'adattatore per accuweather",
"es": "Ajustes del adaptador para accuweather",
"pl": "Ustawienia adaptera dla accuweather",
"zh-cn": "accuweather的适配器设置"
},
"apiKey": {
"en": "API Key",
"de": "API-Schlüssel",
"ru": "Ключ API",
"pt": "Chave API",
"nl": "API sleutel",
"fr": "clé API",
"it": "Chiave API",
"es": "Clave API",
"pl": "Klucz API",
"zh-cn": "API密钥"
},
"loKey": {
"en": "Location Key",
"de": "Standortschlüssel",
"ru": "Ключ местоположения",
"pt": "Chave de localização",
"nl": "Locatiesleutel",
"fr": "Clé de localisation",
"it": "Chiave di posizione",
"es": "Clave de ubicación",
"pl": "Klucz lokalizacji",
"zh-cn": "位置键"
},
"language": {
"en": "Language",
"de": "Sprache",
"ru": "Язык",
"pt": "Língua",
"nl": "Taal",
"fr": "La langue",
"it": "linguaggio",
"es": "Idioma",
"pl": "Język",
"zh-cn": "语言"
},
"api_help": {
"en": "To get API Key, register on https://developer.accuweather.com/ and create application in \"My Apps\" menu",
"de": "Um einen API-Schlüssel zu erhalten, registrieren Sie sich unter https://developer.accuweather.com/ und erstellen Sie eine Anwendung im Menü \"Meine Apps\"",
"ru": "Чтобы получить API Key, зарегистрируйтесь на https://developer.accuweather.com/ и создайте приложение в меню «Мои приложения»",
"pt": "Para obter a chave da API, registre-se em https://developer.accuweather.com/ e crie um aplicativo no menu \"Meus aplicativos\"",
"nl": "Registreer de API Key op https://developer.accuweather.com/ en maak een applicatie in het menu \"Mijn apps\"",
"fr": "Pour obtenir la clé API, inscrivez-vous sur https://developer.accuweather.com/ et créez une application dans le menu \"Mes applications\".",
"it": "Per ottenere la chiave API, registrati su https://developer.accuweather.com/ e crea un'applicazione nel menu \"Le mie app\"",
"es": "Para obtener la clave API, regístrese en https://developer.accuweather.com/ y cree una aplicación en el menú \"Mis aplicaciones\"",
"pl": "Aby uzyskać klucz API, zarejestruj się na https://developer.accuweather.com/ i utwórz aplikację w menu „Moje aplikacje”",
"zh-cn": "要获取API密钥,请在https://developer.accuweather.com/上注册,然后在“我的应用程序”菜单中创建应用程序"
},
"REGISTER": {
"en": "REGISTER",
"de": "REGISTRIEREN",
"ru": "ЗАРЕГИСТРИРОВАТЬСЯ",
"pt": "REGISTO",
"nl": "REGISTREREN",
"fr": "REGISTRE",
"it": "REGISTRARE",
"es": "REGISTRO",
"pl": "ZAREJESTROWAĆ",
"zh-cn": "寄存器"
},
"lo_help": {
"en": "In order to get location key, go to https://www.accuweather.com/ and enter your city name, or try to enter your coordinates (latitude, longitude). Your location key wil be the number at the end of URL.",
"de": "Um den Standortschlüssel zu erhalten, gehen Sie zu https://www.accuweather.com/ und geben Sie Ihren Städtenamen ein oder versuchen Sie, Ihre Koordinaten (Breitengrad, Längengrad) einzugeben. Ihr Standortschlüssel ist die Nummer am Ende der URL.",
"ru": "Чтобы получить ключ местоположения, перейдите по адресу https://www.accuweather.com/ и введите название своего города или попробуйте ввести свои координаты (широта, долгота). Ваш ключ местоположения будет номером в конце URL.",
"pt": "Para obter a chave de localização, vá para https://www.accuweather.com/ e insira o nome da sua cidade ou tente inserir suas coordenadas (latitude, longitude). A sua chave de localização será o número no final do URL.",
"nl": "Om de locatiesleutel te krijgen, ga naar https://www.accuweather.com/ en voer je plaatsnaam in, of probeer je coördinaten in te voeren (lengte- en breedtegraad). Uw locatiesleutel is het nummer aan het einde van de URL.",
"fr": "Pour obtenir la clé de localisation, accédez à la page https://www.accuweather.com/ et entrez le nom de votre ville ou essayez d'entrer vos coordonnées (latitude, longitude). Votre clé de localisation sera le numéro à la fin de l'URL.",
"it": "Per ottenere la chiave di posizione, vai su https://www.accuweather.com/ e inserisci il nome della tua città, oppure prova a inserire le tue coordinate (latitudine, longitudine). La chiave di posizione sarà il numero alla fine dell'URL.",
"es": "Para obtener la clave de ubicación, vaya a https://www.accuweather.com/ e ingrese el nombre de su ciudad, o intente ingresar sus coordenadas (latitud, longitud). Su clave de ubicación será el número al final de la URL.",
"pl": "Aby uzyskać klucz lokalizacji, przejdź na stronę https://www.accuweather.com/ i wprowadź nazwę swojego miasta lub spróbuj wpisać współrzędne (szerokość, długość). Twój klucz lokalizacji będzie liczbą na końcu adresu URL.",
"zh-cn": "要获取位置密钥,请访问https://www.accuweather.com/并输入您的城市名称,或尝试输入您的坐标(纬度,经度)。您的位置键将是URL末尾的数字。"
}
"REGISTER": { "en": "REGISTER", "de": "REGISTRIEREN", "ru": "ЗАРЕГИСТРИРОВАТЬСЯ", "pt": "REGISTO", "nl": "REGISTREREN", "fr": "REGISTRE", "it": "REGISTRARE", "es": "REGISTRO", "pl": "ZAREJESTROWAĆ", "uk": "ЗАРЕЄСТРУВАТИСЯ", "zh-cn": "寄存器"},
"accuweather adapter settings": { "en": "Adapter settings for accuweather", "de": "Adaptereinstellungen für accuweather", "ru": "Настройки адаптера для accuweather", "pt": "Configurações do adaptador para accuweather", "nl": "Adapterinstellingen voor accuweather", "fr": "Paramètres d'adaptateur pour accuweather", "it": "Impostazioni dell'adattatore per accuweather", "es": "Ajustes del adaptador para accuweather", "pl": "Ustawienia adaptera dla accuweather", "uk": "Налаштування адаптера для accuweather", "zh-cn": "accuweather的适配器设置"},
"apiKey": { "en": "API Key", "de": "API-Schlüssel", "ru": "Ключ API", "pt": "Chave API", "nl": "API sleutel", "fr": "clé API", "it": "Chiave API", "es": "Clave API", "pl": "Klucz API", "uk": "Ключ API", "zh-cn": "API密钥"},
"api_help": { "en": "To get API Key, register on https://developer.accuweather.com/ and create application in \"My Apps\" menu", "de": "Um einen API-Schlüssel zu erhalten, registrieren Sie sich unter https://developer.accuweather.com/ und erstellen Sie eine Anwendung im Menü \"Meine Apps\"", "ru": "Чтобы получить API Key, зарегистрируйтесь на https://developer.accuweather.com/ и создайте приложение в меню «Мои приложения»", "pt": "Para obter a chave da API, registre-se em https://developer.accuweather.com/ e crie um aplicativo no menu \"Meus aplicativos\"", "nl": "Registreer de API Key op https://developer.accuweather.com/ en maak een applicatie in het menu \"Mijn apps\"", "fr": "Pour obtenir la clé API, inscrivez-vous sur https://developer.accuweather.com/ et créez une application dans le menu \"Mes applications\".", "it": "Per ottenere la chiave API, registrati su https://developer.accuweather.com/ e crea un'applicazione nel menu \"Le mie app\"", "es": "Para obtener la clave API, regístrese en https://developer.accuweather.com/ y cree una aplicación en el menú \"Mis aplicaciones\"", "pl": "Aby uzyskać klucz API, zarejestruj się na https://developer.accuweather.com/ i utwórz aplikację w menu „Moje aplikacje”", "uk": "Щоб отримати ключ API, зареєструйтеся на сайті https://developer.accuweather.com/ і створіть програму в меню «Мої програми».", "zh-cn": "要获取API密钥,请在https://developer.accuweather.com/上注册,然后在“我的应用程序”菜单中创建应用程序"},
"language": { "en": "Language", "de": "Sprache", "ru": "Язык", "pt": "Língua", "nl": "Taal", "fr": "La langue", "it": "linguaggio", "es": "Idioma", "pl": "Język", "uk": "Мова", "zh-cn": "语言"},
"loKey": { "en": "Location Key", "de": "Standortschlüssel", "ru": "Ключ местоположения", "pt": "Chave de localização", "nl": "Locatiesleutel", "fr": "Clé de localisation", "it": "Chiave di posizione", "es": "Clave de ubicación", "pl": "Klucz lokalizacji", "uk": "Ключ розташування", "zh-cn": "位置键"},
"lo_help": { "en": "In order to get location key, go to https://www.accuweather.com/ and enter your city name, or try to enter your coordinates (latitude, longitude). Your location key wil be the number at the end of URL.", "de": "Um den Standortschlüssel zu erhalten, gehen Sie zu https://www.accuweather.com/ und geben Sie Ihren Städtenamen ein oder versuchen Sie, Ihre Koordinaten (Breitengrad, Längengrad) einzugeben. Ihr Standortschlüssel ist die Nummer am Ende der URL.", "ru": "Чтобы получить ключ местоположения, перейдите по адресу https://www.accuweather.com/ и введите название своего города или попробуйте ввести свои координаты (широта, долгота). Ваш ключ местоположения будет номером в конце URL.", "pt": "Para obter a chave de localização, vá para https://www.accuweather.com/ e insira o nome da sua cidade ou tente inserir suas coordenadas (latitude, longitude). A sua chave de localização será o número no final do URL.", "nl": "Om de locatiesleutel te krijgen, ga naar https://www.accuweather.com/ en voer je plaatsnaam in, of probeer je coördinaten in te voeren (lengte- en breedtegraad). Uw locatiesleutel is het nummer aan het einde van de URL.", "fr": "Pour obtenir la clé de localisation, accédez à la page https://www.accuweather.com/ et entrez le nom de votre ville ou essayez d'entrer vos coordonnées (latitude, longitude). Votre clé de localisation sera le numéro à la fin de l'URL.", "it": "Per ottenere la chiave di posizione, vai su https://www.accuweather.com/ e inserisci il nome della tua città, oppure prova a inserire le tue coordinate (latitudine, longitudine). La chiave di posizione sarà il numero alla fine dell'URL.", "es": "Para obtener la clave de ubicación, vaya a https://www.accuweather.com/ e ingrese el nombre de su ciudad, o intente ingresar sus coordenadas (latitud, longitud). Su clave de ubicación será el número al final de la URL.", "pl": "Aby uzyskać klucz lokalizacji, przejdź na stronę https://www.accuweather.com/ i wprowadź nazwę swojego miasta lub spróbuj wpisać współrzędne (szerokość, długość). Twój klucz lokalizacji będzie liczbą na końcu adresu URL.", "uk": "Щоб отримати ключ розташування, перейдіть на сторінку https://www.accuweather.com/ і введіть назву свого міста або спробуйте ввести свої координати (широта, довгота). Ваш ключ місцезнаходження буде числом у кінці URL-адреси.", "zh-cn": "要获取位置密钥,请访问https://www.accuweather.com/并输入您的城市名称,或尝试输入您的坐标(纬度,经度)。您的位置键将是URL末尾的数字。"},
};
{
"common": {
"name": "accuweather",
"version": "2.0.0",
"news": {
"2.0.0": {
"en": "Production release",
"de": "Produktionsfreigabe",
"ru": "Первая Версия",
"pt": "Lançamento de produção",
"nl": "Productie release",
"fr": "Production",
"it": "Rilascio di produzione",
"es": "Lanzamiento de la producción",
"pl": "Dopuszczenie do produkcji",
"zh-cn": "生产发布"
},
"0.1.0": {
"en": "initial release",
"de": "Erstveröffentlichung",
"ru": "Начальная версия",
"pt": "lançamento inicial",
"nl": "Eerste uitgave",
"fr": "Première version",
"it": "Versione iniziale",
"es": "Versión inicial",
"pl": "Pierwsze wydanie",
"zh-cn": "首次出版"
},
"0.0.1": {
"en": "initial release",
"de": "Erstveröffentlichung",
"ru": "Начальная версия",
"pt": "lançamento inicial",
"nl": "Eerste uitgave",
"fr": "Première version",
"it": "Versione iniziale",
"es": "Versión inicial",
"pl": "Pierwsze wydanie",
"zh-cn": "首次出版"
}
},
"title": "AccuWeather",
"titleLang": {
"en": "AccuWeather",
"de": "AccuWeather",
"ru": "AccuWeather",
"pt": "AccuWeather",
"nl": "AccuWeather",
"fr": "AccuWeather",
"it": "AccuWeather",
"es": "AccuWeather",
"pl": "AccuWeather",
"zh-cn": "机构AccuWeather"
},
"desc": {
"en": "Weather forecast using AccuWeather API",
"de": "Wettervorhersage mit AccuWeather API",
"ru": "Прогноз погоды с использованием AccuWeather API",
"pt": "Previsão do tempo usando a API AccuWeather",
"nl": "Weersverwachting met AccuWeather API",
"fr": "Prévisions météorologiques à l'aide de l'API AccuWeather",
"it": "Previsioni del tempo utilizzando l'API AccuWeather",
"es": "Pronóstico del tiempo usando AccuWeather API",
"pl": "Prognoza pogody za pomocą interfejsu API AccuWeather",
"zh-cn": "使用AccuWeather API的天气预报"
},
"authors": [
"algar42 <igor.aleschenkov@gmail.com>"
],
"keywords": [
"Weather",
"AccuWeather",
"Forecast"
],
"license": "MIT",
"platform": "Javascript/Node.js",
"main": "main.js",
"icon": "accuweather.png",
"enabled": true,
"extIcon": "https://raw.githubusercontent.com/algar42/ioBroker.accuweather/master/admin/accuweather.png",
"readme": "https://github.com/algar42/ioBroker.accuweather/blob/master/README.md",
"loglevel": "info",
"mode": "daemon",
"type": "weather",
"compact": true,
"materialize": true,
"dependencies": [
{
"js-controller": ">=1.4.2"
}
]
},
"native": {
"apiKey": "",
"loKey": "",
"language": "en-us"
},
"objects": [],
"instanceObjects": []
"common": {
"name": "accuweather",
"version": "2.0.1",
"news": {
"2.0.1": {
"en": "BREAKING: Requires Nodejs 20 or higher\nBREAKING: Command states are now buttons and only respond to ack=false. \nadmin option: No data is updated on adapter startup (default: true). \napikey renamed and encrypted\nDependencies and eslint updated\nAdd nextHour.CloudCover",
"de": "BREAKING: Erfordert Nodejs 20 oder höher\nBREAKING: Befehlszustände sind jetzt Tasten und reagieren nur auf ack=false.\nadmin-Option: Beim Adapter-Startup werden keine Daten aktualisiert (Standard: true).\napikey umbenannt und verschlüsselt\nAbhängigkeiten und eslint aktualisiert\nNextHour.CloudCover hinzufügen",
"ru": "20 или более\nВЫВОДЫ: Командные состояния теперь являются кнопками и отвечают только на ack=false.\nadmin опция: Данные не обновляются о запуске адаптера (по умолчанию: True).\napikey переименован и зашифрован\nЗависимость и уклонение\nДобавить следующийHour.CloudCover",
"pt": "BREAKING: Requer Nodejs 20 ou superior\nBREAKING: Os estados de comando agora são botões e só respondem ao ack=false.\nopção admin: Nenhum dado é atualizado na inicialização do adaptador (padrão: verdadeiro).\napikey renomeado e criptografado\nDependências e eslint atualizado\nAdicionar nextHour.CloudCover",
"nl": "Breaking: Vereist Nodejs 20 of hoger\nOpdrachtstaten zijn nu knoppen en reageren alleen op ack=false.\nadmin optie: Er worden geen gegevens bijgewerkt bij het opstarten van de adapter (standaard: waar).\napikey hernoemd en gecodeerd\nAfhankelijkheden en eslint bijgewerkt\nVoeg volgende uur toe.CloudCover",
"fr": "BREAKING: Nécessite Nodejs 20 ou plus\nLes états de commande sont maintenant des boutons et ne répondent qu'à ack=false.\noption administrateur & #160;: Aucune donnée n'est mise à jour au démarrage de l'adaptateur (par défaut: true).\napikey renommé et chiffré\nDépendances et essence mises à jour\nAjouter heure suivante.CloudCover",
"it": "BREAKING: Richiede Nodejs 20 o più\nBREAKING: Gli stati di comando sono ora pulsanti e rispondono solo a ack=false.\nopzione admin: Nessun dato viene aggiornato sull'avvio dell'adattatore (default: true).\napikey rinominato e crittografato\nDipendenze ed eslint aggiornati\nAggiungi il prossimo.CloudCover",
"es": "Requiere Nodejs 20 o superior\nLos estados de mando son ahora botones y sólo responden a ack=false.\nopción de administración: No se actualizan datos sobre el arranque del adaptador (por defecto: verdadero).\napikey renombrado y cifrado\nDependencias y datos actualizados\nAñade siguienteHour.CloudCover",
"pl": "BREAKING: wymaga Nodejs 20 lub wyższy\nBREAKING: stany poleceń są teraz przyciskami i tylko odpowiadają na ack = false.\nopcja admin: Brak aktualizacji danych przy starcie adaptera (domyślnie: true).\napikey przemianowany i zaszyfrowany\nZaktualizowane zależności i eslint\nDodaj nextHour.CloudCover",
"uk": "BREAKING: Вимагає Nodejs 20 або вище\nBREAKING: Командні стани тепер кнопки і тільки відповідають ack=false.\nопція адміністратора: Немає даних оновлюється на запуску адаптера (за замовчуванням: true).\napikey перейменований і зашифрований\nЗалежність і eslint оновлено\nДодати наступнеHour.CloudCover",
"zh-cn": "需要20个或以上的节点\n命令状态现在是按键,只回应阿克=虚构.\n管理选项 : 没有更新适配器启动数据( 默认: true) .\napikey 重命名并加密\n依赖和Eslint 更新\n添加下一个 Hour. CloudCover"
},
"1.5.0": {
"en": "limit updates to once an hour, this fixes part of issue #273.\nAdapter requires js-controller >= 5 and admin >= 6 now\nNode 22 support has been added to testing\nDependencies have been updated",
"de": "Updates auf einmal pro Stunde limitiert, dies repariert einen Teil der Fehlermeldung #273.\nAdapter benötigt js-controller >= 5 und admin >= 6 jetzt\nNode 22 Unterstützung wurde zur Prüfung hinzugefügt\nAbhängigkeiten wurden aktualisiert",
"ru": "ограничить обновления раз в час, это исправляет часть выпуска #273.\nАдаптер требует js-контроллер >= 5 и admin >= 6 сейчас\nПоддержка Node 22 была добавлена к тестированию\nЗависимость обновлена",
"pt": "limite atualizações para uma vez por hora, isso corrige parte do problema #273.\nAdapter requer js-controller >= 5 e admin >= 6 agora\nNode 22 suporte foi adicionado ao teste\nAs dependências foram atualizadas",
"nl": "limiet updates tot eenmaal per uur, dit lost deel van probleem #273.\nJs-controller vereist 5 en admin 6 nu\nNode 22 ondersteuning is toegevoegd aan het testen\nAfhankelijkheden zijn bijgewerkt",
"fr": "limiter les mises à jour à une fois par heure, cela corrige une partie du numéro 273.\nAdaptateur nécessite js-controller >= 5 et administrateur >= 6 maintenant\nLe support Node 22 a été ajouté au test\nLes dépendances ont été actualisées",
"it": "limitare gli aggiornamenti di una volta all'ora, questo risolve parte del problema #273.\nAdattatore richiede js-controller >= 5 e admin >= 6 ora\nIl supporto Node 22 è stato aggiunto ai test\nLe dipendenze sono state aggiornate",
"es": "limitar las actualizaciones una vez por hora, esto fija parte del número #273.\nAdaptador requiere js-controller 5 y admin= 6 ahora\nSe ha añadido apoyo Nodo 22 a las pruebas\nSe han actualizado las dependencias",
"pl": "limit aktualizacje raz na godzinę, to naprawia część wydania # 273.\nAdapter wymaga sterownika js- > = 5 i admin > = 6 teraz\nDo testowania dodano wsparcie węzła 22\nZaktualizowano zależności",
"uk": "обмежити оновлення один раз на годину, це фіксує частину випуску #273.\nАдаптер вимагає js-controller >= 5 і admin >= 6 тепер\nДодано підтримку Node 22 для тестування\nЗалежність було оновлено",
"zh-cn": "将更新限制在每小时一次,这可以修复第273期的部分内容.\n适配器需要js控制器 QQ 第5条 行政 现在6个\n测试中增加了22号节点支持\n依赖关系已更新"
},
"1.4.0": {
"en": "Adapter requires node.js 18 and js-controller >= 5 now\nDependencies have been updated",
"de": "Adapter benötigt node.js 18 und js-controller >= 5 jetzt\nAbhängigkeiten wurden aktualisiert",
"ru": "Адаптер требует node.js 18 и js-controller >= 5 сейчас\nЗависимость обновлена",
"pt": "Adapter requer node.js 18 e js-controller >= 5 agora\nAs dependências foram atualizadas",
"nl": "Adapter vereist node.js 18 en js-controller Nu 5\nAfhankelijkheden zijn bijgewerkt",
"fr": "Adaptateur nécessite node.js 18 et js-controller >= 5 maintenant\nLes dépendances ont été actualisées",
"it": "Adattatore richiede node.js 18 e js-controller >= 5 ora\nLe dipendenze sono state aggiornate",
"es": "Adaptador requiere node.js 18 y js-controller √= 5 ahora\nSe han actualizado las dependencias",
"pl": "Adapter wymaga node.js 18 i sterownika js- > = 5 teraz\nZaktualizowano zależności",
"uk": "Адаптер вимагає node.js 18 і js-controller >= 5 тепер\nЗалежність було оновлено",
"zh-cn": "适配器需要节点.js 18和js控制器 QQ 现在5号\n依赖关系已更新"
},
"1.3.2": {
"en": "fixed: dependencies\nfixed: error message [object Object]",
"de": "fest: abhängigkeiten\nbehoben: Fehlermeldung [objekt]",
"ru": "фиксированный: зависимости\nисправлено: сообщение об ошибке [object Object]",
"pt": "corrigido: dependências\ncorrigido: mensagem de erro [objeto]",
"nl": "afhankelijkheid\nvergissing",
"fr": "fixes: dépendances\ncorrigé: message d'erreur [objet]",
"it": "fisso: dipendenze\nfisso: messaggio di errore [oggetto oggetto]",
"es": "fija: dependencias\nfijo: mensaje de error [objeto objeto]",
"pl": "zależność\nuruchomione: błędy wiadomości (pol.)",
"uk": "фіксована: залежності\nвиправлено: повідомлення про помилку [об'єкт]",
"zh-cn": "固定:取决于\n固定:错误信息[目标]"
},
"1.3.1": {
"en": "added the Wind Direction Text und Cloud Cover\nAdded json config",
"de": "windrichtung Text und Cloud Cover\nHinzugefügt json config",
"ru": "добавлено направление ветра Текст und Облачная крышка\nДобавлено json config",
"pt": "adicionou o texto de direção do vento und Cloud Cover\nAdicionado json config",
"nl": "voegde de Wind Direction Text und Cloud Cover toe\n_",
"fr": "ajouté la fenêtre de direction du vent Text und Cloud Cover\nAjouté json config",
"it": "aggiunto la direzione del vento Testo und Cloud Cover\nAggiunto json config",
"es": "añadido el texto dirección del viento und cubierta de nube\nAñadido json config",
"pl": "wprowadzono dyrekcję Wind Direction Text i Cloud Cover\nAdded json configig",
"uk": "додана хмарна кришка вітру\nДодано json config",
"zh-cn": "添加了Wind Direction案文 und Cloud Cover\n增编"
},
"1.2.4": {
"en": "dependencies update",
"de": "Abhängigkeiten aktualisieren",
"ru": "обновление зависимостей",
"pt": "atualização de dependências",
"nl": "afhankelijkheden bijwerken",
"fr": "mise à jour des dépendances",
"it": "aggiornamento delle dipendenze",
"es": "actualización de dependencias",
"pl": "aktualizacja zależności",
"zh-cn": "依赖更新",
"uk": "оновлення залежностей"
},
"1.2.3": {
"en": "HoursOfSun parameter added to Daily forecast",
"de": "HoursOfSun-Parameter zur täglichen Vorhersage hinzugefügt",
"ru": "В суточный прогноз добавлен параметр HoursOfSun",
"pt": "Parâmetro HoursOfSun adicionado à previsão diária",
"nl": "HoursOfSun-parameter toegevoegd aan dagelijkse voorspelling",
"fr": "Paramètre HoursOfSun ajouté aux prévisions quotidiennes",
"it": "Parametro HoursOfSun aggiunto alla previsione giornaliera",
"es": "Parámetro HoursOfSun agregado al pronóstico diario",
"pl": "Dodano parametr HoursOfSun do prognozy dziennej",
"zh-cn": "每日预测中添加了 hoursOfSun 参数",
"uk": "До щоденного прогнозу додано параметр HoursOfSun"
}
},
"titleLang": {
"en": "AccuWeather",
"de": "AccuWeather",
"ru": "AccuWeather",
"pt": "AccuWeather",
"nl": "AccuWeather",
"fr": "AccuWeather",
"it": "AccuWeather",
"es": "AccuWeather",
"pl": "AccuWeather",
"zh-cn": "机构AccuWeather",
"uk": "AccuWeather"
},
"desc": {
"en": "Weather forecast using AccuWeather API",
"de": "Wettervorhersage mit AccuWeather API",
"ru": "Прогноз погоды с использованием AccuWeather API",
"pt": "Previsão do tempo usando a API AccuWeather",
"nl": "Weersverwachting met AccuWeather API",
"fr": "Prévisions météorologiques à l'aide de l'API AccuWeather",
"it": "Previsioni del tempo utilizzando l'API AccuWeather",
"es": "Pronóstico del tiempo usando AccuWeather API",
"pl": "Prognoza pogody za pomocą interfejsu API AccuWeather",
"zh-cn": "使用AccuWeather API的天气预报",
"uk": "Прогноз погоди за допомогою AccuWeather API"
},
"authors": [
"algar42 <igor.aleschenkov@gmail.com>"
],
"keywords": [
"Weather",
"AccuWeather",
"Forecast"
],
"licenseInformation": {
"license": "MIT",
"type": "free"
},
"platform": "Javascript/Node.js",
"icon": "accuweather.png",
"enabled": true,
"extIcon": "https://raw.githubusercontent.com/iobroker-community-adapters/ioBroker.accuweather/master/admin/accuweather.png",
"readme": "https://github.com/iobroker-community-adapters/ioBroker.accuweather/blob/master/README.md",
"loglevel": "info",
"tier": 2,
"mode": "daemon",
"type": "weather",
"compact": true,
"materialize": true,
"adminUI": {
"config": "json"
},
"connectionType": "cloud",
"dataSource": "poll",
"dependencies": [
{
"js-controller": ">=6.0.11"
}
],
"globalDependencies": [
{
"admin": ">=6.17.14"
}
]
},
"native": {
"apiKeyEncrypted": "",
"loKey": "",
"language": "",
"apiCallProtection": true
},
"protectedNative": [
"apiKeyEncrypted"
],
"encryptedNative": [
"apiKeyEncrypted"
],
"objects": [],
"instanceObjects": []
}

@@ -1,97 +0,148 @@

"use strict";
const req = require("request");
'use strict';
const axios = require('axios');
//const moment = require("moment");
const queryString = require("query-string");
const queryString = require('qs');
/**
* Class representing the AccuWeather API.
*/
class Accuapi {
constructor(apiKey) {
this.apiKey = apiKey;
this.lokey = 335315;
this.query = {};
//this.adapter = adapter;
}
/**
* Create an instance of Accuapi.
*
* @param apiKey - The API key for accessing AccuWeather.
*/
constructor(apiKey) {
this.apiKey = apiKey;
this.lokey = 335315;
this.query = {};
//this.adapter = adapter;
}
localkey(lkey) {
// Unique ID that can be used to search for a specific location.
/**
* Set the location key.
*
* @param lkey - The location key.
* @returns The instance of Accuapi.
*/
localkey(lkey) {
// Unique ID that can be used to search for a specific location.
!lkey ? null : this.lokey = lkey;
return this;
}
!lkey ? null : (this.lokey = lkey);
return this;
}
timeInt(val) {
// Unique ID that can be used to search for a specific location.
/**
* Set the time interval.
*
* @param val - The time interval value.
* @returns Accuapi The instance of Accuapi.
*/
timeInt(val = '') {
// Unique ID that can be used to search for a specific location.
!val ? this.time = "hourly/1hour" : this.time = val;
return this;
}
!val ? (this.time = 'hourly/1hour') : (this.time = val);
return this;
}
language(lan) {
// http://apidev.accuweather.com/developers/languages
// String indicating the language in which to return the resource.
// Default value set to en-us.
/**
* Sets the language for the API request.
*
* @param lan - The language code in which to return the resource.
* Refer to http://apidev.accuweather.com/developers/languages for valid language codes.
* If not provided, the default value is 'en-us'.
* @returns The current instance of the API object to allow for method chaining.
*/
language(lan) {
// http://apidev.accuweather.com/developers/languages
// String indicating the language in which to return the resource.
// Default value set to en-us.
!lan ? null : this.query.language = lan;
return this;
}
!lan ? null : (this.query.language = lan);
return this;
}
details(bool) {
// Boolean value (true or false) specifies whether or not to include the full object.
//Default value set to false.
//(For location searches, details = true will return AccuWeather related details).
/**
* Set the details flag.
*
* @param bool - Specifies whether or not to include the full object.
* @returns The instance of Accuapi.
*/
details(bool) {
// Boolean value (true or false) specifies whether or not to include the full object.
// Default value set to false.
// (For location searches, details = true will return AccuWeather related details).
!bool ? null : this.query.details = bool;
return this;
}
!bool ? null : (this.query.details = bool);
return this;
}
metric(bool) {
// Boolean value (true or false) that specifies to return the data in either metric (=true) or imperial units.
/**
* Set the metric flag.
*
* @param bool - Specifies whether to return the data in metric units.
* @returns The instance of Accuapi.
*/
metric(bool) {
// Boolean value (true or false) that specifies to return the data in either metric (=true) or imperial units.
!bool ? null : this.query.metric = bool;
return this;
}
!bool ? null : (this.query.metric = bool);
return this;
}
generateReqUrl(current) {
if (current) {
this.url = `http://dataservice.accuweather.com/currentconditions/v1/${this.lokey}?apikey=${this.apiKey}`;
}
else {
this.url = `http://dataservice.accuweather.com/forecasts/v1/${this.time}/${this.lokey}?apikey=${this.apiKey}`;
}
this.query ? this.url += `&${queryString.stringify(this.query)}` : this.url;
}
/**
* Generates the request URL for the AccuWeather API.
*
* @param current - A boolean indicating whether to generate the URL for current conditions or forecasts.
* If true, the URL for current conditions is generated.
*/
generateReqUrl(current = false) {
if (current) {
this.url = `http://dataservice.accuweather.com/currentconditions/v1/${this.lokey}?apikey=${this.apiKey}`;
} else {
this.url = `http://dataservice.accuweather.com/forecasts/v1/${this.time}/${this.lokey}?apikey=${this.apiKey}`;
}
this.query ? (this.url += `&${queryString.stringify(this.query)}`) : this.url;
}
get() {
return new Promise((resolve, reject) => {
//
//const body = require("./test-data/daily.json");
//
this.generateReqUrl();
req({ url: this.url, json: true }, (err, res, body) => {
err ? reject(`Forecast cannot be retrieved. ERROR: ${err}`) : null;
res.statusCode !== 200 ? reject(`Forecast cannot be retrieved. Response: ${res.statusCode} ${res.statusMessage}`) : null;
resolve(body);
//log.info("response: " + body);
});
/**
* Retrieves the weather data from the AccuWeather API.
*
* @returns A promise that resolves to the weather data.
* @throws {Error} Throws an error if the forecast cannot be retrieved.
*/
get() {
this.generateReqUrl();
return axios
.get(this.url ? this.url : '')
.then(response => response.data)
.catch(error => {
throw new Error(
`Forecast cannot be retrieved. ERROR: ${(error.response && JSON.stringify(error.response.data)) || error.toString()}`,
);
});
}
});
/**
* Retrieves the current weather data from the AccuWeather API.
*
* @returns A promise that resolves to the current weather data.
* @throws {Error} Throws an error if the forecast cannot be retrieved.
*/
getCurrent() {
//
//const body = require("./test-data/currentCond.json");
//
this.generateReqUrl(true);
return axios
.get(this.url ? this.url : '')
.then(response => response.data)
.catch(error => {
throw new Error(
`Forecast cannot be retrieved. ERROR: ${(error.response && JSON.stringify(error.response.data)) || error.toString()}`,
);
});
}
getCurrent() {
return new Promise((resolve, reject) => {
//
//const body = require("./test-data/currentCond.json");
//
this.generateReqUrl(true);
req({ url: this.url, json: true }, (err, res, body) => {
err ? reject(`Forecast cannot be retrieved. ERROR: ${err}`) : null;
res.statusCode !== 200 ? reject(`Forecast cannot be retrieved. Response: ${res.statusCode} ${res.statusMessage}`) : null;
resolve(body);
//log.info("response: " + body);
});
});
}
}
module.exports = Accuapi;
{
"nextHour.LocalObservationDateTime": {
"type": "state",
"common": {
"name": "Forecast date",
"type": "string",
"read": "true",
"write": "false",
"role": "value.datetime"
},
"native": {}
"nextHour.LocalObservationDateTime": {
"type": "state",
"common": {
"name": "Forecast date",
"type": "string",
"read": true,
"write": false,
"role": "date"
},
"nextHour.WeatherIcon": {
"type": "state",
"common": {
"name": "Weather Icon",
"type": "number",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"nextHour.WeatherIcon": {
"type": "state",
"common": {
"name": "Weather Icon",
"type": "number",
"read": true,
"write": false,
"role": "value"
},
"nextHour.WeatherIconURL": {
"type": "state",
"common": {
"name": "Weather Icon URL",
"type": "string",
"read": "true",
"write": "false",
"role": "media.url"
},
"native": {}
"native": {}
},
"nextHour.WeatherIconURL": {
"type": "state",
"common": {
"name": "Weather Icon URL",
"type": "string",
"read": true,
"write": false,
"role": "media.url"
},
"nextHour.WeatherIconURLS": {
"type": "state",
"common": {
"name": "SVG Weather Icon URL",
"type": "string",
"read": "true",
"write": "false",
"role": "media.url"
},
"native": {}
"native": {}
},
"nextHour.WeatherIconURLS": {
"type": "state",
"common": {
"name": "SVG Weather Icon URL",
"type": "string",
"read": true,
"write": false,
"role": "weather.icon"
},
"nextHour.WeatherText": {
"type": "state",
"common": {
"name": "Weather Description",
"type": "string",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"nextHour.WeatherText": {
"type": "state",
"common": {
"name": "Weather Description",
"type": "string",
"read": true,
"write": false,
"role": "weather.state"
},
"nextHour.HasPrecipitation": {
"type": "state",
"common": {
"name": "Precipitation",
"type": "boolean",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"nextHour.HasPrecipitation": {
"type": "state",
"common": {
"name": "Precipitation",
"type": "boolean",
"read": true,
"write": false,
"role": "value"
},
"nextHour.PrecipitationType": {
"type": "state",
"common": {
"name": "Precipitation Description",
"type": "boolean",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"nextHour.PrecipitationType": {
"type": "state",
"common": {
"name": "Precipitation Description",
"type": "string",
"read": true,
"write": false,
"role": "value"
},
"nextHour.Temperature": {
"type": "state",
"common": {
"name": "Temperature",
"type": "number",
"read": "true",
"write": "false",
"role": "value.temperature",
"unit": "°C"
},
"native": {}
"native": {}
},
"nextHour.Temperature": {
"type": "state",
"common": {
"name": "Temperature",
"type": "number",
"read": true,
"write": false,
"role": "value.temperature",
"unit": "°C"
},
"nextHour.RealFeelTemperature": {
"type": "state",
"common": {
"name": "Feels Like Temperature",
"type": "number",
"read": "true",
"write": "false",
"role": "value.temperature",
"unit": "°C"
},
"native": {}
"native": {}
},
"nextHour.RealFeelTemperature": {
"type": "state",
"common": {
"name": "Feels Like Temperature",
"type": "number",
"read": true,
"write": false,
"role": "value.temperature.feelslike",
"unit": "°C"
},
"nextHour.RealFeelTemperatureShade": {
"type": "state",
"common": {
"name": "Shadow Temperature",
"type": "number",
"read": "true",
"write": "false",
"role": "value.temperature",
"unit": "°C"
},
"native": {}
"native": {}
},
"nextHour.RealFeelTemperatureShade": {
"type": "state",
"common": {
"name": "Shadow Temperature",
"type": "number",
"read": true,
"write": false,
"role": "value.temperature",
"unit": "°C"
},
"nextHour.DewPoint": {
"type": "state",
"common": {
"name": "Dew Point",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit": "°C"
},
"native": {}
"native": {}
},
"nextHour.DewPoint": {
"type": "state",
"common": {
"name": "Dew Point",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "°C"
},
"nextHour.WindSpeed":{
"type": "state",
"common": {
"name": "Wind Speed",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit": "km/h"
},
"native": {}
"native": {}
},
"nextHour.WindSpeed": {
"type": "state",
"common": {
"name": "Wind Speed",
"type": "number",
"read": true,
"write": false,
"role": "value.speed.wind",
"unit": "km/h"
},
"nextHour.WindDirection": {
"type": "state",
"common": {
"name": "Wind Direction",
"type": "string",
"read": "true",
"write": "false",
"role": "value",
"unit": "°"
},
"native": {}
"native": {}
},
"nextHour.WindDirection": {
"type": "state",
"common": {
"name": "Wind Direction",
"type": "number",
"read": true,
"write": false,
"role": "value.direction.wind",
"unit": "°"
},
"nextHour.WindGust": {
"type": "state",
"common": {
"name": "Wind Gust",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit": "km/h"
},
"native": {}
"native": {}
},
"nextHour.WindDirectionText": {
"type": "state",
"common": {
"name": "Wind Direction Text",
"type": "string",
"read": true,
"write": false,
"role": "value.direction.wind"
},
"nextHour.RelativeHumidity": {
"type": "state",
"common": {
"name": "Humidity",
"type": "number",
"read": "true",
"write": "false",
"role": "value.humidity",
"unit": "%"
},
"native": {}
"native": {}
},
"nextHour.WindGust": {
"type": "state",
"common": {
"name": "Wind Gust",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "km/h"
},
"nextHour.UVIndex": {
"type": "state",
"common": {
"name": "UV Index",
"type": "number",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"nextHour.RelativeHumidity": {
"type": "state",
"common": {
"name": "Humidity",
"type": "number",
"read": true,
"write": false,
"role": "value.humidity",
"unit": "%"
},
"nextHour.UVIndexText": {
"type": "state",
"common": {
"name": "UV Index Description",
"type": "string",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"nextHour.CloudCover": {
"type": "state",
"common": {
"name": "Cloud Cover",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "%"
},
"nextHour.Pressure": {
"type": "state",
"common": {
"name": "Pressure",
"type": "number",
"read": "true",
"write": "false",
"role": "value.pressure",
"unit":"mb"
},
"native": {}
"native": {}
},
"nextHour.UVIndex": {
"type": "state",
"common": {
"name": "UV Index",
"type": "number",
"read": true,
"write": false,
"role": "value"
},
"nextHour.PressureTendency": {
"type": "state",
"common": {
"name": "Ptressure Tendency",
"type": "string",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
}
"native": {}
},
"nextHour.UVIndexText": {
"type": "state",
"common": {
"name": "UV Index Description",
"type": "string",
"read": true,
"write": false,
"role": "value"
},
"native": {}
},
"nextHour.Pressure": {
"type": "state",
"common": {
"name": "Pressure",
"type": "number",
"read": true,
"write": false,
"role": "value.pressure",
"unit": "mb"
},
"native": {}
},
"nextHour.PressureTendency": {
"type": "state",
"common": {
"name": "Pressure Tendency",
"type": "string",
"read": true,
"write": false,
"role": "value"
},
"native": {}
}
}
{
"Daily.dayn.Date": {
"type": "state",
"common": {
"name": "Forecast date",
"type": "string",
"read": "true",
"write": "false",
"role": "value.datetime"
},
"native": {}
"Daily.dayn.Date": {
"type": "state",
"common": {
"name": "Forecast date",
"type": "string",
"read": true,
"write": false,
"role": "date"
},
"Daily.dayn.Sunrise": {
"type": "state",
"common": {
"name": "Sunrise datetime",
"type": "string",
"read": "true",
"write": "false",
"role": "value.datetime"
},
"native": {}
"native": {}
},
"Daily.dayn.Sunrise": {
"type": "state",
"common": {
"name": "Sunrise datetime",
"type": "string",
"read": true,
"write": false,
"role": "date.sunrise"
},
"Daily.dayn.Sunset": {
"type": "state",
"common": {
"name": "Sunset datetime",
"type": "string",
"read": "true",
"write": "false",
"role": "value.datetime"
},
"native": {}
"native": {}
},
"Daily.dayn.Sunset": {
"type": "state",
"common": {
"name": "Sunset datetime",
"type": "string",
"read": true,
"write": false,
"role": "date.sunset"
},
"Daily.dayn.Temperature.Minimum": {
"type": "state",
"common": {
"name": "Temperature Min",
"type": "number",
"read": "true",
"write": "false",
"role": "value.temperature",
"unit": "°C"
},
"native": {}
"native": {}
},
"Daily.dayn.HoursOfSun": {
"type": "state",
"common": {
"name": "Hours of Sun",
"type": "number",
"read": true,
"write": false,
"role": "value"
},
"Daily.dayn.Temperature.Maximum": {
"type": "state",
"common": {
"name": "Temperature Max",
"type": "number",
"read": "true",
"write": "false",
"role": "value.temperature",
"unit": "°C"
},
"native": {}
"native": {}
},
"Daily.dayn.Temperature.Minimum": {
"type": "state",
"common": {
"name": "Temperature Min",
"type": "number",
"read": true,
"write": false,
"role": "value.temperature.min",
"unit": "°C"
},
"Daily.dayn.RealFeelTemperature.Minimum": {
"type": "state",
"common": {
"name": "Feels Like Temperature Min",
"type": "number",
"read": "true",
"write": "false",
"role": "value.temperature",
"unit": "°C"
},
"native": {}
"native": {}
},
"Daily.dayn.Temperature.Maximum": {
"type": "state",
"common": {
"name": "Temperature Max",
"type": "number",
"read": true,
"write": false,
"role": "value.temperature.max",
"unit": "°C"
},
"Daily.dayn.RealFeelTemperature.Maximum": {
"type": "state",
"common": {
"name": "Feels Like Temperature Max",
"type": "number",
"read": "true",
"write": "false",
"role": "value.temperature",
"unit": "°C"
},
"native": {}
"native": {}
},
"Daily.dayn.RealFeelTemperature.Minimum": {
"type": "state",
"common": {
"name": "Feels Like Temperature Min",
"type": "number",
"read": true,
"write": false,
"role": "value.temperature.feelslike.min",
"unit": "°C"
},
"Daily.dayn.dayPart.Icon": {
"type": "state",
"common": {
"name": "Weather Icon",
"type": "number",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"Daily.dayn.RealFeelTemperature.Maximum": {
"type": "state",
"common": {
"name": "Feels Like Temperature Max",
"type": "number",
"read": true,
"write": false,
"role": "value.temperature.feelslike.max",
"unit": "°C"
},
"Daily.dayn.dayPart.IconURL": {
"type": "state",
"common": {
"name": "Weather Icon URL",
"type": "string",
"read": "true",
"write": "false",
"role": "media.url"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.Icon": {
"type": "state",
"common": {
"name": "Weather Icon",
"type": "number",
"read": true,
"write": false,
"role": "value"
},
"Daily.dayn.dayPart.IconURLS": {
"type": "state",
"common": {
"name": "SVG Weather Icon URL",
"type": "string",
"read": "true",
"write": "false",
"role": "media.url"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.IconURL": {
"type": "state",
"common": {
"name": "Weather Icon URL",
"type": "string",
"read": true,
"write": false,
"role": "media.url"
},
"Daily.dayn.dayPart.IconPhrase": {
"type": "state",
"common": {
"name": "Weather Description",
"type": "string",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.IconURLS": {
"type": "state",
"common": {
"name": "SVG Weather Icon URL",
"type": "string",
"read": true,
"write": false,
"role": "weather.icon"
},
"Daily.dayn.dayPart.HasPrecipitation": {
"type": "state",
"common": {
"name": "Precipitation",
"type": "boolean",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.IconPhrase": {
"type": "state",
"common": {
"name": "Weather Description",
"type": "string",
"read": true,
"write": false,
"role": "weather.state"
},
"Daily.dayn.dayPart.ShortPhrase": {
"type": "state",
"common": {
"name": "Weather Description",
"type": "string",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.HasPrecipitation": {
"type": "state",
"common": {
"name": "Precipitation",
"type": "boolean",
"read": true,
"write": false,
"role": "value"
},
"Daily.dayn.dayPart.LongPhrase": {
"type": "state",
"common": {
"name": "Weather Description",
"type": "string",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.ShortPhrase": {
"type": "state",
"common": {
"name": "Weather Description",
"type": "string",
"read": true,
"write": false,
"role": "weather.state.description"
},
"Daily.dayn.dayPart.PrecipitationProbability": {
"type": "state",
"common": {
"name": "Precipitation Probability",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"%"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.LongPhrase": {
"type": "state",
"common": {
"name": "Weather Description",
"type": "string",
"read": true,
"write": false,
"role": "value"
},
"Daily.dayn.dayPart.ThunderstormProbability": {
"type": "state",
"common": {
"name": "Thunderstorm Probability",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"%"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.PrecipitationProbability": {
"type": "state",
"common": {
"name": "Precipitation Probability",
"type": "number",
"read": true,
"write": false,
"role": "value.precipitation",
"unit": "%"
},
"Daily.dayn.dayPart.RainProbability": {
"type": "state",
"common": {
"name": "Rain Probability",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"%"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.ThunderstormProbability": {
"type": "state",
"common": {
"name": "Thunderstorm Probability",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "%"
},
"Daily.dayn.dayPart.SnowProbability": {
"type": "state",
"common": {
"name": "Snow Probability",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"%"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.RainProbability": {
"type": "state",
"common": {
"name": "Rain Probability",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "%"
},
"Daily.dayn.dayPart.IceProbability": {
"type": "state",
"common": {
"name": "Ice Probability",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"%"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.SnowProbability": {
"type": "state",
"common": {
"name": "Snow Probability",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "%"
},
"Daily.dayn.dayPart.WindSpeed":{
"type": "state",
"common": {
"name": "Wind Speed",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit": "km/h"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.IceProbability": {
"type": "state",
"common": {
"name": "Ice Probability",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "%"
},
"Daily.dayn.dayPart.WindDirection": {
"type": "state",
"common": {
"name": "Wind Direction",
"type": "string",
"read": "true",
"write": "false",
"role": "value",
"unit": "°"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.WindSpeed": {
"type": "state",
"common": {
"name": "Wind Speed",
"type": "number",
"read": true,
"write": false,
"role": "value.speed.wind",
"unit": "km/h"
},
"Daily.dayn.dayPart.WindGust": {
"type": "state",
"common": {
"name": "Wind Gust",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit": "km/h"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.WindDirection": {
"type": "state",
"common": {
"name": "Wind Direction",
"type": "string",
"read": true,
"write": false,
"role": "value.direction.wind",
"unit": "°"
},
"Daily.dayn.dayPart.RainVolume":{
"type": "state",
"common": {
"name": "Rain Amount",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"mm"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.WindGust": {
"type": "state",
"common": {
"name": "Wind Gust",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "km/h"
},
"Daily.dayn.dayPart.SnowVolume":{
"type": "state",
"common": {
"name": "Snow Amount",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"mm"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.RainVolume": {
"type": "state",
"common": {
"name": "Rain Amount",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "mm"
},
"Daily.dayn.dayPart.IceVolume":{
"type": "state",
"common": {
"name": "Ice Amount",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"mm"
},
"native": {}
"native": {}
},
"Daily.dayn.dayPart.SnowVolume": {
"type": "state",
"common": {
"name": "Snow Amount",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "mm"
},
"Daily.dayn.dayPart.TotalLiquidVolume": {
"type": "state",
"common": {
"name": "Total Precipitation Amount",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"mm"
},
"native": {}
}
"native": {}
},
"Daily.dayn.dayPart.IceVolume": {
"type": "state",
"common": {
"name": "Ice Amount",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "mm"
},
"native": {}
},
"Daily.dayn.dayPart.TotalLiquidVolume": {
"type": "state",
"common": {
"name": "Total Precipitation Amount",
"type": "number",
"read": true,
"write": false,
"role": "value.precipitation",
"unit": "mm"
},
"native": {}
}
}

@@ -1,66 +0,102 @@

"use strict";
'use strict';
async function createSummaryObjects(adapter) {
const obj = require('./summaryObject.json');
await adapter.setObjectNotExistsAsync('Summary', {
type: 'channel',
common: {
name: 'Weather Summary',
},
native: {},
});
const _obj = Object.assign({}, obj);
for (const key in _obj) {
adapter.setObjectNotExists(key, _obj[key]);
}
}
async function createNextHourForecatObjects(hour, adapter) {
const obj = require("./nextHourObject.json");
await adapter.setObjectAsync("Hourly.h" + hour, {
type: "channel",
common: {
name: `Hour ${hour} Forecast`
},
native: {},
});
const obj = require('./nextHourObject.json');
await adapter.setObjectNotExistsAsync(`Hourly.h${hour}`, {
type: 'channel',
common: {
name: `Hour ${hour} Forecast`,
},
native: {},
});
const _obj = Object.assign({}, obj);
for (const key in obj) {
await adapter.setObjectAsync(key.replace("nextHour", "Hourly.h" + hour), obj[key]);
}
for (const key in _obj) {
const measure = {};
const nkey = key.replace('nextHour', `Hourly.h${hour}`);
const role = _obj[key].common.role;
measure[nkey] = Object.assign({}, _obj[key]);
measure[nkey].common = Object.assign({}, _obj[key].common);
if (measure[nkey].common.role) {
measure[nkey].common.role = `${role}.forecast.${hour}`;
}
adapter.log.debug(`key: ${nkey}, role:${JSON.stringify(measure[nkey].common.role)}, base: ${role}`);
adapter.setObjectNotExists(nkey, measure[nkey]);
}
}
async function createCurrentConditionObjects(adapter) {
const obj = require("./currentCondObject.json");
await adapter.setObjectAsync("Current", {
type: "channel",
common: {
name: `Current Conditions`
},
native: {},
});
const obj = require('./currentCondObject.json');
await adapter.setObjectNotExistsAsync('Current', {
type: 'channel',
common: {
name: 'Current Conditions',
},
native: {},
});
for (const key in obj) {
await adapter.setObjectAsync(key.replace("nextHour", "Current"), obj[key]);
}
for (const key in obj) {
adapter.setObjectNotExists(key.replace('nextHour', 'Current'), obj[key]);
}
}
async function createDailyForecastObjects(adapter) {
const obj = require('./DailyObject.json');
for (let i = 1; i <= 5; i++) {
await adapter.setObjectNotExistsAsync(`Daily.Day${i}`, {
type: 'channel',
common: {
name: `Day ${i} Forecast`,
},
native: {},
});
const _obj = Object.assign({}, obj);
const obj = require("./DailyObject.json");
for (let i = 1; i <= 5; i++) {
await adapter.setObjectAsync("Daily.Day" + i, {
type: "channel",
common: {
name: `Day ${i} Forecast`
},
native: {},
});
for (const key in obj) {
if (!key.indexOf("dayPart.")) { await adapter.setObjectAsync(key.replace("dayn.", "Day" + i + "."), obj[key]); }
else {
["Day", "Night"].forEach(async function (dp) {
await adapter.setObjectAsync(key.replace("dayn.", "Day" + i + ".").replace("dayPart.", dp + "."), obj[key]);
});
}
}
}
for (const key in _obj) {
const measure = {};
let nkey = '';
const role = _obj[key].common.role;
if (!key.indexOf('dayPart.')) {
nkey = key.replace('dayn.', `Day${i}.`);
measure[nkey] = Object.assign({}, _obj[key]);
measure[nkey].common = Object.assign({}, _obj[key].common);
if (measure[nkey].common.role) {
measure[nkey].common.role = `${role}.forecast.${i - 1}`;
}
adapter.setObjectNotExists(nkey, measure[nkey]);
} else {
['Day', 'Night'].forEach(dp => {
nkey = key.replace('dayn.', `Day${i}.`).replace('dayPart.', `${dp}.`);
measure[nkey] = Object.assign({}, _obj[key]);
measure[nkey].common = Object.assign({}, _obj[key].common);
if (measure[nkey].common.role) {
measure[nkey].common.role = `${role}.forecast.${i - 1}`;
}
adapter.setObjectNotExists(nkey, measure[nkey]);
});
}
}
}
}
function createHourlyForecastObjects(adapter) {
for (let hr = 0; hr < 24; hr++) {
createNextHourForecatObjects(hr, adapter);
}
async function createHourlyForecastObjects(adapter) {
for (let hr = 0; hr < 24; hr++) {
await createNextHourForecatObjects(hr, adapter);
}
}

@@ -71,2 +107,3 @@

exports.createCurrentConditionObjects = createCurrentConditionObjects;
exports.createDailyForecastObjects = createDailyForecastObjects;
exports.createDailyForecastObjects = createDailyForecastObjects;
exports.createSummaryObjects = createSummaryObjects;
{
"nextHour.DateTime": {
"type": "state",
"common": {
"name": "Forecast date",
"type": "string",
"read": "true",
"write": "false",
"role": "value.datetime"
},
"native": {}
"nextHour.DateTime": {
"type": "state",
"common": {
"name": "Forecast date",
"type": "string",
"read": true,
"write": false,
"role": "date"
},
"nextHour.WeatherIcon": {
"type": "state",
"common": {
"name": "Weather Icon",
"type": "number",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"nextHour.WeatherIcon": {
"type": "state",
"common": {
"name": "Weather Icon",
"type": "number",
"read": true,
"write": false,
"role": "value"
},
"nextHour.WeatherIconURL": {
"type": "state",
"common": {
"name": "Weather Icon URL",
"type": "string",
"read": "true",
"write": "false",
"role": "media.url"
},
"native": {}
"native": {}
},
"nextHour.CloudCover": {
"type": "state",
"common": {
"name": "CloudCover",
"type": "number",
"read": true,
"write": false,
"role": "value"
},
"nextHour.WeatherIconURLS": {
"type": "state",
"common": {
"name": "SVG Weather Icon URL",
"type": "string",
"read": "true",
"write": "false",
"role": "media.url"
},
"native": {}
"native": {}
},
"nextHour.WeatherIconURL": {
"type": "state",
"common": {
"name": "Weather Icon URL",
"type": "string",
"read": true,
"write": false,
"role": "media.url"
},
"nextHour.IconPhrase": {
"type": "state",
"common": {
"name": "Weather Description",
"type": "string",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"nextHour.WeatherIconURLS": {
"type": "state",
"common": {
"name": "SVG Weather Icon URL",
"type": "string",
"read": true,
"write": false,
"role": "weather.icon"
},
"nextHour.HasPrecipitation": {
"type": "state",
"common": {
"name": "Precipitation",
"type": "boolean",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"nextHour.IconPhrase": {
"type": "state",
"common": {
"name": "Weather Description",
"type": "string",
"read": true,
"write": false,
"role": "weather.state"
},
"nextHour.Temperature": {
"type": "state",
"common": {
"name": "Temperature",
"type": "number",
"read": "true",
"write": "false",
"role": "value.temperature",
"unit": "°C"
},
"native": {}
"native": {}
},
"nextHour.HasPrecipitation": {
"type": "state",
"common": {
"name": "Precipitation",
"type": "boolean",
"read": true,
"write": false,
"role": "value"
},
"nextHour.RealFeelTemperature": {
"type": "state",
"common": {
"name": "Feels Like Temperature",
"type": "number",
"read": "true",
"write": "false",
"role": "value.temperature",
"unit": "°C"
},
"native": {}
"native": {}
},
"nextHour.Temperature": {
"type": "state",
"common": {
"name": "Temperature",
"type": "number",
"read": true,
"write": false,
"role": "value.temperature",
"unit": "°C"
},
"nextHour.DewPoint": {
"type": "state",
"common": {
"name": "Dew Point",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit": "°C"
},
"native": {}
"native": {}
},
"nextHour.RealFeelTemperature": {
"type": "state",
"common": {
"name": "Feels Like Temperature",
"type": "number",
"read": true,
"write": false,
"role": "value.temperature.feelslike",
"unit": "°C"
},
"nextHour.WindSpeed":{
"type": "state",
"common": {
"name": "Wind Speed",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit": "km/h"
},
"native": {}
"native": {}
},
"nextHour.DewPoint": {
"type": "state",
"common": {
"name": "Dew Point",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "°C"
},
"nextHour.WindDirection": {
"type": "state",
"common": {
"name": "Wind Direction",
"type": "string",
"read": "true",
"write": "false",
"role": "value",
"unit": "°"
},
"native": {}
"native": {}
},
"nextHour.WindSpeed": {
"type": "state",
"common": {
"name": "Wind Speed",
"type": "number",
"read": true,
"write": false,
"role": "value.speed.wind",
"unit": "km/h"
},
"nextHour.WindGust": {
"type": "state",
"common": {
"name": "Wind Gust",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit": "km/h"
},
"native": {}
"native": {}
},
"nextHour.WindDirection": {
"type": "state",
"common": {
"name": "Wind Direction",
"type": "string",
"read": true,
"write": false,
"role": "value.direction.wind",
"unit": "°"
},
"nextHour.RelativeHumidity": {
"type": "state",
"common": {
"name": "Humidity",
"type": "number",
"read": "true",
"write": "false",
"role": "value.humidity",
"unit": "%"
},
"native": {}
"native": {}
},
"nextHour.WindGust": {
"type": "state",
"common": {
"name": "Wind Gust",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "km/h"
},
"nextHour.UVIndex": {
"type": "state",
"common": {
"name": "UV Index",
"type": "number",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"nextHour.RelativeHumidity": {
"type": "state",
"common": {
"name": "Humidity",
"type": "number",
"read": true,
"write": false,
"role": "value.humidity",
"unit": "%"
},
"nextHour.UVIndexText": {
"type": "state",
"common": {
"name": "UV Index Description",
"type": "string",
"read": "true",
"write": "false",
"role": "value"
},
"native": {}
"native": {}
},
"nextHour.UVIndex": {
"type": "state",
"common": {
"name": "UV Index",
"type": "number",
"read": true,
"write": false,
"role": "value"
},
"nextHour.PrecipitationProbability": {
"type": "state",
"common": {
"name": "Precipitation Probability",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"%"
},
"native": {}
"native": {}
},
"nextHour.UVIndexText": {
"type": "state",
"common": {
"name": "UV Index Description",
"type": "string",
"read": true,
"write": false,
"role": "value"
},
"nextHour.RainProbability": {
"type": "state",
"common": {
"name": "Rain Probability",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"%"
},
"native": {}
"native": {}
},
"nextHour.PrecipitationProbability": {
"type": "state",
"common": {
"name": "Precipitation Probability",
"type": "number",
"read": true,
"write": false,
"role": "value.precipitation",
"unit": "%"
},
"nextHour.SnowProbability": {
"type": "state",
"common": {
"name": "Snow Probability",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"%"
},
"native": {}
"native": {}
},
"nextHour.RainProbability": {
"type": "state",
"common": {
"name": "Rain Probability",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "%"
},
"nextHour.IceProbability": {
"type": "state",
"common": {
"name": "Ice Probability",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"%"
},
"native": {}
"native": {}
},
"nextHour.SnowProbability": {
"type": "state",
"common": {
"name": "Snow Probability",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "%"
},
"nextHour.RainVolume":{
"type": "state",
"common": {
"name": "Rain Amount",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"mm"
},
"native": {}
"native": {}
},
"nextHour.IceProbability": {
"type": "state",
"common": {
"name": "Ice Probability",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "%"
},
"nextHour.SnowVolume":{
"type": "state",
"common": {
"name": "Snow Amount",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"mm"
},
"native": {}
"native": {}
},
"nextHour.RainVolume": {
"type": "state",
"common": {
"name": "Rain Amount",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "mm"
},
"nextHour.IceVolume":{
"type": "state",
"common": {
"name": "Ice Amount",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"mm"
},
"native": {}
"native": {}
},
"nextHour.SnowVolume": {
"type": "state",
"common": {
"name": "Snow Amount",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "mm"
},
"nextHour.TotalLiquidVolume": {
"type": "state",
"common": {
"name": "Total Precipitation Amount",
"type": "number",
"read": "true",
"write": "false",
"role": "value",
"unit":"mm"
},
"native": {}
}
"native": {}
},
"nextHour.IceVolume": {
"type": "state",
"common": {
"name": "Ice Amount",
"type": "number",
"read": true,
"write": false,
"role": "value",
"unit": "mm"
},
"native": {}
},
"nextHour.TotalLiquidVolume": {
"type": "state",
"common": {
"name": "Total Precipitation Amount",
"type": "number",
"read": true,
"write": false,
"role": "value.precipitation",
"unit": "mm"
},
"native": {}
}
}

@@ -1,14 +0,15 @@

const axios = require("axios");
const axios = require('axios');
/**
* Tests whether the given variable is a real object and not an Array
* @param {any} it The variable to test
* @returns {it is Record<string, any>}
*
* @param it The variable to test
* @returns
*/
function isObject(it) {
// This is necessary because:
// typeof null === 'object'
// typeof [] === 'object'
// [] instanceof Object === true
return Object.prototype.toString.call(it) === "[object Object]";
// This is necessary because:
// typeof null === 'object'
// typeof [] === 'object'
// [] instanceof Object === true
return Object.prototype.toString.call(it) === '[object Object]';
}

@@ -18,8 +19,11 @@

* Tests whether the given variable is really an Array
* @param {any} it The variable to test
* @returns {it is any[]}
*
* @param it The variable to test
* @returns
*/
function isArray(it) {
if (typeof Array.isArray === "function") return Array.isArray(it);
return Object.prototype.toString.call(it) === "[object Array]";
if (typeof Array.isArray === 'function') {
return Array.isArray(it);
}
return Object.prototype.toString.call(it) === '[object Array]';
}

@@ -29,16 +33,16 @@

* Translates text to the target language. Automatically chooses the right translation API.
* @param {string} text The text to translate
* @param {string} targetLang The target languate
* @param {string} [yandexApiKey] The yandex API key. You can create one for free at https://translate.yandex.com/developers
* @returns {Promise<string>}
*
* @param text The text to translate
* @param targetLang The target languate
* @param [yandexApiKey] The yandex API key. You can create one for free at https://translate.yandex.com/developers
* @returns
*/
async function translateText(text, targetLang, yandexApiKey) {
if (targetLang === "en") {
return text;
}
if (yandexApiKey) {
return await translateYandex(text, targetLang, yandexApiKey);
} else {
return await translateGoogle(text, targetLang);
}
if (targetLang === 'en') {
return text;
}
if (yandexApiKey) {
return await translateYandex(text, targetLang, yandexApiKey);
}
return await translateGoogle(text, targetLang);
}

@@ -48,21 +52,22 @@

* Translates text with Yandex API
* @param {string} text The text to translate
* @param {string} targetLang The target languate
* @param {string} [apiKey] The yandex API key. You can create one for free at https://translate.yandex.com/developers
* @returns {Promise<string>}
*
* @param text The text to translate
* @param targetLang The target languate
* @param [apiKey] The yandex API key. You can create one for free at https://translate.yandex.com/developers
* @returns
*/
async function translateYandex(text, targetLang, apiKey) {
if (targetLang === "zh-cn") {
targetLang = "zh";
}
try {
const url = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${encodeURIComponent(text)}&lang=en-${targetLang}`;
const response = await axios({url, timeout: 15000});
if (response.data && response.data["text"]) {
return response.data["text"][0];
}
throw new Error("Invalid response for translate request");
} catch (e) {
throw new Error(`Could not translate to "${targetLang}": ${e}`);
}
if (targetLang === 'zh-cn') {
targetLang = 'zh';
}
try {
const url = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${encodeURIComponent(text)}&lang=en-${targetLang}`;
const response = await axios({ url, timeout: 15000 });
if (response.data && response.data['text']) {
return response.data['text'][0];
}
throw new Error('Invalid response for translate request');
} catch (e) {
throw new Error(`Could not translate to "${targetLang}": ${e}`);
}
}

@@ -72,24 +77,25 @@

* Translates text with Google API
* @param {string} text The text to translate
* @param {string} targetLang The target languate
* @returns {Promise<string>}
*
* @param text The text to translate
* @param targetLang The target languate
* @returns
*/
async function translateGoogle(text, targetLang) {
try {
const url = `http://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}&ie=UTF-8&oe=UTF-8`;
const response = await axios({url, timeout: 15000});
if (isArray(response.data)) {
// we got a valid response
return response.data[0][0][0];
}
throw new Error("Invalid response for translate request");
} catch (e) {
throw new Error(`Could not translate to "${targetLang}": ${e}`);
}
try {
const url = `http://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}&ie=UTF-8&oe=UTF-8`;
const response = await axios({ url, timeout: 15000 });
if (isArray(response.data)) {
// we got a valid response
return response.data[0][0][0];
}
throw new Error('Invalid response for translate request');
} catch (e) {
throw new Error(`Could not translate to "${targetLang}": ${e}`);
}
}
module.exports = {
isArray,
isObject,
translateText
isArray,
isObject,
translateText,
};

@@ -1,2 +0,2 @@

"use strict";
'use strict';

@@ -9,416 +9,642 @@ /*

// you need to create an adapter
const utils = require("@iobroker/adapter-core");
const Accuapi = require("./lib/accuapi");
const nextHour = require("./lib/nexthour-obj");
const utils = require('@iobroker/adapter-core');
const AccuAPI = require('./lib/accuapi');
const nextHour = require('./lib/nexthour-obj');
let updateInterval = null;
let timeout1 = null;
let timeout2 = null;
// Load your modules here, e.g.:
// const fs = require("fs");
//let forecast = undefined;
class Accuweather extends utils.Adapter {
/**
* @param [options] - Optional settings for the adapter
*/
constructor(options = {}) {
super({
...options,
name: 'accuweather',
strictObjectChecks: false,
});
this.on('ready', this.onReady.bind(this));
this.on('stateChange', this.onStateChange.bind(this));
this.on('unload', this.onUnload.bind(this));
}
/**
* @param {Partial<ioBroker.AdapterOptions>} [options={}]
*/
constructor(options) {
super({
...options,
name: "accuweather",
});
this.on("ready", this.onReady.bind(this));
this.on("objectChange", this.onObjectChange.bind(this));
this.on("stateChange", this.onStateChange.bind(this));
// this.on("message", this.onMessage.bind(this));
this.on("unload", this.onUnload.bind(this));
}
getCardinalDirection(angle) {
if (typeof angle === 'string') {
angle = parseInt(angle);
}
if (angle <= 0 || angle > 360 || typeof angle === 'undefined') {
return '☈';
}
const arrows = {
north: '↑N',
north_east: '↗NE',
east: '→E',
south_east: '↘SE',
south: '↓S',
south_west: '↙SW',
west: '←W',
north_west: '↖NW',
};
const directions = Object.keys(arrows);
const degree = 360 / directions.length;
angle = angle + degree / 4;
for (let i = 0; i < directions.length; i++) {
if (angle >= i * degree && angle < (i + 1) * degree) {
return arrows[directions[i]];
}
}
return arrows['north'];
}
async setDailyStates(obj) {
const days = obj.DailyForecasts;
try {
for (let day = 1; day <= 5; day++) {
const json = days[day - 1];
for (const key in json) {
let dt = null;
switch (key) {
case 'Date':
dt = new Date(json[key]);
await this.setState(`Daily.Day${day}.${key}`, {
val: json[key],
ack: true,
});
await this.setState(`Summary.DateTime_d${day}`, {
val: json[key],
ack: true,
});
await this.setState(`Summary.DayOfWeek_d${day}`, {
val: dt.toLocaleString(this.config.language, {
weekday: 'short',
}),
ack: true,
});
break;
case 'Sun':
await this.setState(`Daily.Day${day}.Sunrise`, {
val: json[key]['Rise'],
ack: true,
});
await this.setState(`Daily.Day${day}.Sunset`, {
val: json[key]['Set'],
ack: true,
});
if (day === 1) {
await this.setState('Summary.Sunrise', {
val: json[key]['Rise'],
ack: true,
});
await this.setState('Summary.Sunset', {
val: json[key]['Set'],
ack: true,
});
}
break;
case 'HoursOfSun':
await this.setState(`Daily.Day${day}.HoursOfSun`, {
val: json[key],
ack: true,
});
if (day === 1) {
await this.setState('Summary.HoursOfSun', {
val: json[key],
ack: true,
});
}
break;
case 'Temperature':
await this.setState(`Daily.Day${day}.Temperature.Minimum`, {
val: json[key]['Minimum'].Value,
ack: true,
});
await this.setState(`Daily.Day${day}.Temperature.Maximum`, {
val: json[key]['Maximum'].Value,
ack: true,
});
await this.setState(`Summary.TempMin_d${day}`, {
val: json[key]['Minimum'].Value,
ack: true,
});
await this.setState(`Summary.TempMax_d${day}`, {
val: json[key]['Maximum'].Value,
ack: true,
});
break;
case 'RealFeelTemperature':
await this.setState(`Daily.Day${day}.RealFeelTemperature.Minimum`, {
val: json[key]['Minimum'].Value,
ack: true,
});
await this.setState(`Daily.Day${day}.RealFeelTemperature.Maximum`, {
val: json[key]['Maximum'].Value,
ack: true,
});
break;
case 'Day':
case 'Night':
{
const json1 = json[key];
for (const key1 in json1) {
if (typeof json1[key1] !== 'object') {
await this.setState(`Daily.Day${day}.${key}.${key1}`, {
val: json1[key1],
ack: true,
});
if (key1 === 'Icon') {
await this.setState(`Daily.Day${day}.${key}.IconURL`, {
val: `https://developer.accuweather.com/sites/default/files/${String(json1[key1]).padStart(2, '0')}-s.png`,
ack: true,
});
await this.setState(`Daily.Day${day}.${key}.IconURLS`, {
val: `http://vortex.accuweather.com/adc2010/images/slate/icons/${String(json1[key1]).padStart(2, '0')}.svg`,
ack: true,
});
if (key === 'Day') {
await this.setState(`Summary.WeatherIconURL_d${day}`, {
val: `http://vortex.accuweather.com/adc2010/images/slate/icons/${String(json1[key1]).padStart(2, '0')}.svg`,
ack: true,
});
await this.setState(`Summary.WeatherIcon_d${day}`, {
val: json1[key1],
ack: true,
});
}
} else if (key === 'Day') {
if (key1 === 'IconPhrase') {
await this.setState(`Summary.WeatherText_d${day}`, {
val: json1[key1],
ack: true,
});
} else {
await this.setState(`Summary.${key1}_d${day}`, {
val: json1[key1],
ack: true,
});
}
}
} else if (typeof json1[key1] == 'object') {
if (json1[key1]['Value'] !== undefined) {
if (['TotalLiquid', 'Rain', 'Snow', 'Ice'].includes(key1)) {
await this.setState(`Daily.Day${day}.${key}.${key1}Volume`, {
val: json1[key1].Value,
ack: true,
});
if (key === 'Day' && key1 === 'TotalLiquid') {
await this.setState(`Summary.TotalLiquidVolume_d${day}`, {
val: json1[key1].Value,
ack: true,
});
}
} else {
await this.setState(`Daily.Day${day}.${key}.${key1}`, {
val: json1[key1].Value,
ack: true,
});
}
} else if (key1 === 'Wind') {
await this.setState(`Daily.Day${day}.${key}.WindSpeed`, {
val: json1[key1].Speed.Value,
ack: true,
});
await this.setState(`Daily.Day${day}.${key}.WindDirection`, {
val: json1[key1].Direction.Degrees,
ack: true,
});
if (key === 'Day') {
await this.setState(`Summary.WindSpeed_d${day}`, {
val: json1[key1].Speed.Value,
ack: true,
});
await this.setState(`Summary.WindDirection_d${day}`, {
val: json1[key1].Direction.Degrees,
ack: true,
});
await this.setState(`Summary.WindDirectionStr_d${day}`, {
val: this.getCardinalDirection(json1[key1].Direction.Degrees),
ack: true,
});
}
} else if (key1 === 'WindGust') {
await this.setState(`Daily.Day${day}.${key}.WindGust`, {
val: json1[key1].Speed.Value,
ack: true,
});
}
}
}
}
break;
default:
break;
}
}
}
} catch (err) {
this.log.error(String(err));
}
}
async setNextHourStates(obj, item, hour) {
const json = obj[item];
try {
for (const key in json) {
if (typeof json[key] !== 'object') {
await this.setState(`Hourly.h${hour}.${key}`, {
val: json[key],
ack: true,
});
if (key === 'WeatherIcon') {
await this.setState(`Hourly.h${hour}.WeatherIconURL`, {
val: `https://developer.accuweather.com/sites/default/files/${String(json[key]).padStart(2, '0')}-s.png`,
ack: true,
});
await this.setState(`Hourly.h${hour}.WeatherIconURLS`, {
val: `http://vortex.accuweather.com/adc2010/images/slate/icons/${String(json[key]).padStart(2, '0')}.svg`,
ack: true,
});
}
} else if (typeof json[key] == 'object') {
if (json[key]['Value'] !== undefined) {
if (['TotalLiquid', 'Rain', 'Snow', 'Ice'].includes(key)) {
await this.setState(`Hourly.h${hour}.${key}Volume`, {
val: json[key].Value,
ack: true,
});
} else {
await this.setState(`Hourly.h${hour}.${key}`, {
val: json[key].Value,
ack: true,
});
}
} else if (key === 'Wind') {
await this.setState(`Hourly.h${hour}.WindSpeed`, {
val: json[key].Speed.Value,
ack: true,
});
await this.setState(`Hourly.h${hour}.WindDirection`, {
val: json[key].Direction.Degrees,
ack: true,
});
await this.setState(`Hourly.h${hour}.WindDirectionText`, {
val: json[key].Direction.Localized,
ack: true,
});
} else if (key === 'WindGust') {
await this.setState(`Hourly.h${hour}.WindGust`, {
val: json[key].Speed.Value,
ack: true,
});
}
}
}
} catch (err) {
this.log.error(String(err));
}
}
/**
* Is called when databases are connected and adapter received configuration.
*/
async setCurrentStates(obj) {
const json = obj[0];
try {
for (const key in json) {
//this.log.debug("Current: " + key + ": " + typeof json[key]);
if (typeof json[key] !== 'object' || json[key] == null) {
await this.setState(`Current.${key}`, { val: json[key], ack: true });
async setDailyStates(obj) {
const days = obj.DailyForecasts;
try {
for (let day = 1; day <= 5; day++) {
let json = days[day - 1];
for (let key in json) {
switch (key) {
case "Date":
await this.setStateAsync("Daily.Day" + day + "." + key, { val: json[key], ack: true });
break;
case "Sun":
await this.setStateAsync("Daily.Day" + day + ".Sunrise", { val: json[key]["Rise"], ack: true });
await this.setStateAsync("Daily.Day" + day + ".Sunset", { val: json[key]["Set"], ack: true });
break;
case "Temperature":
await this.setStateAsync("Daily.Day" + day + ".Temperature.Minimum", { val: json[key]["Minimum"].Value, ack: true });
await this.setStateAsync("Daily.Day" + day + ".Temperature.Maximum", { val: json[key]["Maximum"].Value, ack: true });
break;
case "RealFeelTemperature":
await this.setStateAsync("Daily.Day" + day + ".RealFeelTemperature.Minimum", { val: json[key]["Minimum"].Value, ack: true });
await this.setStateAsync("Daily.Day" + day + ".RealFeelTemperature.Maximum", { val: json[key]["Maximum"].Value, ack: true });
break;
case "Day":
case "Night":
{
let json1 = json[key];
for (let key1 in json1) {
if (typeof json1[key1] !== "object") {
await this.setStateAsync("Daily.Day" + day + "." + key + "." + key1, { val: json1[key1], ack: true });
if (key1==="Icon") {
await this.setStateAsync("Daily.Day" + day + "." + key + ".IconURL", { val: "https://developer.accuweather.com/sites/default/files/"+String(json1[key1]).padStart(2, "0")+"-s.png", ack: true });
await this.setStateAsync("Daily.Day" + day + "." + key + ".IconURLS", { val: "http://vortex.accuweather.com/adc2010/images/slate/icons/"+String(json1[key1]).padStart(2, "0")+".svg", ack: true });
}
//https://developer.accuweather.com/sites/default/files/36-s.png
//http://vortex.accuweather.com/adc2010/images/slate/icons/1.svg
} else
if (typeof json1[key1] == "object") {
if (key === 'WeatherIcon') {
await this.setState('Current.WeatherIconURL', {
val: `https://developer.accuweather.com/sites/default/files/${String(json[key]).padStart(2, '0')}-s.png`,
ack: true,
});
await this.setState('Current.WeatherIconURLS', {
val: `http://vortex.accuweather.com/adc2010/images/slate/icons/${String(json[key]).padStart(2, '0')}.svg`,
ack: true,
});
await this.setState('Summary.WeatherIconURL', {
val: `http://vortex.accuweather.com/adc2010/images/slate/icons/${String(json[key]).padStart(2, '0')}.svg`,
ack: true,
});
await this.setState('Summary.WeatherIcon', {
val: json[key],
ack: true,
});
} else if (key === 'LocalObservationDateTime') {
const dt = new Date(json[key]);
const dow = dt.toLocaleString(this.config.language, {
weekday: 'short',
});
await this.setState('Summary.CurrentDateTime', {
val: json[key],
ack: true,
});
await this.setState('Summary.DayOfWeek', { val: dow, ack: true });
this.log.debug(
`Date ${dt}, dow: ${dt.toLocaleString(this.config.language, { weekday: 'short' })}`,
);
} else {
await this.setState(`Summary.${key}`, {
val: json[key],
ack: true,
});
}
} else if (json[key] !== null) {
if (json[key].Metric !== undefined) {
//this.log.debug(key + ": " + json[key].Metric.Value);
await this.setState(`Current.${key}`, {
val: json[key].Metric.Value,
ack: true,
});
await this.setState(`Summary.${key}`, {
val: json[key].Metric.Value,
ack: true,
});
} else if (key === 'Wind') {
await this.setState('Current.WindSpeed', {
val: json[key].Speed.Metric.Value,
ack: true,
});
await this.setState('Summary.WindSpeed', {
val: json[key].Speed.Metric.Value,
ack: true,
});
await this.setState('Current.WindDirection', {
val: json[key].Direction.Degrees,
ack: true,
});
await this.setState('Current.WindDirectionText', {
val: json[key].Direction.Localized,
ack: true,
});
await this.setState('Summary.WindDirection', {
val: json[key].Direction.Degrees,
ack: true,
});
await this.setState('Summary.WindDirectionStr', {
val: this.getCardinalDirection(json[key].Direction.Degrees),
ack: true,
});
} else if (key === 'WindGust') {
await this.setState('Current.WindGust', {
val: json[key].Speed.Metric.Value,
ack: true,
});
} else if (key === 'PressureTendency') {
await this.setState('Current.PressureTendency', {
val: json[key].LocalizedText,
ack: true,
});
}
}
}
} catch (err) {
this.log.error(String(err));
}
}
if (json1[key1]["Value"] !== undefined) {
if (["TotalLiquid", "Rain", "Snow", "Ice"].includes(key1)) {
await this.setStateAsync("Daily.Day" + day + "." + key + "." + key1 + "Volume", { val: json1[key1].Value, ack: true });
} else { await this.setStateAsync("Daily.Day" + day + "." + key + "." + key1, { val: json1[key1].Value, ack: true }); }
} else
if (key1 == "Wind") {
await this.setStateAsync("Daily.Day" + day + "." + key + ".WindSpeed", { val: json1[key1].Speed.Value, ack: true });
await this.setStateAsync("Daily.Day" + day + "." + key + ".WindDirection", { val: json1[key1].Direction.Degrees, ack: true });
} else
if (key1 == "WindGust") {
await this.setStateAsync("Daily.Day" + day + "." + key + ".WindGust", { val: json1[key1].Speed.Value, ack: true });
}
}
}
}
break;
default:
break;
}
}
}
} catch (err) { this.log.error(err); }
}
async setHourlyStates(obj) {
for (const hr in obj) {
if (typeof obj[hr] === 'object' && obj[hr]['DateTime']) {
const d = new Date(obj[hr]['DateTime']);
await this.setNextHourStates(obj, hr, d.getHours());
}
}
}
async setNextHourStates(obj, item, hour) {
const json = obj[item];
try {
for (let key in json) {
if (typeof json[key] !== "object") {
await this.setStateAsync("Hourly.h" + hour + "." + key, { val: json[key], ack: true });
if (key==="WeatherIcon") {
await this.setStateAsync("Hourly.h" + hour + ".WeatherIconURL", { val: "https://developer.accuweather.com/sites/default/files/"+String(json[key]).padStart(2, "0")+"-s.png", ack: true });
await this.setStateAsync("Hourly.h" + hour + ".WeatherIconURLS", { val: "http://vortex.accuweather.com/adc2010/images/slate/icons/"+String(json[key]).padStart(2, "0")+".svg", ack: true });
}
} else
if (typeof json[key] == "object") {
request5Days() {
if (typeof this.forecast !== 'undefined') {
const loc = this.config.loKey;
const lang = this.config.language;
this.forecast
.localkey(loc)
.timeInt('daily/5day')
.language(lang)
.metric(true)
.details(true)
.get()
.then(res => this.setDailyStates(res))
.catch(err => this.log.error(String(err)));
}
}
if (json[key]["Value"] !== undefined) {
if (["TotalLiquid", "Rain", "Snow", "Ice"].includes(key)) {
await this.setStateAsync("Hourly.h" + hour + "." + key + "Volume", { val: json[key].Value, ack: true });
} else { await this.setStateAsync("Hourly.h" + hour + "." + key, { val: json[key].Value, ack: true }); }
} else
if (key == "Wind") {
await this.setStateAsync("Hourly.h" + hour + ".WindSpeed", { val: json[key].Speed.Value, ack: true });
await this.setStateAsync("Hourly.h" + hour + ".WindDirection", { val: json[key].Direction.Degrees, ack: true });
} else
if (key == "WindGust") {
await this.setStateAsync("Hourly.h" + hour + ".WindGust", { val: json[key].Speed.Value, ack: true });
}
}
}
} catch (err) { this.log.error(err); }
}
request12Hours() {
if (typeof this.forecast !== 'undefined') {
const loc = this.config.loKey;
const lang = this.config.language;
this.forecast
.localkey(loc)
.timeInt('hourly/12hour')
.language(lang)
.metric(true)
.details(true)
.get()
.then(res => this.setHourlyStates(res))
.catch(err => this.log.error(err));
}
}
async setCurrentStates(obj) {
const json = obj[0];
try {
for (let key in json) {
//this.log.debug("Current: " + key + ": " + typeof json[key]);
if (typeof json[key] !== "object" && json[key] !== null) {
await this.setStateAsync("Current." + key, { val: json[key], ack: true });
if (key==="WeatherIcon") {
await this.setStateAsync("Current" + ".WeatherIconURL", { val: "https://developer.accuweather.com/sites/default/files/"+String(json[key]).padStart(2, "0")+"-s.png", ack: true });
await this.setStateAsync("Current" + ".WeatherIconURLS", { val: "http://vortex.accuweather.com/adc2010/images/slate/icons/"+String(json[key]).padStart(2, "0")+".svg", ack: true });
}
}
else if (json[key] !== null) {
if (json[key].Metric !== undefined) {
//this.log.debug(key + ": " + json[key].Metric.Value);
await this.setStateAsync("Current." + key, { val: json[key].Metric.Value, ack: true });
} else
if (key == "Wind") {
await this.setStateAsync("Current.WindSpeed", { val: json[key].Speed.Metric.Value, ack: true });
await this.setStateAsync("Current.WindDirection", { val: json[key].Direction.Degrees, ack: true });
} else
if (key == "WindGust") {
await this.setStateAsync("Current.WindGust", { val: json[key].Speed.Metric.Value, ack: true });
} else
if (key == "PressureTendency") {
await this.setStateAsync("Current.PressureTendency", { val: json[key].LocalizedText, ack: true });
}
}
}
} catch (err) { this.log.error(err); }
}
requestCurrent() {
if (typeof this.forecast !== 'undefined') {
const loc = this.config.loKey;
const lang = this.config.language;
setHourlyStates(obj) {
for (let hr in obj) {
if (typeof obj[hr] == "object" && obj[hr]["DateTime"]) {
const d = new Date(obj[hr]["DateTime"]);
this.setNextHourStates(obj, hr, d.getHours());
}
}
}
this.forecast
.localkey(loc)
.timeInt()
.language(lang)
.metric(true)
.details(true)
.getCurrent()
.then(res => this.setCurrentStates(res))
.catch(err => this.log.error(err));
}
}
requst5Days() {
if (typeof this.forecast !== "undefined") {
const loc = this.config.loKey;
const lang = this.config.language;
this.forecast
.localkey(loc)
.timeInt("daily/5day")
.language(lang)
.metric(true)
.details(true)
.get()
.then(res => {
//this.log.debug(JSON.stringify(res));
this.setDailyStates(res);
})
.catch(err => {
this.log.error(err);
});
}
}
async onReady() {
const nameSpaceObj = await this.getForeignObjectAsync(this.namespace);
if (!nameSpaceObj) {
await this.setForeignObject(this.namespace, {
_id: this.namespace,
type: 'meta',
common: { name: 'Accuweather device', type: 'meta.folder' },
native: {},
});
}
const obj = await this.getForeignObjectAsync(`system.adapter.${this.namespace}`);
requst12Hours() {
if (typeof this.forecast !== "undefined") {
const loc = this.config.loKey;
const lang = this.config.language;
this.forecast
.localkey(loc)
.timeInt("hourly/12hour")
.language(lang)
.metric(true)
.details(true)
.get()
.then(res => {
//this.log.debug(JSON.stringify(res));
this.setHourlyStates(res);
})
.catch(err => {
this.log.error(err);
});
}
}
if (obj && obj.native && obj.native.apiKey) {
obj.native.apiKeyEncrypted = this.encrypt(obj.native.apiKey);
this.config.apiKeyEncrypted = obj.native.apiKey;
delete obj.native.apiKey;
await this.setForeignObject(`system.adapter.${this.namespace}`, obj);
}
requstCurrent() {
if (typeof this.forecast !== "undefined") {
const loc = this.config.loKey;
const lang = this.config.language;
this.forecast
.localkey(loc)
.timeInt()
.language(lang)
.metric(true)
.details(true)
.getCurrent()
.then(res => {
this.log.debug(JSON.stringify(res));
this.setCurrentStates(res);
})
.catch(err => {
this.log.error(err);
});
}
}
if (!this.config.language) {
const systemConfig = await this.getForeignObjectAsync('system.config');
if (systemConfig && systemConfig.common && systemConfig.common.language) {
this.config.language = systemConfig.common.language;
}
}
async onReady() {
nextHour.createHourlyForecastObjects(this);
nextHour.createCurrentConditionObjects(this);
nextHour.createDailyForecastObjects(this);
await nextHour.createHourlyForecastObjects(this);
await nextHour.createCurrentConditionObjects(this);
await nextHour.createDailyForecastObjects(this);
await nextHour.createSummaryObjects(this);
this.log.debug("API: " + this.config.apiKey + "; Loc: " + this.config.loKey + " Lang: " + this.config.language);
//this.log.debug(`API: ${this.config.apiKey}; Loc: ${this.config.loKey} Lang: ${this.config.language}`);
this.log.debug(`API: ********; Loc: ${this.config.loKey} Lang: ${this.config.language}`);
if (this.config.apiKey !== "") {
this.forecast = new Accuapi(this.config.apiKey);
} else { this.log.error("API Key is missing. Please enter Accuweather API key"); }
if (this.config.apiKeyEncrypted) {
this.forecast = new AccuAPI(this.config.apiKeyEncrypted);
} else {
this.log.error('API Key is missing. Please enter Accuweather API key');
}
setInterval(()=>{
const _this=this;
const cdt=new Date();
if ((cdt.getHours()===7 || cdt.getHours()===20) && cdt.getMinutes() <=5 ) {setTimeout(()=>{_this.requst5Days();},Math.random()*10000+1);}
if (cdt.getMinutes() <=5 && cdt.getMinutes() > 0) {setTimeout(()=>{_this.requstCurrent();},Math.random()*10000+1);}
if ((cdt.getHours()===6 || cdt.getHours()===12 || cdt.getHours()===18 || cdt.getHours()===0) && cdt.getMinutes() <=5) {setTimeout(()=>{_this.requst12Hours();},Math.random()*10000+1);}
}, 300000);
updateInterval = setInterval(() => {
const now = new Date();
if ((now.getHours() === 7 || now.getHours() === 20) && now.getMinutes() < 5) {
timeout1 = setTimeout(
() => {
timeout1 = null;
this.request5Days();
},
Math.random() * 10000 + 1,
);
}
if (now.getMinutes() < 5) {
timeout2 = setTimeout(
() => {
timeout2 = null;
this.requestCurrent();
},
Math.random() * 10000 + 1,
);
}
if (
(now.getHours() === 6 || now.getHours() === 12 || now.getHours() === 18 || now.getHours() === 0) &&
now.getMinutes() < 5
) {
timeout1 = setTimeout(
() => {
timeout1 = null;
this.request12Hours();
},
Math.random() * 10000 + 1,
);
}
}, 300000); // 5 minutes
if (!this.config.apiCallProtection) {
this.request12Hours();
this.requestCurrent();
this.request5Days();
} else {
this.log.info('The data has not been updated. The normal update cycle is running.');
}
this.requst12Hours();
this.requstCurrent();
this.requst5Days();
/*
setInterval(() => {
this.requst12Hours();
}, 21600000);
/*
For every state in the system, there has to be also an object of type state
Here a simple template for a boolean variable named "testVariable"
Because every adapter instance uses its own unique namespace variable names can't collide with other adapters variables
*/
setInterval(() => {
this.requstCurrent();
}, 3600000);
*/
//this.log.info(fres);
//accu=require('./lib/accuapi')()('GqmgWXup3W4DSrGoHpGdB32MR9bSAlPI');
// Initialize your adapter here
await this.extendObject('updateCurrent', {
type: 'state',
common: {
name: 'Update Current Weather',
type: 'boolean',
role: 'button',
read: false,
write: true,
},
native: {},
});
await this.extendObject('updateHourly', {
type: 'state',
common: {
name: 'Update 12 Hours Forecast',
type: 'boolean',
role: 'button',
read: false,
write: true,
},
native: {},
});
await this.extendObject('updateDaily', {
type: 'state',
common: {
name: 'Update 5 Days Forecast',
type: 'boolean',
role: 'button',
read: false,
write: true,
},
native: {},
});
// The adapters config (in the instance object everything under the attribute "native") is accessible via
// this.config:
//this.log.info("config option1: " + this.config.option1);
//this.log.info("config option2: " + this.config.option2);
// in this template, all states changes inside the adapter's namespace are subscribed
await this.subscribeStatesAsync('updateCurrent');
await this.subscribeStatesAsync('updateHourly');
await this.subscribeStatesAsync('updateDaily');
}
/*
For every state in the system there has to be also an object of type state
Here a simple template for a boolean variable named "testVariable"
Because every adapter instance uses its own unique namespace variable names can't collide with other adapters variables
*/
/**
* Is called when adapter shuts down - callback has to be called under any circumstances!
*
* @param callback - The callback function to be called when the unload process is complete
*/
onUnload(callback) {
try {
this.log.info('cleaned everything up...');
updateInterval && clearInterval(updateInterval);
updateInterval = null;
await this.setObjectAsync("updateCurrent", {
type: "state",
common: {
name: "Update Current Weather",
type: "boolean",
role: "button",
read: true,
write: true
},
native: {},
});
await this.setObjectAsync("updateHourly", {
type: "state",
common: {
name: "Update 12 Hours Forecast",
type: "boolean",
role: "button",
read: true,
write: true,
},
native: {},
});
await this.setObjectAsync("updateDaily", {
type: "state",
common: {
name: "Update 5 Days Forecast",
type: "boolean",
role: "button",
read: true,
write: true,
},
native: {},
});
timeout1 && clearTimeout(timeout1);
timeout1 = null;
timeout2 && clearTimeout(timeout2);
timeout2 = null;
// in this template all states changes inside the adapters namespace are subscribed
this.subscribeStates("update*");
callback();
callback = null;
} catch {
callback && callback();
}
}
/*
setState examples
you will notice that each setState will cause the stateChange event to fire (because of above subscribeStates cmd)
*/
// the variable testVariable is set to true as command (ack=false)
//await this.setStateAsync("testVariable", true);
// same thing, but the value is flagged "ack"
// ack should be always set to true if the value is received from or acknowledged from the target system
//await this.setStateAsync("testVariable", { val: true, ack: true });
// same thing, but the state is deleted after 30s (getState will return null afterwards)
//await this.setStateAsync("testVariable", { val: true, ack: true });
// examples for the checkPassword/checkGroup functions
//let result = await this.checkPasswordAsync("admin", "iobroker");
//this.log.info("check user admin pw ioboker: " + result);
//result = await this.checkGroupAsync("admin", "admin");
//this.log.info("check group user admin group admin: " + result);
}
/**
* Is called when adapter shuts down - callback has to be called under any circumstances!
* @param {() => void} callback
*/
onUnload(callback) {
try {
this.log.info("cleaned everything up...");
callback();
} catch (e) {
callback();
}
}
/**
* Is called if a subscribed object changes
* @param {string} id
* @param {ioBroker.Object | null | undefined} obj
*/
onObjectChange(id, obj) {
if (obj) {
this.log.debug(`object ${id} changed: ${JSON.stringify(obj)}`);
} else {
// The object was deleted
this.log.debug(`object ${id} deleted`);
}
}
/**
* Is called if a subscribed state changes
* @param {string} id
* @param {ioBroker.State | null | undefined} state
*/
onStateChange(id, state) {
if (state) {
// The state was changed
if (id.indexOf("updateCurrent")) {this.requstCurrent();} else
if (id.indexOf("updateHourly")) {this.requst12Hours();} else
if (id.indexOf("updateDaily")) {this.requst5Days();}
this.log.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
} else {
// The state was deleted
this.log.debug(`state ${id} deleted`);
}
}
// /**
// * Some message was sent to this instance over message box. Used by email, pushover, text2speech, ...
// * Using this method requires "common.message" property to be set to true in io-package.json
// * @param {ioBroker.Message} obj
// */
// onMessage(obj) {
// if (typeof obj === "object" && obj.message) {
// if (obj.command === "send") {
// // e.g. send email or pushover or whatever
// this.log.info("send command");
// // Send response in callback if required
// if (obj.callback) this.sendTo(obj.from, obj.command, "Message received", obj.callback);
// }
// }
// }
/**
* Is called if a subscribed state changes
*
* @param id - The id of the state that changed
* @param state - The state object that changed
*/
onStateChange(id, state) {
if (state) {
if (!state.ack) {
// The state was changed
if (id === `${this.namespace}.updateCurrent`) {
this.requestCurrent();
} else if (id === `${this.namespace}.updateHourly`) {
this.request12Hours();
} else if (id === `${this.namespace}.updateDaily`) {
this.request5Days();
}
this.log.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
}
} else {
// The state was deleted
this.log.debug(`state ${id} deleted`);
}
}
}
// @ts-ignore parent is a valid property on module
// @ts-expect-error parent is a valid property on module
if (module.parent) {
// Export the constructor in compact mode
/**
* @param {Partial<ioBroker.AdapterOptions>} [options={}]
*/
module.exports = (options) => new Accuweather(options);
// Export the constructor in compact mode
/**
* @param [options] - Optional settings for the adapter instance
*/
module.exports = options => new Accuweather(options);
} else {
// otherwise start the instance directly
new Accuweather();
// otherwise start the instance directly
new Accuweather();
}
{
"name": "iobroker.accuweather",
"version": "2.0.0",
"version": "2.0.1",
"description": "Weather forecast using AccuWeather API",

@@ -9,5 +9,6 @@ "author": {

},
"homepage": "https://github.com/algar42/ioBroker.accuweather",
"homepage": "https://github.com/iobroker-community-adapters/ioBroker.accuweather",
"license": "MIT",
"keywords": [
"ioBroker",
"Weather",

@@ -19,47 +20,65 @@ "AccuWeather",

"type": "git",
"url": "https://github.com/algar42/ioBroker.accuweather"
"url": "https://github.com/iobroker-community-adapters/ioBroker.accuweather"
},
"engines": {
"node": ">=20"
},
"dependencies": {
"@iobroker/adapter-core": "^1.0.3",
"query-string": "^6.8.3",
"request": "^2.88.0"
"@iobroker/adapter-core": "^3.2.3",
"axios": "^1.7.9",
"qs": "^6.14.0"
},
"devDependencies": {
"@iobroker/testing": "^1.2.5",
"@types/chai": "^4.2.0",
"@types/chai-as-promised": "^7.1.2",
"@types/gulp": "^4.0.6",
"@types/mocha": "^5.2.7",
"@types/node": "^10.14.17",
"@types/proxyquire": "^1.3.28",
"@types/sinon": "^7.0.13",
"@types/sinon-chai": "^3.2.3",
"axios": "^0.19.0",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"colors": "^1.3.3",
"eslint": "^6.2.2",
"gulp": "^4.0.2",
"mocha": "^6.2.0",
"@alcalzone/release-script": "^3.8.0",
"@alcalzone/release-script-plugin-iobroker": "^3.7.2",
"@alcalzone/release-script-plugin-license": "^3.7.0",
"@alcalzone/release-script-plugin-manual-review": "^3.7.0",
"@iobroker/adapter-dev": "^1.3.0",
"@iobroker/eslint-config": "^1.0.0",
"@iobroker/testing": "^5.0.0",
"@tsconfig/node20": "^20.1.4",
"@types/axios": "^0.9.36",
"@types/chai": "^4.3.11",
"@types/chai-as-promised": "^8.0.1",
"@types/gulp": "^4.0.17",
"@types/mocha": "^10.0.8",
"@types/node": "^22.10.3",
"@types/proxyquire": "^1.3.31",
"@types/sinon": "^17.0.3",
"@types/sinon-chai": "^3.2.12",
"chai": "^4.5.0",
"chai-as-promised": "^8.0.1",
"colors": "1.4.0",
"mocha": "^11.0.1",
"proxyquire": "^2.1.3",
"sinon": "^7.4.1",
"sinon-chai": "^3.3.0",
"ts-node": "^8.3.0",
"typescript": "^3.6.3"
"sinon": "^19.0.2",
"sinon-chai": "^3.7.0",
"typescript": "^5.7.2"
},
"main": "main.js",
"files": [
"admin/",
"lib/",
"main.js",
"io-package.json",
"LICENSE"
],
"scripts": {
"test:js": "mocha --opts test/mocha.custom.opts",
"test:js": "mocha --config test/mocharc.custom.json \"{!(node_modules|test)/**/*.test.js,*.test.js,test/**/test!(PackageFiles|Startup).js}\"",
"test:package": "mocha test/package --exit",
"test:unit": "mocha test/unit --exit",
"test:integration": "mocha test/integration --exit",
"test": "npm run test:js && npm run test:package",
"release": "node --require ts-node/register maintenance/release.ts",
"build": "tsc -p tsconfig.build.json",
"lint": "eslint"
"check": "tsc --noEmit -p tsconfig.check.json",
"lint": "eslint -c eslint.config.mjs .",
"translate": "translate-adapter",
"release": "release-script",
"update-packages": "ncu --upgrade"
},
"bugs": {
"url": "https://github.com/algar42/ioBroker.accuweather/issues"
"url": "https://github.com/iobroker-community-adapters/ioBroker.accuweather/issues"
},
"publishConfig": {
"access": "public"
},
"readmeFilename": "README.md"
}
![Logo](admin/accuweather.png)
# ioBroker.accuweather
[![NPM version](http://img.shields.io/npm/v/iobroker.accuweather.svg)](https://www.npmjs.com/package/iobroker.accuweather)
![Number of Installations](http://iobroker.live/badges/accuweather-installed.svg) ![Number of Installations](http://iobroker.live/badges/accuweather-stable.svg) [![NPM version](http://img.shields.io/npm/v/iobroker.accuweather.svg)](https://www.npmjs.com/package/iobroker.accuweather)
[![Downloads](https://img.shields.io/npm/dm/iobroker.accuweather.svg)](https://www.npmjs.com/package/iobroker.accuweather)
[![Dependency Status](https://img.shields.io/david/algar42/iobroker.accuweather.svg)](https://david-dm.org/algar42/iobroker.accuweather)
[![Known Vulnerabilities](https://snyk.io/test/github/algar42/ioBroker.accuweather/badge.svg)](https://snyk.io/test/github/algar42/ioBroker.accuweather)
[![NPM](https://nodei.co/npm/iobroker.accuweather.png?downloads=true)](https://nodei.co/npm/iobroker.accuweather/)
**Tests:**: [![Travis-CI](http://img.shields.io/travis/algar42/ioBroker.accuweather/master.svg)](https://travis-ci.org/algar42/ioBroker.accuweather)
## accuweather adapter for ioBroker
Weather forecast using AccuWeather API.
Weather forecast using AccuWeather API
Adapter receives
- Current Conditions (updated every hour), (24 requests)
- 5 Days daily forecast (update daily at approximately 7am and 8pm), (2 requests)
- and 12 hours forecast (updated every six hours at 12am, 6am, 12pm and 6pm). (4 requests)
Adapter receives Current Conditions (updated every hour), 5 Days daily forecast (update once daily at approximately 7am), and 12 hours forecast (updated every six hours at 12am, 6am, 12pm and 6pm).
By default, the adapter does not update any data when restarting.
Please adjust this in the configuration. 50 requests per day are allowed, each restart would require 3 requests to update all data.

@@ -22,24 +23,87 @@ ## Getting started

### Get API Key
To get API Key, register on https://developer.accuweather.com/ and create application in `My Apps` menu.
Once the application is created, you will have an API key generated.
For free use, it is possible to make 50 requests to API per day.
It was noted that to get the API working, the following settings are preferred (please choose your country!):
![settings](admin/image.png)
To get API Key, register on https://developer.accuweather.com/ and create application in \"My Apps\" menu. Once application created you will have API key generated.
For free use it is possible to make 50 requests to API per day.
### Get Location Key
In order to get location key, go to https://www.accuweather.com/ and enter your city name, or try to enter your coordinates (latitude, longitude) as you have them, e.g., in ioBroker settings.
Your location key will be the number at the end of the forecast URL.
In order to get location key, go to https://www.accuweather.com/ and enter your city name, or try to enter your coordinates (latitude, longitude) as you have them e.g. in IoBroker settings.
Your location key wil be the number at the end of URL of forecast.
### Using in Lovelace visualization (starting version 1.1.0)
The summary channel contains a current and by-day forecast with role/types of states supported by type-detector.
New feature can be used in order to show weather forecast in Lovelace UI.
For better view a custom lovelace card is created - see https://github.com/algar42/IoB.lovelace.accuweather-card
## Changelog
### 0.1.0
* (algar42) First release
<!--
Placeholder for the next version (at the beginning of the line):
### **WORK IN PROGRESS**
-->
### 2.0.1 (2025-01-18)
* (ticaki) BREAKING: Requires Nodejs 20 or higher
* (ticaki) BREAKING: Command states are now buttons and only respond to ack=false.
* (ticaki) admin option: No data is updated on adapter startup (default: true).
* (ticaki) apikey renamed and encrypted
* (ticaki) Dependencies and eslint updated
* (devtronic) Add nextHour.CloudCover
### 0.0.1
* (algar42) initial commit
### 1.5.0 (2024-06-23)
* (xdaamg) limit updates to once an hour, this fixes part of issue #273.
* (mcm1957) Adapter requires js-controller >= 5 and admin >= 6 now
* (mcm1957) Node 22 support has been added to testing
* (mcm1957) Dependencies have been updated
### 1.4.0 (2024-04-02)
* (mcm1957) Adapter requires node.js 18 and js-controller >= 5 now
* (mcm1957) Dependencies have been updated
### 1.3.2 (2023-12-04)
* (ticaki) fixed: dependencies
* (ticaki) fixed: error message [object Object]
### 1.3.1 (2023-08-15)
* (isi07) added the Wind Direction Text und Cloud Cover
* (bluefox) Added json config
### 1.2.4 (2022-02-08)
* (algar42) Depency updates
### 1.2.3 (2021-12-29)
* (algar42) HoursOfSun Parameter added to the Daily forecast
### 1.2.1 (2021-07-22)
* (bluefox) Updated logo
### 1.2.0 (2021-07-03)
* (Garfonso) adjust roles to properly detect weather forecast in Summary folder. (Summary objects need to be deleted and adapter restarted after that)
### 1.1.7 (2021-06-24)
* (bluefox) Create device for device-detector
### v1.1.6 (2021-05-05)
Minor bug fixes to `Object.common` section
### 1.1.5 (2021-01-25)
* (algar42) Resolve log Warning for js-controller 3.2
### 1.1.4
* (HGlab01) small bugfix regarding setTimeout range
### 1.1.3 (2020-03-04)
* (algar42) Minor updates for compact mode
### 1.1.0 (2019-11-09)
* (algar42) Summary channel added to support type-detector and automatic weather device creation
### 1.0.2 (2019-09-12)
* (algar42) Production Release
## License
MIT License
Copyright (c) 2019 algar42 <igor.aleschenkov@gmail.com>
Copyright (c) 2024-2025 iobroker-community-adapters <iobroker-community-adapters@gmx.de>
Copyright (c) 2021-2023 algar42 <igor.aleschenkov@gmail.com>

@@ -46,0 +110,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc