homebridge-fibaro-home-center
Version:
Homebridge plugin for Fibaro Home Center (2, 2 Lite, 3, 3 Lite, Yubii Home).
236 lines • 8.88 kB
JavaScript
"use strict";
// fibaro-api.ts
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FibaroClient = void 0;
const superagent_1 = __importDefault(require("superagent"));
const superagent_throttle_1 = __importDefault(require("superagent-throttle"));
const os = __importStar(require("os"));
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const constants = __importStar(require("./constants"));
// Throttle for GET requests
// fix HC2 - 503-error (devices > 100)
const throttle = new superagent_throttle_1.default({
active: true,
rate: constants.DEFAULT_THROTTLE_RATE,
ratePer: constants.DEFAULT_THROTTLE_RATE_PER,
concurrent: constants.DEFAULT_THROTTLE_CONCURRENT,
});
class FibaroClient {
constructor(baseUrl, username, password, log, adminUsername, adminPassword) {
var _a;
this.baseUrl = baseUrl;
this.auth = this.createAuthString(username, password);
this.adminAuth = adminUsername ? this.createAuthString(adminUsername, adminPassword) : '';
this.https = (_a = baseUrl === null || baseUrl === void 0 ? void 0 : baseUrl.includes('https:')) !== null && _a !== void 0 ? _a : false;
this.ca = this.loadCertificate(log);
this.status = this.https && !this.ca ? false : true;
if (this.https && !this.ca) {
log('Put a valid ca.cer file in config.json folder.');
}
}
createAuthString(username, password) {
return 'Basic ' + Buffer.from(`${username}:${password}`).toString('base64');
}
loadCertificate(log) {
var _a;
if (!this.baseUrl || !this.https) {
return null;
}
const certPaths = [
...constants.CERTIFICATE_PATHS,
path.resolve(((_a = process.env.UIX_CONFIG_PATH) === null || _a === void 0 ? void 0 : _a.replace(/\/config\.json$/, '')) || path.join(os.homedir(), '.homebridge'), constants.CERTIFICATE_FILE_NAME),
];
for (const certPath of certPaths) {
try {
if (fs.existsSync(certPath)) {
return fs.readFileSync(certPath);
}
}
catch (e) {
log(`Error reading ${constants.CERTIFICATE_FILE_NAME} from ${certPath}:`, e);
}
}
return null;
}
composeURL(service) {
return this.baseUrl + service;
}
async genericGet(service) {
const url = this.composeURL(service);
let request = superagent_1.default
.get(url)
.use(throttle.plugin())
.set('Authorization', this.auth)
.set('accept', constants.HTTP_ACCEPT_HEADER);
if (this.https) {
request = request.ca(this.ca);
}
return request;
}
genericPost(service, body) {
const url = this.composeURL(service);
let request = superagent_1.default
.post(url)
.use(throttle.plugin())
.send(body)
.set('Authorization', this.auth)
.set('accept', constants.HTTP_ACCEPT_HEADER);
if (this.https) {
request = request.ca(this.ca);
}
return request.catch(error => {
if (error.message === 'Request discarded due to concurrent limit') {
// Silently discard the request
return Promise.resolve({ discarded: true });
}
throw error; // Re-throw other errors
});
}
genericPut(service, body) {
const url = this.composeURL(service);
let request = superagent_1.default
.put(url)
.use(throttle.plugin())
.send(body)
.set('Authorization', this.auth)
.set('accept', constants.HTTP_ACCEPT_HEADER);
if (this.https) {
request = request.ca(this.ca);
}
return request.catch(error => {
if (error.message === 'Request discarded due to concurrent limit') {
// Silently discard the request
return Promise.resolve({ discarded: true });
}
throw error; // Re-throw other errors
});
}
genericAdminPut(service, body) {
const url = this.composeURL(service);
let request = superagent_1.default
.put(url)
.use(throttle.plugin())
.send(body)
.set('Authorization', this.adminAuth)
.set('accept', constants.HTTP_ACCEPT_HEADER);
if (this.https) {
request = request.ca(this.ca);
}
return request;
}
getInfo() {
return this.genericGet(constants.API_URL_INFO);
}
getScenes() {
return this.genericGet(constants.API_URL_SCENES);
}
getClimateZones() {
return this.genericGet(constants.API_URL_CLIMATE + '?detailed=false');
}
getClimateZone(ID) {
return this.genericGet(constants.API_URL_CLIMATE + '/' + ID);
}
getHeatingZones() {
return this.genericGet(constants.API_URL_HEATING);
}
getHeatingZone(ID) {
return this.genericGet(constants.API_URL_HEATING + '/' + ID);
}
setClimateZoneHandTemperature(ID, mode, temperature, timestamp) {
const body = {
'properties': {
'handMode': mode,
'handTimestamp': timestamp,
},
};
switch (mode) {
case 'Heat':
body.properties['handSetPointHeating'] = temperature;
break;
case 'Cool':
body.properties['handSetPointCooling'] = temperature;
break;
}
return this.genericPut(constants.API_URL_CLIMATE + '/' + ID, body);
}
setHeatingZoneHandTemperature(ID, temperature, timestamp) {
const body = {
'properties': {
'handTemperature': temperature,
'handTimestamp': timestamp,
},
};
return this.genericPut(constants.API_URL_HEATING + '/' + ID, body);
}
getRooms() {
return this.genericGet(constants.API_URL_ROOMS);
}
getDevices() {
return this.genericGet(constants.API_URL_DEVICES);
}
getDeviceProperties(ID) {
return this.genericGet(constants.API_URL_DEVICES + '/' + ID);
}
refreshStates(lastPoll) {
return this.genericGet(constants.API_URL_REFRESH_STATES + '?last=' + lastPoll);
}
executeDeviceAction(ID, action, param) {
const body = param !== null ? {
'args': param,
} : {};
return this.genericPost(constants.API_URL_DEVICES + '/' + ID + '/action/' + action, body);
}
executeScene(ID, useOldApi) {
const body = {};
return this.genericPost(constants.API_URL_SCENES + '/' + ID + (useOldApi ? '/action/start' : '/execute'), body);
}
getGlobalVariable(globalVariableID) {
return this.genericGet(constants.API_URL_GLOBAL_VARIABLES + '/' + globalVariableID);
}
setGlobalVariable(globalVariableID, value) {
const body = value !== null ? {
'value': value,
'invokeScenes': true,
} : null;
return this.genericAdminPut(constants.API_URL_GLOBAL_VARIABLES + '/' + globalVariableID, body);
}
}
exports.FibaroClient = FibaroClient;
//# sourceMappingURL=fibaro-api.js.map