Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

iobroker.bluelink

Package Overview
Dependencies
Maintainers
3
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

iobroker.bluelink - npm Package Compare versions

Comparing version
3.0.3
to
3.1.0
+57
eslint.config.cjs
const globals = require('globals');
const js = require('@eslint/js');
const { FlatCompat } = require('@eslint/eslintrc');
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
module.exports = [
{
ignores: ['.dev-server/**'],
},
...compat.extends('eslint:recommended', 'plugin:prettier/recommended'),
{
languageOptions: {
globals: {
...globals.node,
...globals.mocha,
},
ecmaVersion: 2022,
sourceType: 'commonjs',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
rules: {
indent: ['error', 4, { SwitchCase: 1 }],
'prettier/prettier': ['off', { endOfLine: 'auto' }],
'no-unused-vars': 'off',
'no-console': 'off',
'no-var': 'error',
'no-trailing-spaces': 'error',
'prefer-const': 'warn',
'no-prototype-builtins': 'warn',
'no-case-declarations': 'warn',
'no-useless-escape': 'warn',
quotes: [
'error',
'single',
{
avoidEscape: true,
allowTemplateLiterals: true,
},
],
},
},
];
+13
-13

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

{
{
'Username': {
'en': 'Username',
'de': 'Nutzername',
'ru': 'Имя пользователя',
'pt': 'Nome de usuário',
'nl': 'Gebruikersnaam',
'fr': "Nom d'utilisateur",
'it': 'Nome utente',
'es': 'Nombre de usuario',
'pl': 'Nazwa Użytkownika',
'zh-cn': '用户名'
},
'bluelink adapter settings': {

@@ -14,14 +26,2 @@ 'en': 'Adapter settings for bluelink',

},
'Username': {
'en': 'Username',
'de': 'Nutzername',
'ru': 'Имя пользователя',
'pt': 'Nome de usuário',
'nl': 'Gebruikersnaam',
'fr': "Nom d'utilisateur",
'it': 'Nome utente',
'es': 'Nombre de usuario',
'pl': 'Nazwa Użytkownika',
'zh-cn': '用户名'
},
'Password': {

@@ -28,0 +28,0 @@ 'en': 'Password',

{
"common": {
"name": "bluelink",
"version": "3.0.3",
"version": "3.1.0",
"news": {
"3.1.0": {
"en": "SOC corr \ndependency update",
"de": "SOC corr\naktualisierung der abhängigkeit",
"ru": "SOC corr\nобновление",
"pt": "Corantes SOC\natualização de dependência",
"nl": "SOC corr\nafhankelijkheidsupdate",
"fr": "SOC corr\nmise à jour de la dépendance",
"it": "Corpo SOC\naggiornamento della dipendenza",
"es": "SOC corr\nactualización de la dependencia",
"pl": "SOC corr\naktualizacja zależności",
"uk": "СОК кор\nоновлення залежності",
"zh-cn": "SOC 缩写\n依赖性更新"
},
"3.0.4": {
"en": "typo",
"de": "typo",
"ru": "typo",
"pt": "tipo:",
"nl": "type",
"fr": "typo",
"it": "tipo",
"es": "typo",
"pl": "typo",
"uk": "типи",
"zh-cn": "类型"
},
"3.0.3": {

@@ -70,28 +96,2 @@ "en": "add city to position text",

"zh-cn": "重新设计"
},
"2.3.10": {
"en": "add address as text using openstreetmap",
"de": "adresse als text hinzufügen mit opentreetmap",
"ru": "добавить адрес как текст с помощью opentreetmap",
"pt": "adicionar endereço como texto usando o opentreetmap",
"nl": "adres toevoegen als tekst met openstreetmap",
"fr": "ajouter l'adresse comme texte en utilisant openstreetmap",
"it": "aggiungere l'indirizzo come testo usando openstreetmap",
"es": "añadir dirección como texto usando openstreetmap",
"pl": "dodaj adres jako tekst używając openstreetmap",
"uk": "додати адресу як текст за допомогою openstreetmap",
"zh-cn": "使用 opentreetmap 添加地址为文本"
},
"2.3.9": {
"en": "add ccs2 car status",
"de": "ccs2 autostatus hinzufügen",
"ru": "добавить статус автомобиля ccs2",
"pt": "adicionar status do carro ccs2",
"nl": "ccs2 autostatus toevoegen",
"fr": "ajouter ccs2 statut de voiture",
"it": "aggiungere ccs2 auto stato",
"es": "añadir ccs2 estado del coche",
"pl": "dodaj status samochodu ccs2",
"uk": "додати стан автомобіля ccs2",
"zh-cn": "添加 ccs2 车位"
}

@@ -98,0 +98,0 @@ },

@@ -65,13 +65,13 @@

await this.adapter.setObjectNotExistsAsync(vin + '.control.force_checkDriveInfo', {
type: 'state',
common: {
name: 'Force load Drive Infos',
type: 'boolean',
role: 'button',
read: true,
write: true,
def: true,
},
native: {},
});
type: 'state',
common: {
name: 'Force load Drive Infos',
type: 'boolean',
role: 'button',
read: true,
write: true,
def: true,
},
native: {},
});

@@ -78,0 +78,0 @@ this.adapter.subscribeStates(vin + '.control.force_checkDriveInfo');

@@ -18,47 +18,22 @@ //v1.5b

async parse(path, element, options) {
if (element === null || element === undefined) {
this.adapter.log.debug('Cannot extract empty: ' + path);
return;
}
const objectKeys = Object.keys(element);
if (element === null || element === undefined) {
this.adapter.log.debug('Cannot extract empty: ' + path);
return;
}
if (!options || !options.write) {
if (!options) {
options = { write: false };
} else {
options['write'] = false;
}
const objectKeys = Object.keys(element);
if (!options || !options.write) {
if (!options) {
options = { write: false };
} else {
options['write'] = false;
}
}
if (typeof element === 'string' || typeof element === 'number') {
let name = element;
if (typeof element === 'number') {
name = element.toString();
}
if (!this.alreadyCreatedObjects[path]) {
await this.adapter
.setObjectNotExistsAsync(path, {
type: 'state',
common: {
name: name,
role: this.getRole(element, options.write),
type: element !== null ? typeof element : 'mixed',
write: options.write,
read: true,
},
native: {},
})
.then(() => {
this.alreadyCreatedObjects[path] = true;
})
.catch((error) => {
this.adapter.log.error(error);
});
}
this.adapter.setState(path, element, true);
return;
if (typeof element === 'string' || typeof element === 'number') {
let name = element;
if (typeof element === 'number') {
name = element.toString();
}

@@ -68,6 +43,8 @@ if (!this.alreadyCreatedObjects[path]) {

.setObjectNotExistsAsync(path, {
type: 'channel',
type: 'state',
common: {
name: options.channelName || '',
write: false,
name: name,
role: this.getRole(element, options.write),
type: element !== null ? typeof element : 'mixed',
write: options.write,
read: true,

@@ -79,3 +56,2 @@ },

this.alreadyCreatedObjects[path] = true;
options.channelName = undefined;
})

@@ -86,51 +62,75 @@ .catch((error) => {

}
if (Array.isArray(element)) {
await this.extractArray(element, '', path, options);
return;
}
for (const key of objectKeys) {
try {
if (Array.isArray(element[key])) {
await this.extractArray(element, key, path, options);
} else if (element[key] !== null && element[key] !== undefined && typeof element[key] === 'object') {
await this.parse(path + '.' + key, element[key], options);
} else {
if (!this.alreadyCreatedObjects[path + '.' + key]) {
let objectName = key;
if (options.descriptions && options.descriptions[key]) {
objectName = options.descriptions[key];
}
const type = element[key] !== null && element[key] !== undefined ? typeof element[key] : 'mixed';
const common = {
name: objectName,
role: this.getRole(element[key], options.write),
type: type,
write: options.write,
read: true,
};
await this.adapter
.setObjectNotExistsAsync(path + '.' + key, {
type: 'state',
common: common,
native: {},
})
.then(() => {
this.alreadyCreatedObjects[path + '.' + key] = true;
})
.catch((error) => {
this.adapter.log.error(error);
});
this.adapter.setState(path, element, true);
return;
}
if (!this.alreadyCreatedObjects[path]) {
await this.adapter
.setObjectNotExistsAsync(path, {
type: 'channel',
common: {
name: options.channelName || '',
write: false,
read: true,
},
native: {},
})
.then(() => {
this.alreadyCreatedObjects[path] = true;
options.channelName = undefined;
})
.catch((error) => {
this.adapter.log.error(error);
});
}
if (Array.isArray(element)) {
await this.extractArray(element, '', path, options);
return;
}
for (const key of objectKeys) {
try {
if (Array.isArray(element[key])) {
await this.extractArray(element, key, path, options);
} else if (element[key] !== null && element[key] !== undefined && typeof element[key] === 'object') {
await this.parse(path + '.' + key, element[key], options);
} else {
if (!this.alreadyCreatedObjects[path + '.' + key]) {
let objectName = key;
if (options.descriptions && options.descriptions[key]) {
objectName = options.descriptions[key];
}
if (element[key] !== undefined) {
this.adapter.setState(path + '.' + key, element[key], true);
}
const type = element[key] !== null && element[key] !== undefined ? typeof element[key] : 'mixed';
const common = {
name: objectName,
role: this.getRole(element[key], options.write),
type: type,
write: options.write,
read: true,
};
await this.adapter
.setObjectNotExistsAsync(path + '.' + key, {
type: 'state',
common: common,
native: {},
})
.then(() => {
this.alreadyCreatedObjects[path + '.' + key] = true;
})
.catch((error) => {
this.adapter.log.error(error);
});
}
} catch (error) {
this.adapter.log.error('Error extract objectKeys: ' + path + '.' + element);
this.adapter.log.error(error);
if (element[key] !== undefined) {
this.adapter.setState(path + '.' + key, element[key], true);
}
}
} catch (error) {
this.adapter.log.error('Error extract objectKeys: ' + path + '.' + element);
this.adapter.log.error(error);
}
}
}

@@ -137,0 +137,0 @@ async extractArray(element, key, path, options) {

@@ -46,23 +46,3 @@ const axios = require('axios').default;

/**
* 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>}
*/
async function getResolvedAddress(latitude,longitude) {
try {
const url = `https://nominatim.openstreetmap.org/reverse.php?format=json&lat=${latitude}&lon==${longitude}&zoom=18`;
const response = await axios({url, timeout: 5000});
if (response.data) {
const addr = ([strasse ? strasse : null,hausnummer ? [' ',hausnummer,''].join('') : null,strasse ? ', ' : null,plz ? String(plz) + ' ' : null,stadt ? String(stadt) + '' : null,stadtteil ? [' (',stadtteil,')'].join('') : null,kreis ? ', ' + String(kreis) : null,bundesland ? ', ' + String(bundesland) : null,land ? ', ' + String(land) : null,!land ? 'not found.' : null].join(''));
return addr;
}
} catch (err) {
throw new Error(`Could not find address: ${err}`);
}
}
async function getResolveAddress(latitude,longitude) {

@@ -84,2 +64,24 @@ try {

}
/**
* 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>}
*/
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 && isArray(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}`);
}
}

@@ -86,0 +88,0 @@ /**

+141
-139

@@ -50,3 +50,3 @@ 'use strict';

adapterIntervals.evHistoryInterval = null;
this.countError = 0;
this.countError = 0;
}

@@ -117,3 +117,3 @@

let force_update_obj = await this.getStateAsync(`${vin}.control.force_update`);
const force_update_obj = await this.getStateAsync(`${vin}.control.force_update`);
try {

@@ -124,3 +124,3 @@ switch (tmpControl) {

await this.readStatusVin(vehicle, force_update_obj.val);
this.driveHistory(vehicle);
this.driveHistory(vehicle);
break;

@@ -139,5 +139,5 @@ case 'lock':

this.log.info('Starting clima for vehicle');
let airTempC = await this.getStateAsync(`${vin}.control.clima.set.airTemp`);
let defrost = await this.getStateAsync(`${vin}.control.clima.set.defrost`);
let heating = await this.getStateAsync(`${vin}.control.clima.set.heating`);
const airTempC = await this.getStateAsync(`${vin}.control.clima.set.airTemp`);
const defrost = await this.getStateAsync(`${vin}.control.clima.set.defrost`);
const heating = await this.getStateAsync(`${vin}.control.clima.set.heating`);
try {

@@ -153,4 +153,4 @@ response = await vehicle.start({

vin: vin,
});
});
this.log.debug(JSON.stringify(response));

@@ -211,10 +211,10 @@ } catch (err) {

//set fast charging
let charge_limit_slow = await this.getStateAsync(`${vin}.control.charge_limit_slow`);
const charge_limit_slow = await this.getStateAsync(`${vin}.control.charge_limit_slow`);
charge_option.fast = state.val;
charge_option.slow = charge_limit_slow.val;
}
}
if (tmpControl == 'charge_limit_slow') {
this.log.info('Set new charging options charge_limit_slow');
//set slow charging
let charge_limit_fast = await this.getStateAsync(`${vin}.control.charge_limit_fast`);
const charge_limit_fast = await this.getStateAsync(`${vin}.control.charge_limit_fast`);
charge_option.slow = state.val;

@@ -309,3 +309,3 @@ charge_option.fast = charge_limit_fast.val;

let requestTimeout = setTimeout(async () => {
const requestTimeout = setTimeout(async () => {
this.login();

@@ -328,15 +328,15 @@ }, 1000 * 60 * 60); // warte 1 stunde

for (const vehicle of this.vehicles) {
const vin = vehicle.vehicleConfig.vin;
let force_update_obj = await this.getStateAsync(`${vin}.control.force_update`);
this.log.debug('Read new status from api for ' + vin);
let batteryControlState12V = await this.getStateAsync(`${vin}.control.batteryControlState12V`);
const vin = vehicle.vehicleConfig.vin;
const force_update_obj = await this.getStateAsync(`${vin}.control.force_update`);
this.log.debug('Read new status from api for ' + vin);
const batteryControlState12V = await this.getStateAsync(`${vin}.control.batteryControlState12V`);
if (this.batteryState12V[vin] && this.batteryState12V[vin] < batteryControlState12V.val && force_update_obj.val) {
this.log.warn('12V Battery state is low: ' + this.batteryState12V[vin] + '%. Recharge to prevent damage!');
if (this.config.protectAgainstDeepDischarge && !force) {
this.log.warn('Auto Refresh is disabled, only use force refresh to reenable refresh if you are willing to risk your battery');
continue;
}
}
await this.readStatusVin(vehicle,force_update_obj.val);
if (this.batteryState12V[vin] && this.batteryState12V[vin] < batteryControlState12V.val && force_update_obj.val) {
this.log.warn('12V Battery state is low: ' + this.batteryState12V[vin] + '%. Recharge to prevent damage!');
if (this.config.protectAgainstDeepDischarge && !force) {
this.log.warn('Auto Refresh is disabled, only use force refresh to reenable refresh if you are willing to risk your battery');
continue;
}
}
await this.readStatusVin(vehicle,force_update_obj.val);
}

@@ -355,72 +355,72 @@

async readStatusVin(vehicle, force_update) {
const vin = vehicle.vehicleConfig.vin;
try {
let newStatus;
const vin = vehicle.vehicleConfig.vin;
try {
let newStatus;
if(force_update) {
this.log.info('Read new update for ' + vin + ' directly from the car');
} else {
this.log.info('Read new update for ' + vin + ' from the server');
}
if(force_update) {
this.log.info('Read new update for ' + vin + ' directly from the car');
} else {
this.log.info('Read new update for ' + vin + ' from the server');
}
try {
try {
newStatus = await vehicle.fullStatus({
refresh: force_update,
parsed: true,
});
newStatus = await vehicle.fullStatus({
refresh: force_update,
parsed: true,
});
//set all values
this.log.debug('Set new full status for ' + vin);
this.log.debug('RAW ' + JSON.stringify(newStatus));
//set all values
this.log.debug('Set new full status for ' + vin);
this.log.debug('RAW ' + JSON.stringify(newStatus));
// raw data
await this.json2iob.parse(vin + '.vehicleStatusRaw', newStatus);
await this.setNewFullStatus(newStatus, vin);
// raw data
await this.json2iob.parse(vin + '.vehicleStatusRaw', newStatus);
await this.setNewFullStatus(newStatus, vin);
} catch (error) {
if (typeof error === 'string') {
this.log.error('Error on API-Request GetFullStatus');
this.log.error(error);
} else {
//if(error.source.statusCode == 503) {
this.log.info('Error on API-Full-Status - Fallback GetStatusFromCar');
} catch (error) {
if (typeof error === 'string') {
this.log.error('Error on API-Request GetFullStatus');
this.log.error(error);
} else {
//if(error.source.statusCode == 503) {
this.log.info('Error on API-Full-Status - Fallback GetStatusFromCar');
//Abfrage Full hat nicht geklappt. Haben wir einen Fallback?
newStatus = await vehicle.status({
refresh: force_update,
parsed: true,
});
this.log.debug('Set new GetNormalStatus for ' + vin);
this.log.debug(JSON.stringify(newStatus));
//Abfrage Full hat nicht geklappt. Haben wir einen Fallback?
newStatus = await vehicle.status({
refresh: force_update,
parsed: true,
});
this.log.debug('Set new GetNormalStatus for ' + vin);
this.log.debug(JSON.stringify(newStatus));
await this.json2iob.parse(vin + '.vehicleStatusRaw', newStatus);
await this.setShortStatus(newStatus, vin);
}
}
await this.json2iob.parse(vin + '.vehicleStatusRaw', newStatus);
await this.setShortStatus(newStatus, vin);
}
}
//Abfrage war erfolgreich, lösche ErrorCounter
this.countError = 0;
await this.setStateAsync(`${vin}.error_counter`, this.countError, true);
this.log.info('Update for ' + vin + ' successfull');
// last update
await this.setStateAsync(`${vin}.lastInfoUpdate`, Number(Date.now()), true);
//Abfrage war erfolgreich, lösche ErrorCounter
this.countError = 0;
await this.setStateAsync(`${vin}.error_counter`, this.countError, true);
this.log.info('Update for ' + vin + ' successfull');
// last update
await this.setStateAsync(`${vin}.lastInfoUpdate`, Number(Date.now()), true);
} catch (error) {
this.countError += 1; // add 1
} catch (error) {
this.countError += 1; // add 1
this.log.error('Error on API-Request Status, ErrorCount:' + this.countError);
if (typeof error === 'string') {
this.log.error(error);
} else if (error instanceof Error) {
this.log.error(error.message);
}
}
this.log.error('Error on API-Request Status, ErrorCount:' + this.countError);
if (typeof error === 'string') {
this.log.error(error);
} else if (error instanceof Error) {
this.log.error(error.message);
}
}
await this.setStateAsync(`${vin}.error_counter`, this.countError, true);
await this.setStateAsync(`${vin}.error_counter`, this.countError, true);
if (this.countError > this.config.errorCounter) {
//Error counter over x erros, restart Adapter to fix te API Token
this.restart();
}
if (this.countError > this.config.errorCounter) {
//Error counter over x erros, restart Adapter to fix te API Token
this.restart();
}
}

@@ -434,5 +434,5 @@

this.driveHistory(vehicle);
}
}
}
async driveHistory(vehicle) {

@@ -443,3 +443,3 @@ try {

const vin = vehicle.vehicleConfig.vin;
if (driveHistory.hasOwnProperty('cumulated[0]')) {

@@ -454,7 +454,7 @@ this.log.debug('driveHistory-Data: ' + JSON.stringify(driveHistory));

});
await this.json2iob.parse(vin + '.driveHistory', driveHistory, { preferedArrayName: 'rawDate' });
this.todayOnly(vin, driveHistory);
const monthlyReport = await vehicle.monthlyReport();

@@ -488,9 +488,9 @@ await this.setObjectNotExistsAsync(vin + '.monthlyReport', {

}
async todayOnly(vin, driveHistory) {
let onlyHistory = driveHistory.history;
const onlyHistory = driveHistory.history;
const today = this.getToday();
for (const lpEntry in onlyHistory) {
let res = onlyHistory[lpEntry];
const res = onlyHistory[lpEntry];
this.log.debug('check Today ' + today + ' ' + res.rawDate);

@@ -511,5 +511,5 @@ if (today == res.rawDate) { // suche heutiges Datum

}
getToday() {
var today = new Date();
const today = new Date();
const yyyy = today.getFullYear();

@@ -524,3 +524,3 @@ let mm = today.getMonth() + 1;

}
//short status

@@ -587,3 +587,3 @@ async setShortStatus(newStatus, vin) {

if (newStatus.vehicleStatus.hasOwnProperty("airTemp")) {
if (newStatus.vehicleStatus.hasOwnProperty('airTemp')) {
await this.setStateAsync(vin + '.vehicleStatus.airTemp', {

@@ -603,30 +603,32 @@ val: this.getCelsiusFromTempcode(newStatus.vehicleStatus.airTemp.value),

if (newStatus.vehicleStatus.hasOwnProperty('evStatus')) {
if (newStatus.vehicleStatus.evStatus.reservChargeInfos.targetSOClist[0].plugType == 1) {
//Slow = 1 -> Index 0 ist slow
slow_charging = newStatus.vehicleStatus.evStatus.reservChargeInfos.targetSOClist[0].targetSOClevel;
await this.setStateAsync(vin + '.control.charge_limit_slow', {
val: slow_charging,
ack: true,
});
if (newStatus.vehicleStatus.evStatus.reservChargeInfos.hasOwnProperty('targetSOClist[0]')) {
if (newStatus.vehicleStatus.evStatus.reservChargeInfos.targetSOClist[0].plugType == 1) {
//Slow = 1 -> Index 0 ist slow
slow_charging = newStatus.vehicleStatus.evStatus.reservChargeInfos.targetSOClist[0].targetSOClevel;
await this.setStateAsync(vin + '.control.charge_limit_slow', {
val: slow_charging,
ack: true,
});
fast_charging = newStatus.vehicleStatus.evStatus.reservChargeInfos.targetSOClist[1].targetSOClevel;
await this.setStateAsync(vin + '.control.charge_limit_fast', {
val: fast_charging,
ack: true,
});
} else {
//fast = 0 -> Index 0 ist fast
slow_charging = newStatus.vehicleStatus.evStatus.reservChargeInfos.targetSOClist[1].targetSOClevel;
await this.setStateAsync(vin + '.control.charge_limit_slow', {
val: slow_charging,
ack: true,
});
fast_charging = newStatus.vehicleStatus.evStatus.reservChargeInfos.targetSOClist[1].targetSOClevel;
await this.setStateAsync(vin + '.control.charge_limit_fast', {
val: fast_charging,
ack: true,
});
fast_charging = newStatus.vehicleStatus.evStatus.reservChargeInfos.targetSOClist[0].targetSOClevel;
await this.setStateAsync(vin + '.control.charge_limit_fast', {
val: fast_charging,
ack: true,
});
}
} else {
//fast = 0 -> Index 0 ist fast
slow_charging = newStatus.vehicleStatus.evStatus.reservChargeInfos.targetSOClist[1].targetSOClevel;
await this.setStateAsync(vin + '.control.charge_limit_slow', {
val: slow_charging,
ack: true,
});
fast_charging = newStatus.vehicleStatus.evStatus.reservChargeInfos.targetSOClist[0].targetSOClevel;
await this.setStateAsync(vin + '.control.charge_limit_fast', {
val: fast_charging,
ack: true,
});
}
}

@@ -682,11 +684,11 @@ //Nur für Elektro Fahrzeuge - Battery

if (newStatus.ccs2Status.state.Vehicle.Green.BatteryManagement.hasOwnProperty('BatteryRemain')) {
await this.setStateAsync(vin + '.vehicleStatus.battery.soc', {
val: newStatus.ccs2Status.state.Vehicle.Green.BatteryManagement.BatteryRemain.Ratio,
ack: true
});
}
if (newStatus.ccs2Status.state.hasOwnProperty('Vehicle') && newStatus.ccs2Status.state.Vehicle.Green.BatteryManagement.hasOwnProperty('BatteryRemain')) {
await this.setStateAsync(vin + '.vehicleStatus.battery.soc', {
val: newStatus.ccs2Status.state.Vehicle.Green.BatteryManagement.BatteryRemain.Ratio,
ack: true
});
}
// hier nachschauen welcher DP
/* await this.setStateAsync(vin + '.vehicleStatus.battery.charge', {
/* await this.setStateAsync(vin + '.vehicleStatus.battery.charge', {
val: newStatus.vehicleStatus.?????,

@@ -707,15 +709,15 @@ ack: true

//fast = 0 -> Index 0 ist fast
if (newStatus.ccs2Status.state.Vehicle.Green.ChargingInformation.hasOwnProperty('TargetSoC')) {
slow_charging = newStatus.ccs2Status.state.Vehicle.Green.ChargingInformation.TargetSoC.Standard;
await this.setStateAsync(vin + '.control.charge_limit_slow', {
val: slow_charging,
ack: true,
});
fast_charging = newStatus.ccs2Status.state.Vehicle.Green.ChargingInformation.TargetSoC.Quick;
await this.setStateAsync(vin + '.control.charge_limit_fast', {
val: fast_charging,
ack: true,
});
}
if (newStatus.ccs2Status.state.Vehicle.Green.ChargingInformation.hasOwnProperty('TargetSoC')) {
slow_charging = newStatus.ccs2Status.state.Vehicle.Green.ChargingInformation.TargetSoC.Standard;
await this.setStateAsync(vin + '.control.charge_limit_slow', {
val: slow_charging,
ack: true,
});
fast_charging = newStatus.ccs2Status.state.Vehicle.Green.ChargingInformation.TargetSoC.Quick;
await this.setStateAsync(vin + '.control.charge_limit_fast', {
val: fast_charging,
ack: true,
});
}
} else {

@@ -722,0 +724,0 @@ if (newStatus.vehicleStatus.hasOwnProperty('battery')) {

{
"name": "iobroker.bluelink",
"version": "3.0.3",
"version": "3.1.0",
"description": "Adapter to control Hyundai or Kia vehicle",

@@ -40,8 +40,8 @@ "author": {

"dependencies": {
"@iobroker/adapter-core": "^3.1.3",
"@iobroker/adapter-core": "^3.1.6",
"bluelinky": "https://github.com/Hacksore/bluelinky/tarball/abdedb456ea792307a7429a503f8737d66b1beb8",
"axios": "^1.6.8"
"axios": "^1.7.7"
},
"devDependencies": {
"@alcalzone/release-script": "^3.7.0",
"@alcalzone/release-script": "^3.8.0",
"@alcalzone/release-script-plugin-iobroker": "^3.7.2",

@@ -51,3 +51,3 @@ "@alcalzone/release-script-plugin-license": "^3.7.0",

"@iobroker/testing": "^4.1.0",
"@types/node": "^20.12.7",
"@types/node": "^22.7.4",
"@types/chai": "^4.3.6",

@@ -61,6 +61,8 @@ "@types/chai-as-promised": "^7.1.5",

"chai-as-promised": "^7.1.1",
"eslint": "^8.52.0",
"mocha": "^10.2.0",
"eslint": "^9.11.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"mocha": "^10.7.3",
"proxyquire": "^2.1.3",
"sinon": "^17.0.1",
"sinon": "^19.0.2",
"sinon-chai": "^3.7.0",

@@ -67,0 +69,0 @@ "typescript": "^5.5.3"

@@ -39,2 +39,9 @@ ![Logo](admin/bluelink.png)

## Changelog
### 3.1.0 (2024-10-05)
* (arteck) SOC corr
* (arteck) dependency update
### 3.0.4 (2024-10-03)
* (arteck) typo
### 3.0.3 (2024-10-02)

@@ -41,0 +48,0 @@ * (arteck) add city to position text