iobroker.accuweather
Advanced tools
Comparing version 1.4.0 to 1.5.0
/*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": "1.4.0", | ||
"version": "1.5.0", | ||
"news": { | ||
"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": { | ||
@@ -55,3 +68,4 @@ "en": "Adapter requires node.js 18 and js-controller >= 5 now\nDependencies have been updated", | ||
"pl": "aktualizacja zależności", | ||
"zh-cn": "依赖更新" | ||
"zh-cn": "依赖更新", | ||
"uk": "оновлення залежностей" | ||
}, | ||
@@ -68,3 +82,4 @@ "1.2.3": { | ||
"pl": "Dodano parametr HoursOfSun do prognozy dziennej", | ||
"zh-cn": "每日预测中添加了 hoursOfSun 参数" | ||
"zh-cn": "每日预测中添加了 hoursOfSun 参数", | ||
"uk": "До щоденного прогнозу додано параметр HoursOfSun" | ||
}, | ||
@@ -81,15 +96,4 @@ "1.2.1": { | ||
"pl": "Zaktualizowane logo", | ||
"zh-cn": "更新标志" | ||
}, | ||
"1.2.0": { | ||
"en": "adjust roles to properly detect weather forecast in Summary folder. (Summary objects need to be deleted and adapter restarted after that)", | ||
"de": "Passen Sie die Rollen an, um die Wettervorhersage im Ordner \"Zusammenfassung\" richtig zu erkennen. (Zusammenfassungsobjekte müssen danach gelöscht und der Adapter neu gestartet werden)", | ||
"ru": "Изменены роли для правильного определения устройства Погода. (Объекты Summary необходимо удалить и после этого перезапустить адаптер)", | ||
"pt": "ajuste as funções para detectar adequadamente a previsão do tempo na pasta Resumo. (Objetos de resumo precisam ser excluídos e o adaptador reiniciado depois disso)", | ||
"nl": "pas rollen aan om de weersvoorspelling correct te detecteren in de map Samenvatting. (Samenvattingsobjecten moeten daarna worden verwijderd en de adapter moet opnieuw worden opgestart)", | ||
"fr": "ajustez les rôles pour détecter correctement les prévisions météorologiques dans le dossier Résumé. (Les objets de résumé doivent être supprimés et l'adaptateur redémarré après cela)", | ||
"it": "regolare i ruoli per rilevare correttamente le previsioni del tempo nella cartella Riepilogo. (Gli oggetti di riepilogo devono essere eliminati e l'adattatore riavviato successivamente)", | ||
"es": "ajuste los roles para detectar correctamente el pronóstico del tiempo en la carpeta Resumen. (Los objetos de resumen deben eliminarse y el adaptador debe reiniciarse después de eso)", | ||
"pl": "dostosuj role, aby poprawnie wykryć prognozę pogody w folderze Podsumowanie. (Obiekty podsumowania należy usunąć, a następnie ponownie uruchomić adapter)", | ||
"zh-cn": "调整角色以正确检测摘要文件夹中的天气预报。 (之后需要删除摘要对象并重新启动适配器)" | ||
"zh-cn": "更新标志", | ||
"uk": "Оновлений логотип" | ||
} | ||
@@ -107,3 +111,4 @@ }, | ||
"pl": "AccuWeather", | ||
"zh-cn": "机构AccuWeather" | ||
"zh-cn": "机构AccuWeather", | ||
"uk": "AccuWeather" | ||
}, | ||
@@ -120,3 +125,4 @@ "desc": { | ||
"pl": "Prognoza pogody za pomocą interfejsu API AccuWeather", | ||
"zh-cn": "使用AccuWeather API的天气预报" | ||
"zh-cn": "使用AccuWeather API的天气预报", | ||
"uk": "Прогноз погоди за допомогою AccuWeather API" | ||
}, | ||
@@ -153,3 +159,3 @@ "authors": [ | ||
{ | ||
"js-controller": ">=5.0.0" | ||
"js-controller": ">=5.0.19" | ||
} | ||
@@ -159,3 +165,3 @@ ], | ||
{ | ||
"admin": ">=5.1.13" | ||
"admin": ">=6.13.16" | ||
} | ||
@@ -162,0 +168,0 @@ ] |
@@ -1,85 +0,85 @@ | ||
"use strict"; | ||
const axios = require("axios"); | ||
'use strict'; | ||
const axios = require('axios'); | ||
//const moment = require("moment"); | ||
const queryString = require("qs"); | ||
const queryString = require('qs'); | ||
class Accuapi { | ||
constructor(apiKey) { | ||
this.apiKey = apiKey; | ||
this.lokey = 335315; | ||
this.query = {}; | ||
//this.adapter = adapter; | ||
} | ||
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. | ||
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. | ||
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. | ||
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). | ||
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. | ||
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; | ||
} | ||
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; | ||
} | ||
get() { | ||
this.generateReqUrl(); | ||
return axios(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()}`); | ||
}); | ||
} | ||
get() { | ||
this.generateReqUrl(); | ||
return axios(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() { | ||
// | ||
//const body = require("./test-data/currentCond.json"); | ||
// | ||
this.generateReqUrl(true); | ||
return axios(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() { | ||
// | ||
//const body = require("./test-data/currentCond.json"); | ||
// | ||
this.generateReqUrl(true); | ||
return axios(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()}`); | ||
}); | ||
} | ||
} | ||
module.exports = Accuapi; |
@@ -1,42 +0,42 @@ | ||
"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); | ||
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]); | ||
} | ||
for (const key in _obj) { | ||
adapter.setObjectNotExists(key, _obj[key]); | ||
} | ||
} | ||
async function createNextHourForecatObjects(hour, adapter) { | ||
const obj = require("./nextHourObject.json"); | ||
await adapter.setObjectNotExistsAsync(`Hourly.h${hour}`, { | ||
type: "channel", | ||
common: { | ||
name: `Hour ${hour} Forecast`, | ||
}, | ||
native: {}, | ||
}); | ||
const _obj = Object.assign({}, obj); | ||
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) { | ||
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]); | ||
} | ||
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]); | ||
} | ||
} | ||
@@ -46,14 +46,14 @@ | ||
async function createCurrentConditionObjects(adapter) { | ||
const obj = require("./currentCondObject.json"); | ||
await adapter.setObjectNotExistsAsync("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) { | ||
adapter.setObjectNotExists(key.replace("nextHour", "Current"), obj[key]); | ||
} | ||
for (const key in obj) { | ||
adapter.setObjectNotExists(key.replace('nextHour', 'Current'), obj[key]); | ||
} | ||
} | ||
@@ -63,44 +63,44 @@ | ||
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.setObjectNotExistsAsync(`Daily.Day${i}`, { | ||
type: 'channel', | ||
common: { | ||
name: `Day ${i} Forecast` | ||
}, | ||
native: {}, | ||
}); | ||
const _obj = Object.assign({}, obj); | ||
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]); | ||
}); | ||
} | ||
} | ||
} | ||
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]); | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
async function createHourlyForecastObjects(adapter) { | ||
for (let hr = 0; hr < 24; hr++) { | ||
await createNextHourForecatObjects(hr, adapter); | ||
} | ||
for (let hr = 0; hr < 24; hr++) { | ||
await createNextHourForecatObjects(hr, adapter); | ||
} | ||
} | ||
@@ -107,0 +107,0 @@ |
@@ -1,2 +0,2 @@ | ||
const axios = require("axios"); | ||
const axios = require('axios'); | ||
@@ -9,7 +9,7 @@ /** | ||
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]'; | ||
} | ||
@@ -23,4 +23,4 @@ | ||
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]'; | ||
} | ||
@@ -36,10 +36,10 @@ | ||
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); | ||
} else { | ||
return await translateGoogle(text, targetLang); | ||
} | ||
} | ||
@@ -55,15 +55,15 @@ | ||
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}`); | ||
} | ||
} | ||
@@ -78,19 +78,19 @@ | ||
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 | ||
}; |
780
main.js
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -9,5 +9,5 @@ /* | ||
// 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; | ||
@@ -18,323 +18,323 @@ let timeout1 = null; | ||
class Accuweather extends utils.Adapter { | ||
/** | ||
/** | ||
* @param {Partial<utils.AdapterOptions>} [options={}] | ||
*/ | ||
constructor(options = {}) { | ||
super({ | ||
...options, | ||
name: "accuweather", | ||
strictObjectChecks: false | ||
}); | ||
this.on("ready", this.onReady.bind(this)); | ||
this.on("objectChange", this.onObjectChange.bind(this)); | ||
this.on("stateChange", this.onStateChange.bind(this)); | ||
this.on("unload", this.onUnload.bind(this)); | ||
} | ||
constructor(options = {}) { | ||
super({ | ||
...options, | ||
name: 'accuweather', | ||
strictObjectChecks: false | ||
}); | ||
this.on('ready', this.onReady.bind(this)); | ||
this.on('objectChange', this.onObjectChange.bind(this)); | ||
this.on('stateChange', this.onStateChange.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"]; | ||
} | ||
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.setStateAsync(`Daily.Day${day}.${key}`, { val: json[key], ack: true }); | ||
await this.setStateAsync(`Summary.DateTime_d${day}`, { val: json[key], ack: true }); | ||
await this.setStateAsync(`Summary.DayOfWeek_d${day}`, { val: dt.toLocaleString(this.config.language, {weekday: "short"}), 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 }); | ||
if (day === 1) { | ||
await this.setStateAsync("Summary.Sunrise", { val: json[key]["Rise"], ack: true }); | ||
await this.setStateAsync("Summary.Sunset", { val: json[key]["Set"], ack: true }); | ||
} | ||
break; | ||
case "HoursOfSun": | ||
await this.setStateAsync(`Daily.Day${day}.HoursOfSun`, { val: json[key], ack: true }); | ||
if (day === 1) { | ||
await this.setStateAsync("Summary.HoursOfSun", { val: json[key], 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 }); | ||
await this.setStateAsync(`Summary.TempMin_d${day}`, { val: json[key]["Minimum"].Value, ack: true }); | ||
await this.setStateAsync(`Summary.TempMax_d${day}`, { 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": | ||
{ | ||
const json1 = json[key]; | ||
for (const 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 }); | ||
if (key === "Day") { | ||
await this.setStateAsync(`Summary.WeatherIconURL_d${day}`, { val: `http://vortex.accuweather.com/adc2010/images/slate/icons/${String(json1[key1]).padStart(2, "0")}.svg`, ack: true }); | ||
await this.setStateAsync(`Summary.WeatherIcon_d${day}`, { val: json1[key1], ack: true }); | ||
} | ||
} else if (key === "Day") { | ||
if (key1 === "IconPhrase") { | ||
await this.setStateAsync(`Summary.WeatherText_d${day}`, { val: json1[key1], ack: true }); | ||
} else { | ||
await this.setStateAsync(`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.setStateAsync(`Daily.Day${day}.${key}.${key1}Volume`, { val: json1[key1].Value, ack: true }); | ||
if (key === "Day" && key1 === "TotalLiquid") { | ||
await this.setStateAsync(`Summary.TotalLiquidVolume_d${day}`, { 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 }); | ||
if (key === "Day") { | ||
await this.setStateAsync(`Summary.WindSpeed_d${day}`, { val: json1[key1].Speed.Value, ack: true }); | ||
await this.setStateAsync(`Summary.WindDirection_d${day}`, { val: json1[key1].Direction.Degrees, ack: true }); | ||
await this.setStateAsync(`Summary.WindDirectionStr_d${day}`, { val: this.getCardinalDirection(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 (/** @type any */ err) { | ||
this.log.error(err); | ||
} | ||
} | ||
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.setStateAsync(`Daily.Day${day}.${key}`, { val: json[key], ack: true }); | ||
await this.setStateAsync(`Summary.DateTime_d${day}`, { val: json[key], ack: true }); | ||
await this.setStateAsync(`Summary.DayOfWeek_d${day}`, { val: dt.toLocaleString(this.config.language, {weekday: 'short'}), 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 }); | ||
if (day === 1) { | ||
await this.setStateAsync('Summary.Sunrise', { val: json[key]['Rise'], ack: true }); | ||
await this.setStateAsync('Summary.Sunset', { val: json[key]['Set'], ack: true }); | ||
} | ||
break; | ||
case 'HoursOfSun': | ||
await this.setStateAsync(`Daily.Day${day}.HoursOfSun`, { val: json[key], ack: true }); | ||
if (day === 1) { | ||
await this.setStateAsync('Summary.HoursOfSun', { val: json[key], 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 }); | ||
await this.setStateAsync(`Summary.TempMin_d${day}`, { val: json[key]['Minimum'].Value, ack: true }); | ||
await this.setStateAsync(`Summary.TempMax_d${day}`, { 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': | ||
{ | ||
const json1 = json[key]; | ||
for (const 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 }); | ||
if (key === 'Day') { | ||
await this.setStateAsync(`Summary.WeatherIconURL_d${day}`, { val: `http://vortex.accuweather.com/adc2010/images/slate/icons/${String(json1[key1]).padStart(2, '0')}.svg`, ack: true }); | ||
await this.setStateAsync(`Summary.WeatherIcon_d${day}`, { val: json1[key1], ack: true }); | ||
} | ||
} else if (key === 'Day') { | ||
if (key1 === 'IconPhrase') { | ||
await this.setStateAsync(`Summary.WeatherText_d${day}`, { val: json1[key1], ack: true }); | ||
} else { | ||
await this.setStateAsync(`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.setStateAsync(`Daily.Day${day}.${key}.${key1}Volume`, { val: json1[key1].Value, ack: true }); | ||
if (key === 'Day' && key1 === 'TotalLiquid') { | ||
await this.setStateAsync(`Summary.TotalLiquidVolume_d${day}`, { 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 }); | ||
if (key === 'Day') { | ||
await this.setStateAsync(`Summary.WindSpeed_d${day}`, { val: json1[key1].Speed.Value, ack: true }); | ||
await this.setStateAsync(`Summary.WindDirection_d${day}`, { val: json1[key1].Direction.Degrees, ack: true }); | ||
await this.setStateAsync(`Summary.WindDirectionStr_d${day}`, { val: this.getCardinalDirection(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 (/** @type any */ err) { | ||
this.log.error(err); | ||
} | ||
} | ||
async setNextHourStates(obj, item, hour) { | ||
const json = obj[item]; | ||
try { | ||
for (const 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") { | ||
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 }); | ||
await this.setStateAsync(`Hourly.h${hour}.WindDirectionText`, { val: json[key].Direction.Localized , ack: true }); | ||
} else if (key === "WindGust") { | ||
await this.setStateAsync(`Hourly.h${hour}.WindGust`, { val: json[key].Speed.Value, ack: true }); | ||
} | ||
} | ||
} | ||
} catch (/** @type any */err) { | ||
this.log.error(err); | ||
} | ||
} | ||
async setNextHourStates(obj, item, hour) { | ||
const json = obj[item]; | ||
try { | ||
for (const 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') { | ||
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 }); | ||
await this.setStateAsync(`Hourly.h${hour}.WindDirectionText`, { val: json[key].Direction.Localized , ack: true }); | ||
} else if (key === 'WindGust') { | ||
await this.setStateAsync(`Hourly.h${hour}.WindGust`, { val: json[key].Speed.Value, ack: true }); | ||
} | ||
} | ||
} | ||
} catch (/** @type any */err) { | ||
this.log.error(err); | ||
} | ||
} | ||
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.setStateAsync(`Current.${key}`, { val: json[key], ack: true }); | ||
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.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 }); | ||
await this.setStateAsync("Summary.WeatherIconURL", { val: `http://vortex.accuweather.com/adc2010/images/slate/icons/${String(json[key]).padStart(2, "0")}.svg`, ack: true }); | ||
await this.setStateAsync("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.setStateAsync("Summary.CurrentDateTime", { val: json[key], ack: true }); | ||
await this.setStateAsync("Summary.DayOfWeek", { val: dow, ack: true }); | ||
this.log.debug(`Date ${dt}, dow: ${dt.toLocaleString(this.config.language, {weekday: "short"})}`); | ||
} else { | ||
await this.setStateAsync(`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.setStateAsync(`Current.${key}`, { val: json[key].Metric.Value, ack: true }); | ||
await this.setStateAsync(`Summary.${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("Summary.WindSpeed", { val: json[key].Speed.Metric.Value, ack: true }); | ||
await this.setStateAsync("Current.WindDirection", { val: json[key].Direction.Degrees, ack: true }); | ||
await this.setStateAsync("Current.WindDirectionText", { val: json[key].Direction.Localized, ack: true }); | ||
await this.setStateAsync("Summary.WindDirection", { val: json[key].Direction.Degrees, ack: true }); | ||
await this.setStateAsync("Summary.WindDirectionStr", { val: this.getCardinalDirection(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 (/** @type any */err) { | ||
this.log.error(err); | ||
} | ||
} | ||
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 }); | ||
await this.setStateAsync('Summary.WeatherIconURL', { val: `http://vortex.accuweather.com/adc2010/images/slate/icons/${String(json[key]).padStart(2, '0')}.svg`, ack: true }); | ||
await this.setStateAsync('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.setStateAsync('Summary.CurrentDateTime', { val: json[key], ack: true }); | ||
await this.setStateAsync('Summary.DayOfWeek', { val: dow, ack: true }); | ||
this.log.debug(`Date ${dt}, dow: ${dt.toLocaleString(this.config.language, {weekday: 'short'})}`); | ||
} else { | ||
await this.setStateAsync(`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.setStateAsync(`Current.${key}`, { val: json[key].Metric.Value, ack: true }); | ||
await this.setStateAsync(`Summary.${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('Summary.WindSpeed', { val: json[key].Speed.Metric.Value, ack: true }); | ||
await this.setStateAsync('Current.WindDirection', { val: json[key].Direction.Degrees, ack: true }); | ||
await this.setStateAsync('Current.WindDirectionText', { val: json[key].Direction.Localized, ack: true }); | ||
await this.setStateAsync('Summary.WindDirection', { val: json[key].Direction.Degrees, ack: true }); | ||
await this.setStateAsync('Summary.WindDirectionStr', { val: this.getCardinalDirection(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 (/** @type any */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 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()); | ||
} | ||
} | ||
} | ||
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(err)); | ||
} | ||
} | ||
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(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)); | ||
} | ||
} | ||
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)); | ||
} | ||
} | ||
requestCurrent() { | ||
if (typeof this.forecast !== "undefined") { | ||
const loc = this.config.loKey; | ||
const lang = this.config.language; | ||
requestCurrent() { | ||
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.setCurrentStates(res)) | ||
.catch(err => this.log.error(err)); | ||
} | ||
} | ||
this.forecast | ||
.localkey(loc) | ||
.timeInt() | ||
.language(lang) | ||
.metric(true) | ||
.details(true) | ||
.getCurrent() | ||
.then(res => this.setCurrentStates(res)) | ||
.catch(err => this.log.error(err)); | ||
} | ||
} | ||
async onReady() { | ||
let obj; | ||
try { | ||
obj = await this.getForeignObjectAsync(this.namespace); | ||
} catch (e) { | ||
// ignore | ||
} | ||
if (!obj) { | ||
//@ts-ignore | ||
await this.setForeignObjectAsync(this.namespace, { type: "device", common: { name: "Accuweather device" }, native: {} }); | ||
} | ||
async onReady() { | ||
let obj; | ||
try { | ||
obj = await this.getForeignObjectAsync(this.namespace); | ||
} catch (e) { | ||
// ignore | ||
} | ||
if (!obj) { | ||
//@ts-ignore | ||
await this.setForeignObjectAsync(this.namespace, { type: 'device', common: { name: 'Accuweather device' }, native: {} }); | ||
} | ||
if (!this.config.language) { | ||
const systemConfig = await this.getForeignObjectAsync("system.config"); | ||
if (systemConfig && systemConfig.common && systemConfig.common.language) { | ||
this.config.language = systemConfig.common.language; | ||
} | ||
} | ||
if (!this.config.language) { | ||
const systemConfig = await this.getForeignObjectAsync('system.config'); | ||
if (systemConfig && systemConfig.common && systemConfig.common.language) { | ||
this.config.language = systemConfig.common.language; | ||
} | ||
} | ||
await nextHour.createHourlyForecastObjects(this); | ||
await nextHour.createCurrentConditionObjects(this); | ||
await nextHour.createDailyForecastObjects(this); | ||
await nextHour.createSummaryObjects(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}`); | ||
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.apiKey) { | ||
this.forecast = new AccuAPI(this.config.apiKey); | ||
} else { | ||
this.log.error('API Key is missing. Please enter Accuweather API key'); | ||
} | ||
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 | ||
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 | ||
this.request12Hours(); | ||
this.requestCurrent(); | ||
this.request5Days(); | ||
this.request12Hours(); | ||
this.requestCurrent(); | ||
this.request5Days(); | ||
/* | ||
/* | ||
For every state in the system, there has to be also an object of type state | ||
@@ -345,67 +345,67 @@ Here a simple template for a boolean variable named "testVariable" | ||
await this.setObjectNotExistsAsync("updateCurrent", { | ||
type: "state", | ||
common: { | ||
name: "Update Current Weather", | ||
type: "boolean", | ||
role: "button", | ||
read: true, | ||
write: true | ||
}, | ||
native: {}, | ||
}); | ||
await this.setObjectNotExistsAsync("updateHourly", { | ||
type: "state", | ||
common: { | ||
name: "Update 12 Hours Forecast", | ||
type: "boolean", | ||
role: "button", | ||
read: true, | ||
write: true, | ||
}, | ||
native: {}, | ||
}); | ||
await this.setObjectNotExistsAsync("updateDaily", { | ||
type: "state", | ||
common: { | ||
name: "Update 5 Days Forecast", | ||
type: "boolean", | ||
role: "button", | ||
read: true, | ||
write: true, | ||
}, | ||
native: {}, | ||
}); | ||
await this.setObjectNotExistsAsync('updateCurrent', { | ||
type: 'state', | ||
common: { | ||
name: 'Update Current Weather', | ||
type: 'boolean', | ||
role: 'button', | ||
read: true, | ||
write: true | ||
}, | ||
native: {}, | ||
}); | ||
await this.setObjectNotExistsAsync('updateHourly', { | ||
type: 'state', | ||
common: { | ||
name: 'Update 12 Hours Forecast', | ||
type: 'boolean', | ||
role: 'button', | ||
read: true, | ||
write: true, | ||
}, | ||
native: {}, | ||
}); | ||
await this.setObjectNotExistsAsync('updateDaily', { | ||
type: 'state', | ||
common: { | ||
name: 'Update 5 Days Forecast', | ||
type: 'boolean', | ||
role: 'button', | ||
read: true, | ||
write: true, | ||
}, | ||
native: {}, | ||
}); | ||
// 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"); | ||
} | ||
// 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'); | ||
} | ||
/** | ||
/** | ||
* 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..."); | ||
updateInterval && clearInterval(updateInterval); | ||
updateInterval = null; | ||
onUnload(callback) { | ||
try { | ||
this.log.info('cleaned everything up...'); | ||
updateInterval && clearInterval(updateInterval); | ||
updateInterval = null; | ||
timeout1 && clearTimeout(timeout1); | ||
timeout1 = null; | ||
timeout1 && clearTimeout(timeout1); | ||
timeout1 = null; | ||
timeout2 && clearTimeout(timeout2); | ||
timeout2 = null; | ||
timeout2 && clearTimeout(timeout2); | ||
timeout2 = null; | ||
callback(); | ||
// @ts-ignore | ||
callback = null; | ||
} catch (e) { | ||
callback && callback(); | ||
} | ||
} | ||
callback(); | ||
// @ts-ignore | ||
callback = null; | ||
} catch (e) { | ||
callback && callback(); | ||
} | ||
} | ||
/** | ||
/** | ||
* Is called if a subscribed object changes | ||
@@ -415,12 +415,12 @@ * @param {string} id | ||
*/ | ||
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`); | ||
} | ||
} | ||
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 | ||
@@ -430,18 +430,18 @@ * @param {string} id | ||
*/ | ||
onStateChange(id, state) { | ||
if (state) { | ||
// 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`); | ||
} | ||
} | ||
onStateChange(id, state) { | ||
if (state) { | ||
// 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`); | ||
} | ||
} | ||
} | ||
@@ -451,12 +451,12 @@ | ||
if (module.parent) { | ||
// Export the constructor in compact mode | ||
/** | ||
// Export the constructor in compact mode | ||
/** | ||
* @param {Partial<utils.AdapterOptions>} [options={}] | ||
*/ | ||
module.exports = (options) => new Accuweather(options); | ||
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": "1.4.0", | ||
"version": "1.5.0", | ||
"description": "Weather forecast using AccuWeather API", | ||
@@ -24,5 +24,5 @@ "author": { | ||
"dependencies": { | ||
"@iobroker/adapter-core": "^3.0.6", | ||
"axios": "^1.6.8", | ||
"qs": "^6.12.0" | ||
"@iobroker/adapter-core": "^3.1.6", | ||
"axios": "^1.7.2", | ||
"qs": "^6.12.1" | ||
}, | ||
@@ -35,3 +35,3 @@ "devDependencies": { | ||
"@iobroker/adapter-dev": "^1.3.0", | ||
"@iobroker/testing": "^4.1.1", | ||
"@iobroker/testing": "^4.1.3", | ||
"@tsconfig/node18": "^18.2.4", | ||
@@ -41,4 +41,4 @@ "@types/chai": "^4.3.11", | ||
"@types/gulp": "^4.0.17", | ||
"@types/mocha": "^10.0.6", | ||
"@types/node": "^20.12.2", | ||
"@types/mocha": "^10.0.7", | ||
"@types/node": "^20.14.8", | ||
"@types/proxyquire": "^1.3.31", | ||
@@ -48,11 +48,10 @@ "@types/sinon": "^17.0.3", | ||
"chai": "^4.4.1", | ||
"chai-as-promised": "^7.1.1", | ||
"chai-as-promised": "^7.1.2", | ||
"colors": "1.4.0", | ||
"eslint": "^8.57.0", | ||
"gulp": "^4.0.2", | ||
"mocha": "^10.4.0", | ||
"proxyquire": "^2.1.3", | ||
"sinon": "^17.0.1", | ||
"sinon": "^18.0.0", | ||
"sinon-chai": "^3.7.0", | ||
"typescript": "^5.4.3" | ||
"typescript": "^5.5.2" | ||
}, | ||
@@ -68,12 +67,10 @@ "main": "main.js", | ||
"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", | ||
"lint": "eslint", | ||
"check": "tsc --noEmit -p tsconfig.check.json", | ||
"lint": "eslint .", | ||
"translate": "translate-adapter", | ||
"release": "release-script", | ||
"release-patch": "release-script patch --yes --no-update-lockfile", | ||
"release-minor": "release-script minor --yes --no-update-lockfile", | ||
"release-major": "release-script major --yes --no-update-lockfile", | ||
"update-packages": "ncu --upgrade" | ||
@@ -80,0 +77,0 @@ }, |
@@ -39,2 +39,8 @@ ![Logo](admin/accuweather.png) | ||
--> | ||
### 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) | ||
@@ -41,0 +47,0 @@ * (mcm1957) Adapter requires node.js 18 and js-controller >= 5 now |
189391
24
113
2603
Updatedaxios@^1.7.2
Updatedqs@^6.12.1