pikojs
Version:
Nodejs package to retrieve PV data from a Piko Kostal Inverter.
164 lines (149 loc) • 5.65 kB
JavaScript
/*
* pikojs
*
* Copyright (c) 2018 pitfermi (Petros Mavridis).
*
* pikojs's license follows:
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* This license applies to all parts of pikojs that are not externally
* maintained libraries.
*/
var axios = require('axios');
var cheerio = require('cheerio');
/**
* Initialize Piko object
* @param {object} options
* @return {void}
*/
function Piko(options) {
this._options = {
host: options.hostname || null,
username: options.username || 'pvserver',
password: options.password || 'pvwr',
port: options.port || '80'
};
}
/**
* Fetch HTML from the Piko webpage using Promises.
* Note that getData returns a Promise
* @return {Promise<object>}
*/
Piko.prototype.getData = async function () {
try {
const url = `${this._options.host}:${this._options.port}`;
return this.parseHTML(
(await axios(url, {
method: 'get',
auth: {
username: this._options.username,
password: this._options.password
}
})).data
);
} catch (error) {
console.log(error);
}
};
/**
* Parse the HTML for the various values
* using CSS selectors
* @param {string} htmlPage htmlpage string to be parsed
* @return {object}
*/
Piko.prototype.parseHTML = function (htmlPage) {
var $ = cheerio.load(htmlPage);
let name = $('body > form > table > tr:nth-child(2) > td:nth-child(2) > font > font').text().trim();
let currentACPower = this.fixValue($('body > form > font > table:nth-child(2) > tr:nth-child(4) > td:nth-child(3)').text());
let dailyEnergy = this.fixValue($('body > form > font > table:nth-child(2) > tr:nth-child(6) > td:nth-child(6)').text());
let totalEnergy = this.fixValue($('body > form > font > table:nth-child(2) > tr:nth-child(4) > td:nth-child(6)').text());
let status = $('body > form > font > table:nth-child(2) > tr:nth-child(8) > td:nth-child(3)').text().trim();
let dcV1 = this.fixValue($('body > form > tr:nth-child(7) > td:nth-child(3)').text());
let dcC1 = this.fixValue($('body > form > tr:nth-child(9) > td:nth-child(3)').text());
let dcV2 = this.fixValue($('body > form > tr:nth-child(12) > td:nth-child(3)').text());
let dcC2 = this.fixValue($('body > form > tr:nth-child(14) > td:nth-child(3)').text());
let dcV3 = this.fixValue($('body > form > tr:nth-child(17) > td:nth-child(3)').text());
let dcC3 = this.fixValue($('body > form > tr:nth-child(19) > td:nth-child(3)').text());
let acV1 = this.fixValue($('body > form > tr:nth-child(7) > td:nth-child(6)').text());
let acP1 = this.fixValue($('body > form > tr:nth-child(9) > td:nth-child(6)').text());
let acV2 = this.fixValue($('body > form > tr:nth-child(12) > td:nth-child(6)').text());
let acP2 = this.fixValue($('body > form > tr:nth-child(14) > td:nth-child(6)').text());
let acV3 = this.fixValue($('body > form > tr:nth-child(17) > td:nth-child(6)').text());
let acP3 = this.fixValue($('body > form > tr:nth-child(19) > td:nth-child(6)').text());
return {
name,
status,
currentACPower,
dailyEnergy,
totalEnergy,
units: {
power: "W",
energy: "kWh",
voltage: "V",
current: "A"
},
dc: [
{
id: "1",
voltage: dcV1,
current: dcC1
},
{
id: "2",
voltage: dcV2,
current: dcC2
},
{
id: "3",
voltage: dcV3,
current: dcC3
}
],
ac: [
{
id: "1",
voltage: acV1,
power: acP1
},
{
id: "2",
voltage: acV2,
power: acP2
},
{
id: "3",
voltage: acV3,
power: acP3
}
]
};
}
/**
* Fix value in case '0' is represented as 'x x x...'
* @param {string} value
* @return {number}
*/
Piko.prototype.fixValue = function (value) {
if (typeof value === 'string') {
value = value.trim();
}
return (value.includes("x x x") ? 0 : parseFloat(value));
}
module.exports = Piko;