diff --git a/README.md b/README.md index c4c77cb..54ac18d 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ When the adapter crashes or an other Code error happens, this error message that ### __WORK IN PROGRESS__ * (simatec) eslint-config fix +* (simatec) Code fix ### 0.9.13 (2024-11-27) * (simatec) Dependencies updated diff --git a/eslint.config.mjs b/eslint.config.mjs index 1221f34..32ba58c 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -25,7 +25,21 @@ export default [ // you may disable some 'jsdoc' warnings - but using jsdoc is highly recommended // as this improves maintainability. jsdoc warnings will not block buiuld process. rules: { - // 'jsdoc/require-jsdoc': 'off', + 'jsdoc/require-jsdoc': 'off', + 'no-async-promise-executor': 'off', + 'prettier/prettier': 'off', + '@typescript-eslint/no-unused-vars': 'off', + 'curly': 'off', + 'jsdoc/require-returns-description': 'off', + 'no-else-return': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + //'no-prototype-builtins': 'off', + //'no-case-declarations': 'off', + //'no-useless-escape': 'off', + //'jsdoc/require-param': 'off', + //'@typescript-eslint/no-require-imports': 'off', + //'jsdoc/no-types': 'off', + //'jsdoc/tag-lines': 'off', }, }, diff --git a/lib/createObjects.js b/lib/createObjects.js index f08af69..86c5fdb 100644 --- a/lib/createObjects.js +++ b/lib/createObjects.js @@ -1,325 +1,325 @@ 'use strict'; const cloudDataObjects = { - 'acpower': { - 'type': 'state', - 'common': { - 'role': 'value.power', - 'name': 'Inverter AC-Power total', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'W' + acpower: { + type: 'state', + common: { + role: 'value.power', + name: 'Inverter AC-Power total', + type: 'number', + read: true, + write: false, + unit: 'W' }, - 'native': {} + native: {} }, - 'yieldtoday': { - 'type': 'state', - 'common': { - 'role': 'value.power.consumption', - 'name': 'Inverter AC-Energy out Daily', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'KWh' + yieldtoday: { + type: 'state', + common: { + role: 'value.power.consumption', + name: 'Inverter AC-Energy out Daily', + type: 'number', + read: true, + write: false, + unit: 'KWh' }, - 'native': {} + native: {} }, - 'yieldtotal': { - 'type': 'state', - 'common': { - 'role': 'value.power.consumption', - 'name': 'Inverter AC-Energy out total', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'KWh' + yieldtotal: { + type: 'state', + common: { + role: 'value.power.consumption', + name: 'Inverter AC-Energy out total', + type: 'number', + read: true, + write: false, + unit: 'KWh' }, - 'native': {} + native: {} }, - 'feedinpower': { - 'type': 'state', - 'common': { - 'role': 'value.power', - 'name': 'GCP-Power total', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'W' + feedinpower: { + type: 'state', + common: { + role: 'value.power', + name: 'GCP-Power total', + type: 'number', + read: true, + write: false, + unit: 'W' }, - 'native': {} + native: {} }, - 'feedinenergy': { - 'type': 'state', - 'common': { - 'role': 'value.power.consumption', - 'name': 'GCP-Energy to Grid total', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'KWh' + feedinenergy: { + type: 'state', + common: { + role: 'value.power.consumption', + name: 'GCP-Energy to Grid total', + type: 'number', + read: true, + write: false, + unit: 'KWh' }, - 'native': {} + native: {} }, - 'consumeenergy': { - 'type': 'state', - 'common': { - 'role': 'value.power.consumption', - 'name': 'GCP-Energy from Grid total', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'KWh' + consumeenergy: { + type: 'state', + common: { + role: 'value.power.consumption', + name: 'GCP-Energy from Grid total', + type: 'number', + read: true, + write: false, + unit: 'KWh' }, - 'native': {} + native: {} }, - 'feedinpowerM2': { - 'type': 'state', - 'common': { - 'role': 'value.power', - 'name': 'address to meter AC-Power total', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'W' + feedinpowerM2: { + type: 'state', + common: { + role: 'value.power', + name: 'address to meter AC-Power total', + type: 'number', + read: true, + write: false, + unit: 'W' }, - 'native': {} + native: {} }, - 'soc': { - 'type': 'state', - 'common': { - 'role': 'value', - 'name': 'Inverter DC-Battery Energy SOC', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': '%' + soc: { + type: 'state', + common: { + role: 'value', + name: 'Inverter DC-Battery Energy SOC', + type: 'number', + read: true, + write: false, + unit: '%' }, - 'native': {} + native: {} }, - 'peps1': { - 'type': 'state', - 'common': { - 'role': 'value.power', - 'name': 'Inverter AC EPS-Power L1', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'W' + peps1: { + type: 'state', + common: { + role: 'value.power', + name: 'Inverter AC EPS-Power L1', + type: 'number', + read: true, + write: false, + unit: 'W' }, - 'native': {} + native: {} }, - 'peps2': { - 'type': 'state', - 'common': { - 'role': 'value.power', - 'name': 'Inverter AC EPS-Power L2', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'W' + peps2: { + type: 'state', + common: { + role: 'value.power', + name: 'Inverter AC EPS-Power L2', + type: 'number', + read: true, + write: false, + unit: 'W' }, - 'native': {} + native: {} }, - 'peps3': { - 'type': 'state', - 'common': { - 'role': 'value.power', - 'name': 'Inverter AC EPS-Power L3', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'W' + peps3: { + type: 'state', + common: { + role: 'value.power', + name: 'Inverter AC EPS-Power L3', + type: 'number', + read: true, + write: false, + unit: 'W' }, - 'native': {} + native: {} }, - 'batPower': { - 'type': 'state', - 'common': { - 'role': 'value.power', - 'name': 'Inverter DC-Battery power total', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'W' + batPower: { + type: 'state', + common: { + role: 'value.power', + name: 'Inverter DC-Battery power total', + type: 'number', + read: true, + write: false, + unit: 'W' }, - 'native': {} + native: {} }, - 'powerdc1': { - 'type': 'state', - 'common': { - 'role': 'value.power', - 'name': 'Inverter DC PV power MPPT1', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'W' + powerdc1: { + type: 'state', + common: { + role: 'value.power', + name: 'Inverter DC PV power MPPT1', + type: 'number', + read: true, + write: false, + unit: 'W' }, - 'native': {} + native: {} }, - 'powerdc2': { - 'type': 'state', - 'common': { - 'role': 'value.power', - 'name': 'Inverter DC PV power MPPT2', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'W' + powerdc2: { + type: 'state', + common: { + role: 'value.power', + name: 'Inverter DC PV power MPPT2', + type: 'number', + read: true, + write: false, + unit: 'W' }, - 'native': {} + native: {} }, - 'powerdc3': { - 'type': 'state', - 'common': { - 'role': 'value.power', - 'name': 'Inverter DC PV power MPPT3', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'W' + powerdc3: { + type: 'state', + common: { + role: 'value.power', + name: 'Inverter DC PV power MPPT3', + type: 'number', + read: true, + write: false, + unit: 'W' }, - 'native': {} + native: {} }, - 'powerdc4': { - 'type': 'state', - 'common': { - 'role': 'value.power', - 'name': 'Inverter DC PV power MPPT4', - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'W' + powerdc4: { + type: 'state', + common: { + role: 'value.power', + name: 'Inverter DC PV power MPPT4', + type: 'number', + read: true, + write: false, + unit: 'W' }, - 'native': {} + native: {} } } const infoObjects = { - 'success': { - 'type': 'state', - 'common': { - 'role': 'indicator.state', - 'name': 'API success', - 'type': 'boolean', - 'read': true, - 'write': false + success: { + type: 'state', + common: { + role: 'indicator.state', + name: 'API success', + type: 'boolean', + read: true, + write: false }, - 'native': {} + native: {} }, - 'exception': { - 'type': 'state', - 'common': { - 'role': 'text', - 'name': 'API connection', - 'type': 'string', - 'read': true, - 'write': false + exception: { + type: 'state', + common: { + role: 'text', + name: 'API connection', + type: 'string', + read: true, + write: false }, - 'native': {} + native: {} }, - 'inverterSN': { - 'type': 'state', - 'common': { - 'role': 'text', - 'name': 'Unique identifier of inverter (Serial No.)', - 'type': 'string', - 'read': true, - 'write': false + inverterSN: { + type: 'state', + common: { + role: 'text', + name: 'Unique identifier of inverter (Serial No.)', + type: 'string', + read: true, + write: false }, - 'native': {} + native: {} }, - 'sn': { - 'type': 'state', - 'common': { - 'role': 'text', - 'name': 'Unique identifier of communication module (Registration No.)', - 'type': 'string', - 'read': true, - 'write': false + sn: { + type: 'state', + common: { + role: 'text', + name: 'Unique identifier of communication module (Registration No.)', + type: 'string', + read: true, + write: false }, - 'native': {} + native: {} }, - 'inverterType': { - 'type': 'state', - 'common': { - 'role': 'text', - 'name': 'Inverter type', - 'type': 'string', - 'read': true, - 'write': false + inverterType: { + type: 'state', + common: { + role: 'text', + name: 'Inverter type', + type: 'string', + read: true, + write: false }, - 'native': {} + native: {} }, - 'inverterStatus': { - 'type': 'state', - 'common': { - 'role': 'text', - 'name': 'Inverter status', - 'type': 'string', - 'read': true, - 'write': false + inverterStatus: { + type: 'state', + common: { + role: 'text', + name: 'Inverter status', + type: 'string', + read: true, + write: false }, - 'native': {} + native: {} }, - 'uploadTime': { - 'type': 'state', - 'common': { - 'role': 'value.time', - 'name': 'Update time', - 'type': 'string', - 'read': true, - 'write': false + uploadTime: { + type: 'state', + common: { + role: 'value.time', + name: 'Update time', + type: 'string', + read: true, + write: false }, - 'native': {} + native: {} }, - 'connectType': { - 'type': 'state', - 'common': { - 'role': 'text', - 'name': 'Connect Type for Request', - 'type': 'string', - 'read': true, - 'write': false + connectType: { + type: 'state', + common: { + role: 'text', + name: 'Connect Type for Request', + type: 'string', + read: true, + write: false }, - 'native': {} + native: {} }, - 'online': { - 'type': 'state', - 'common': { - 'role': 'switch', - 'name': 'Inverter Online', - 'type': 'boolean', - 'read': true, - 'write': false + online: { + type: 'state', + common: { + role: 'switch', + name: 'Inverter Online', + type: 'boolean', + read: true, + write: false }, - 'native': {} + native: {} }, - 'connection': { - 'type': 'state', - 'common': { - 'role': 'indicator.connected', - 'name': 'If connected', - 'type': 'boolean', - 'read': true, - 'write': false, - 'def': false + connection: { + type: 'state', + common: { + role: 'indicator.connected', + name: 'If connected', + type: 'boolean', + read: true, + write: false, + def: false }, - 'native': {} + native: {} } }; const specialObjects = { - 'json': { - 'type': 'state', - 'common': { - 'name': 'json data', - 'type': 'string', - 'role': 'json', - 'read': true, - 'write': false + json: { + type: 'state', + common: { + name: 'json data', + type: 'string', + role: 'json', + read: true, + write: false }, - 'native': {} + native: {} } }; @@ -329,7 +329,7 @@ async function createdDataStates(api, adapter) { return new Promise(async (resolve) => { for (const obj in cloudDataObjects) { if (api.result[`${obj}`] || obj == 'yieldtoday') { - await adapter.setObjectNotExistsAsync('data.' + obj, cloudDataObjects[obj]); + await adapter.setObjectNotExistsAsync(`data.${obj}`, cloudDataObjects[obj]); } else if (!api.result[`${obj}`]) { delete api.result[`${obj}`]; } @@ -346,7 +346,7 @@ async function createdInfoStates(adapter, connectType) { return new Promise(async (resolve) => { for (const obj in infoObjects) { if ((obj != 'online' && connectType == 'cloud') || (obj != 'success' && obj != 'exception' && connectType == 'local')) { - await adapter.setObjectNotExistsAsync('info.' + obj, infoObjects[obj]); + await adapter.setObjectNotExistsAsync(`info.${obj}`, infoObjects[obj]); } } await sleep(1000); @@ -361,7 +361,7 @@ async function createdInfoStates(adapter, connectType) { async function createdSpecialStates(adapter) { return new Promise(async (resolve) => { for (const obj in specialObjects) { - await adapter.setObjectNotExistsAsync('data.' + obj, specialObjects[obj]); + await adapter.setObjectNotExistsAsync(`data.${obj}`, specialObjects[obj]); } await sleep(1000); clearTimeout(timerSleep); @@ -377,16 +377,16 @@ async function createdHistoryStates(adapter, historyDays) { const _historyDays = c + 1; await adapter.setObjectNotExistsAsync(`history.yield_${_historyDays}_days_ago`, { - 'type': 'state', - 'common': { - 'role': 'value.power.consumption', - 'name': `Inverter AC-Energy ${_historyDays} days ago`, - 'type': 'number', - 'read': true, - 'write': false, - 'unit': 'KWh' + type: 'state', + common: { + role: 'value.power.consumption', + name: `Inverter AC-Energy ${_historyDays} days ago`, + type: 'number', + read: true, + write: false, + unit: 'KWh' }, - 'native': {} + native: {} }); } } diff --git a/lib/tools.js b/lib/tools.js index a28044b..c8f3a95 100644 --- a/lib/tools.js +++ b/lib/tools.js @@ -2,8 +2,9 @@ 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} + * + * @param it The variable to test + * @returns */ function isObject(it) { // This is necessary because: @@ -15,8 +16,9 @@ function isObject(it) { /** * 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); @@ -25,10 +27,11 @@ function isArray(it) { /** * 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} + * + * @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') { @@ -45,10 +48,11 @@ async function translateText(text, targetLang, yandexApiKey) { /** * 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} + * + * @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') { @@ -56,6 +60,7 @@ async function translateYandex(text, targetLang, apiKey) { } try { const url = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${encodeURIComponent(text)}&lang=en-${targetLang}`; + // @ts-ignore const response = await axios({url, timeout: 15000}); if (response.data && response.data.text && isArray(response.data.text)) { return response.data.text[0]; @@ -68,13 +73,15 @@ async function translateYandex(text, targetLang, apiKey) { /** * Translates text with Google API - * @param {string} text The text to translate - * @param {string} targetLang The target languate - * @returns {Promise} + * + * @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`; + // @ts-ignore const response = await axios({url, timeout: 15000}); if (isArray(response.data)) { // we got a valid response @@ -82,6 +89,7 @@ async function translateGoogle(text, targetLang) { } throw new Error('Invalid response for translate request'); } catch (e) { + // @ts-ignore if (e.response && e.response.status === 429) { throw new Error( `Could not translate to "${targetLang}": Rate-limited by Google Translate` diff --git a/main.js b/main.js index 076f64a..d762a8a 100644 --- a/main.js +++ b/main.js @@ -172,7 +172,7 @@ async function getSystemData() { function getDate(d) { d = d || new Date(); - return (('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2)); + return (`${(`0${d.getHours()}`).slice(-2)}:${(`0${d.getMinutes()}`).slice(-2)}`); } async function nightCalc(_isNight) { @@ -182,8 +182,8 @@ async function nightCalc(_isNight) { try { const times = SunCalc.getTimes(new Date(), latitude, longitude); - const dusk = ('0' + times.dusk.getHours()).slice(-2) + ':' + ('0' + times.dusk.getMinutes()).slice(-2); - const dawn = ('0' + times.dawn.getHours()).slice(-2) + ':' + ('0' + times.dawn.getMinutes()).slice(-2); + const dusk = `${(`0${times.dusk.getHours()}`).slice(-2)}:${(`0${times.dusk.getMinutes()}`).slice(-2)}`; + const dawn = `${(`0${times.dawn.getHours()}`).slice(-2)}:${(`0${times.dawn.getMinutes()}`).slice(-2)}`; adapter.log.debug(`dusk: ${dusk}`); adapter.log.debug(`dawn: ${dawn}`); @@ -218,8 +218,8 @@ async function sunPos() { const azimuth = Math.round(10 * currentAzimuth) / 10; const altitude = Math.round(10 * currentAltitude) / 10; - adapter.log.debug('Sun Altitude: ' + altitude + '°'); - adapter.log.debug('Sun Azimut: ' + azimuth + '°'); + adapter.log.debug(`Sun Altitude: ${altitude}°`); + adapter.log.debug(`Sun Azimut: ${azimuth}°`); await adapter.setStateAsync('suninfo.Azimut', azimuth, true); await adapter.setStateAsync('suninfo.Altitude', altitude, true); @@ -250,11 +250,11 @@ async function validateURL() { validateStatus: () => true }); } catch (err) { - adapter.log.warn('Solax Cloud is not available: ' + err); + adapter.log.warn(`Solax Cloud is not available: ${err}`); reject(err); } if (available && available.status) { - adapter.log.debug('Solax Cloud is available ... Status: ' + available.status); + adapter.log.debug(`Solax Cloud is available ... Status: ${available.status}`); resolve(cloudURL[url]); break; } @@ -347,7 +347,7 @@ async function fillData() { adapter.log.debug('SolaX API is currently unavailable'); } } catch (err) { - adapter.log.warn('request error: ' + err); + adapter.log.warn(`request error: ${err}`); } // @ts-ignore resolve(); @@ -357,7 +357,7 @@ async function fillData() { async function setData(solaxRequest) { return new Promise(async (resolve) => { - const list = await adapter.getForeignObjectsAsync(adapter.namespace + '.data.*'); + const list = await adapter.getForeignObjectsAsync(`${adapter.namespace}.data.*`); if (list) { let num = 0; @@ -396,7 +396,7 @@ async function setData(solaxRequest) { async function createdJSON() { return new Promise(async (resolve) => { const json = {}; - const infoList = await adapter.getForeignObjectsAsync(adapter.namespace + '.info.*'); + const infoList = await adapter.getForeignObjectsAsync(`${adapter.namespace}.info.*`); if (infoList) { for (const i in infoList) { @@ -412,7 +412,7 @@ async function createdJSON() { } } - const dataList = await adapter.getForeignObjectsAsync(adapter.namespace + '.data.*'); + const dataList = await adapter.getForeignObjectsAsync(`${adapter.namespace}.data.*`); if (dataList) { let num = 0; @@ -641,16 +641,16 @@ async function setDataPoint(dataPoint, data) { // @ts-ignore if (!stateCache.includes(dataPoint.name)) { await adapter.setObjectNotExistsAsync(dataPointPath, { - 'type': 'state', - 'common': { - 'role': dataPoint.role, - 'name': dataPoint.description, - 'type': dataPoint.type, - 'unit': dataPoint.unit, - 'read': true, - 'write': false + type: 'state', + common: { + role: dataPoint.role, + name: dataPoint.description, + type: dataPoint.type, + unit: dataPoint.unit, + read: true, + write: false }, - 'native': {} + native: {} }); stateCache.push(dataPoint.name); @@ -727,7 +727,7 @@ async function main() { astroTimer = setInterval(async () => { _isNight = await nightCalc(_isNight); await sunPos(); - adapter.log.debug('is Night: ' + _isNight); + adapter.log.debug(`is Night: ${_isNight}`); }, 5 * 60 * 1000); schedule.cancelJob('dayHistory');