Skip to content

Commit

Permalink
Merge pull request #112 from Hacksore/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Hacksore authored Mar 25, 2021
2 parents e7947d8 + 440dfae commit 0f04dd7
Show file tree
Hide file tree
Showing 24 changed files with 1,317 additions and 623 deletions.
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# bluelinky

An unoffcial nodejs API wrapper for Hyundai BlueLink
An unofficial nodejs API wrapper for Hyundai BlueLink

[![CI](https://img.shields.io/github/workflow/status/Hacksore/bluelinky/npm)](https://github.com/Hacksore/bluelinky/actions?query=workflow%3Anpm)
[![npm](https://img.shields.io/npm/v/bluelinky.svg)](https://www.npmjs.com/package/bluelinky)
Expand All @@ -18,6 +18,7 @@ const BlueLinky = require('bluelinky');
const client = new BlueLinky({
username: '[email protected]',
password: 'hunter1',
brand: 'hyundai',
region: 'US',
pin: '1234'
});
Expand Down Expand Up @@ -45,7 +46,8 @@ Ensure you have a `config.json` that matches the structure of the following, wit
{
"username": "email",
"password": "password",
"pin": "ping",
"pin": "pin",
"brand": "kia" or "hyundai",
"vin": "vin"
}
```
Expand All @@ -56,12 +58,23 @@ Now you can invoke the debug.ts script with `npm run debug`
## Documentation
Checkout out the [bluelinky-docs](https://hacksore.github.io/bluelinky-docs/) for more info.

Important information for login problems:
- If you experience login problems, please logout from the app on your phone and login again. You might need to ' upgrade ' your account to a generic Kia/Hyundai account, or create a new password or PIN.
- After you migrated your Bluelink account to a generic Hyundai account, or your UVO account to a generic Kia account, make sure that both accounts have the same credentials (userid and password) to avoid confusion in logging in.

## Supported Features
- Lock
- Unlock
- Start (with climate control)
- Stop
- Status
- Status (full, parsed, cached)
- odometer
- location
- startCharge
- monthlyReport
- tripInfo
- EV: getChargeTargets
- EV: setChargeLimits

## Supported Regions
| [Regions](https://github.com/Hacksore/bluelinky/wiki/Regions)
Expand Down
6 changes: 6 additions & 0 deletions __tests__/bluelinky.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe('BlueLinky', () => {
username: '[email protected]',
password: '123',
pin: '1234',
brand: 'hyundai',
region: 'US',
});

Expand Down Expand Up @@ -79,6 +80,7 @@ describe('BlueLinky', () => {
username: '[email protected]',
password: 'hunter1',
pin: '1234',
brand: 'hyundai',
region: 'US',
});

Expand All @@ -96,6 +98,7 @@ describe('BlueLinky', () => {
username: '[email protected]',
password: 'hunter1',
pin: '1234',
brand: 'hyundai',
region: 'KR',
});
}).toThrowError('Your region is not supported yet.');
Expand All @@ -106,6 +109,7 @@ describe('BlueLinky', () => {
username: '[email protected]',
password: 'hunter1',
pin: '1234',
brand: 'hyundai',
region: 'US',
});

Expand All @@ -119,6 +123,7 @@ describe('BlueLinky', () => {
username: '[email protected]',
password: 'hunter1',
pin: '1234',
brand: 'hyundai',
region: 'US',
});

Expand All @@ -133,6 +138,7 @@ describe('BlueLinky', () => {
username: '[email protected]',
password: 'hunter1',
pin: '1234',
brand: 'hyundai',
region: 'US',
});

Expand Down
1 change: 1 addition & 0 deletions __tests__/controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const getController = region => {
username: '[email protected]',
password: 'test',
region: 'US',
brand: 'hyundai',
autoLogin: true,
pin: '1234',
vin: '4444444444444',
Expand Down
1 change: 1 addition & 0 deletions __tests__/vehicle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const getVehicle = (region: string) => {
password: 'test',
region: region,
autoLogin: true,
brand: 'hyundai',
pin: '1234',
vin: '4444444444444',
vehicleId: undefined,
Expand Down
58 changes: 54 additions & 4 deletions debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import config from './config.json';
import BlueLinky from './src';
import inquirer from 'inquirer';
import { Vehicle } from './src/vehicles/vehicle';

const apiCalls = [
{ name: 'exit', value: 'exit' },
Expand All @@ -18,12 +19,16 @@ const apiCalls = [
{ name: 'lock', value: 'lock' },
{ name: 'unlock', value: 'unlock' },
{ name: 'locate', value: 'locate' },
{ name: 'monthly report', value: 'monthlyReport' },
{ name: 'trip informations', value: 'tripInfo' },
{ name: '[EV] get charge targets', value: 'getChargeTargets' },
{ name: '[EV] set charge targets', value: 'setChargeTargets' },
];

let vehicle;
const { username, password, vin, pin } = config;

const onReadyHandler = vehicles => {
const onReadyHandler = <T extends Vehicle>(vehicles: T[]) => {
vehicle = vehicles[0];
askForCommandInput();
};
Expand All @@ -37,23 +42,30 @@ const askForRegionInput = () => {
message: 'What Region are you in?',
choices: ['US', 'EU', 'CA'],
},
{
type: 'list',
name: 'brand',
message: 'Which brand are you using?',
choices: ['hyundai', 'kia'],
}
])
.then(answers => {
if (answers.command == 'exit') {
return;
} else {
console.log(answers)
console.log('Logging in...');
createInstance(answers.region);
createInstance(answers.region, answers.brand);
}
});
};

const createInstance = region => {
const createInstance = (region, brand) => {
const client = new BlueLinky({
username,
password,
region: region,
region,
brand,
pin
});
client.on('ready', onReadyHandler);
Expand Down Expand Up @@ -99,6 +111,13 @@ async function performCommand(command) {
});
console.log('status : ' + JSON.stringify(status, null, 2));
break;
case 'statusU':
const statusU = await vehicle.status({
refresh: false,
parsed: false,
});
console.log('status : ' + JSON.stringify(statusU, null, 2));
break;
case 'statusR':
const statusR = await vehicle.status({
refresh: true,
Expand Down Expand Up @@ -142,6 +161,37 @@ async function performCommand(command) {
const unlockRes = await vehicle.unlock();
console.log('unlock : ' + JSON.stringify(unlockRes, null, 2));
break;
case 'monthlyReport':
const report = await vehicle.monthlyReport();
console.log('monthyReport : ' + JSON.stringify(report, null, 2));
break;
case 'tripInfo':
const trips = await vehicle.tripInfo();
console.log('trips : ' + JSON.stringify(trips, null, 2));
break;
case 'getChargeTargets':
const targets = await vehicle.getChargeTargets();
console.log('targets : ' + JSON.stringify(targets, null, 2));
break;
case 'setChargeTargets':
const { fast, slow } = await inquirer
.prompt([
{
type: 'list',
name: 'fast',
message: 'What fast charge limit do you which to set?',
choices: [50, 60, 70, 80, 90, 100],
},
{
type: 'list',
name: 'slow',
message: 'What slow charge limit do you which to set?',
choices: [50, 60, 70, 80, 90, 100],
}
]);
await vehicle.setChargeTargets({ fast, slow });
console.log('targets : OK');
break;
}

askForCommandInput();
Expand Down
11 changes: 8 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bluelinky",
"version": "6.0.1",
"version": "7.0.0",
"description": "",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand All @@ -18,8 +18,9 @@
"author": "Hacksore",
"license": "MIT",
"dependencies": {
"date-fns": "^2.19.0",
"got": "^9.6.0",
"push-receiver": "^2.1.0",
"push-receiver": "^2.1.1",
"tough-cookie": "^4.0.0",
"url": "^0.11.0",
"winston": "^3.3.3"
Expand Down
10 changes: 5 additions & 5 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// moved all the US constants to its own file, we can use this file for shared constants
import { CA_ENDPOINTS } from './constants/canada';
import { EU_ENDPOINTS } from './constants/europe';
import { getBrandEnvironment as getCABrandEnvironment, CanadianBrandEnvironment } from './constants/canada';
import { getBrandEnvironment as getEUBrandEnvironment, EuropeanBrandEnvironment } from './constants/europe';

import { VehicleStatusOptions } from './interfaces/common.interfaces';
import { Brand, VehicleStatusOptions } from './interfaces/common.interfaces';

export const ALL_ENDPOINTS = {
CA: CA_ENDPOINTS,
EU: EU_ENDPOINTS,
CA: (brand: Brand): CanadianBrandEnvironment['endpoints'] => getCABrandEnvironment(brand).endpoints,
EU: (brand: Brand): EuropeanBrandEnvironment['endpoints'] => getEUBrandEnvironment(brand).endpoints,
};

export const GEN2 = 2;
Expand Down
34 changes: 28 additions & 6 deletions src/constants/america.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
//TODO: Someone needs to figure out the Kia endpoints
// we can then make a fork easier to maintain
import { Brand } from '../interfaces/common.interfaces';

export const API_HOST = 'api.telematics.hyundaiusa.com';
export interface AmericaBrandEnvironment {
brand: Brand;
host: string;
baseUrl: string;
clientId: string;
clientSecret: string;
}

export const BASE_URL = `https://${API_HOST}`;
export const CLIENT_ID = '815c046afaa4471aa578827ad546cc76';
export const CLIENT_SECRET = 'GXZveJJAVTehh/OtakM3EQ==';
const getHyundaiEnvironment = (): AmericaBrandEnvironment => {
const host = 'api.telematics.hyundaiusa.com';
const baseUrl = `https://${host}`;
return {
brand: 'hyundai',
host,
baseUrl,
clientId: '815c046afaa4471aa578827ad546cc76',
clientSecret: 'GXZveJJAVTehh/OtakM3EQ==',
};
};

export const getBrandEnvironment = (brand: Brand): AmericaBrandEnvironment => {
switch (brand) {
case 'hyundai':
return Object.freeze(getHyundaiEnvironment());
default:
throw new Error(`Constructor ${brand} is not managed.`);
}
};
Loading

0 comments on commit 0f04dd7

Please sign in to comment.