mirror of
https://github.com/parnic/MMM-IntelliCenter.git
synced 2025-06-16 21:21:53 -05:00
Initial commit, WIP
This gets the module far enough along that it can use the library, find and connect to a unit, and issue requests to it. This is a copy/paste of the ScreenLogic version, so I expect a lot of changes/renames will need to happen still.
This commit is contained in:
283
node_helper.js
Normal file
283
node_helper.js
Normal file
@ -0,0 +1,283 @@
|
||||
/* global module require clearInterval clearTimeout setTimeout setInterval config */
|
||||
|
||||
var NodeHelper = require("node_helper");
|
||||
|
||||
let FindUnits;
|
||||
let Unit;
|
||||
import("node-intellicenter").then((x) => {
|
||||
FindUnits = x.FindUnits;
|
||||
Unit = x.Unit;
|
||||
});
|
||||
let messages;
|
||||
import("node-intellicenter/messages").then((x) => {
|
||||
messages = x.messages;
|
||||
});
|
||||
const Log = require("logger");
|
||||
|
||||
const reconnectDelayMs = 10 * 1000;
|
||||
const unitFinderTimeoutMs = 5 * 1000;
|
||||
let foundUnit = false;
|
||||
const poolData = {};
|
||||
let refreshTimer;
|
||||
let unitFinderRetry;
|
||||
let unitReconnectTimer;
|
||||
|
||||
module.exports = NodeHelper.create({
|
||||
setCircuit(circuitState) {
|
||||
this.setCircuitState(circuitState, (poolStatus) => {
|
||||
this.sendSocketNotification("INTELLICENTER_CIRCUIT_DONE", {
|
||||
circuitState,
|
||||
status: poolStatus
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
setHeatpoint(heatpoint) {
|
||||
this.setHeatpointState(heatpoint, (poolStatus) => {
|
||||
this.sendSocketNotification("INTELLICENTER_HEATPOINT_DONE", {
|
||||
heatpoint,
|
||||
status: poolStatus
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
setHeatstate(heatstate) {
|
||||
this.setHeatstateState(heatstate, (poolStatus) => {
|
||||
this.sendSocketNotification("INTELLICENTER_HEATSTATE_DONE", {
|
||||
heatstate,
|
||||
status: poolStatus
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
setLightcmd(lightCmd) {
|
||||
this.setLights(lightCmd, (poolStatus) => {
|
||||
this.sendSocketNotification("INTELLICENTER_LIGHTCMD_DONE", {
|
||||
lightCmd,
|
||||
status: poolStatus
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
notifyReconnecting() {
|
||||
this.sendSocketNotification("INTELLICENTER_RECONNECTING");
|
||||
},
|
||||
|
||||
socketNotificationReceived(notification, payload) {
|
||||
if (notification === "INTELLICENTER_CONFIG") {
|
||||
if (!this.config) {
|
||||
this.config = payload;
|
||||
this.connect(
|
||||
(status) => {
|
||||
this.sendSocketNotification("INTELLICENTER_RESULT", status);
|
||||
},
|
||||
() => {
|
||||
this.notifyReconnecting();
|
||||
}
|
||||
);
|
||||
} else if (poolData.status) {
|
||||
this.sendSocketNotification("INTELLICENTER_RESULT", poolData);
|
||||
}
|
||||
// If we don't have a status yet, assume the initial connection is still in progress and this socket notification will be delivered when setup is done
|
||||
}
|
||||
if (notification === "INTELLICENTER_CIRCUIT") {
|
||||
this.setCircuit(payload);
|
||||
}
|
||||
if (notification === "INTELLICENTER_HEATPOINT") {
|
||||
this.setHeatpoint(payload);
|
||||
}
|
||||
if (notification === "INTELLICENTER_HEATSTATE") {
|
||||
this.setHeatstate(payload);
|
||||
}
|
||||
if (notification === "INTELLICENTER_LIGHTCMD") {
|
||||
this.setLightcmd(payload);
|
||||
}
|
||||
},
|
||||
|
||||
resetFoundUnit() {
|
||||
foundUnit = null;
|
||||
if (refreshTimer) {
|
||||
clearInterval(refreshTimer);
|
||||
refreshTimer = null;
|
||||
}
|
||||
if (unitFinderRetry) {
|
||||
clearInterval(unitFinderRetry);
|
||||
unitFinderRetry = null;
|
||||
}
|
||||
if (unitReconnectTimer) {
|
||||
clearTimeout(unitReconnectTimer);
|
||||
unitReconnectTimer = null;
|
||||
}
|
||||
},
|
||||
|
||||
setupUnit(cb, reconnectCb) {
|
||||
Log.info("[MMM-IntelliCenter] initial connection to unit...");
|
||||
|
||||
foundUnit
|
||||
.on("error", (e) => {
|
||||
Log.error(
|
||||
`[MMM-IntelliCenter] error in unit connection. restarting the connection process in ${reconnectDelayMs / 1000} seconds`
|
||||
);
|
||||
Log.error(e);
|
||||
|
||||
reconnectCb();
|
||||
this.resetFoundUnit();
|
||||
unitReconnectTimer = setTimeout(() => {
|
||||
this.connect(cb, reconnectCb);
|
||||
}, reconnectDelayMs);
|
||||
})
|
||||
.on("close", () => {
|
||||
Log.error(
|
||||
`[MMM-IntelliCenter] unit connection closed unexpectedly. restarting the connection process in ${reconnectDelayMs / 1000} seconds`
|
||||
);
|
||||
|
||||
reconnectCb();
|
||||
this.resetFoundUnit();
|
||||
unitReconnectTimer = setTimeout(() => {
|
||||
this.connect(cb, reconnectCb);
|
||||
}, reconnectDelayMs);
|
||||
})
|
||||
.once("connected", () => {
|
||||
Log.info(
|
||||
"[MMM-IntelliCenter] logged into unit. getting basic configuration..."
|
||||
);
|
||||
foundUnit.send(new messages.GetSystemInformation()).then(() => {
|
||||
Log.info("[MMM-IntelliCenter] got it!");
|
||||
});
|
||||
})
|
||||
.once("controllerConfig", (config) => {
|
||||
Log.info(
|
||||
"[MMM-IntelliCenter] configuration received. adding client..."
|
||||
);
|
||||
poolData.controllerConfig = config;
|
||||
poolData.degStr = this.config.degC ? "C" : "F";
|
||||
foundUnit.addClient(1234);
|
||||
})
|
||||
.once("addClient", () => {
|
||||
Log.info(
|
||||
"[MMM-IntelliCenter] client added successfully and listening for changes"
|
||||
);
|
||||
foundUnit.getPoolStatus();
|
||||
// Connection seems to time out every 10 minutes without some sort of request made
|
||||
refreshTimer = setInterval(
|
||||
() => {
|
||||
foundUnit.pingServer();
|
||||
},
|
||||
1 * 60 * 1000
|
||||
);
|
||||
})
|
||||
.on("poolStatus", (status) => {
|
||||
Log.info("[MMM-IntelliCenter] received pool status update");
|
||||
poolData.status = status;
|
||||
cb(poolData);
|
||||
});
|
||||
|
||||
foundUnit.connect();
|
||||
},
|
||||
|
||||
findServer(cb, reconnectCb) {
|
||||
Log.info("[MMM-IntelliCenter] starting search for local units");
|
||||
const finder = new FindUnits(this.config.multicastInterface);
|
||||
finder
|
||||
.on("serverFound", (server) => {
|
||||
finder.close();
|
||||
Log.info(
|
||||
`[MMM-IntelliCenter] local unit found at ${server.addressStr}:${server.port}`
|
||||
);
|
||||
|
||||
foundUnit = new Unit(server.addressStr, server.port);
|
||||
this.setupUnit(cb, reconnectCb);
|
||||
|
||||
clearInterval(unitFinderRetry);
|
||||
unitFinderRetry = null;
|
||||
})
|
||||
.on("error", (e) => {
|
||||
Log.error(
|
||||
`[MMM-IntelliCenter] error trying to find a server. scheduling a retry in ${reconnectDelayMs / 1000} seconds`
|
||||
);
|
||||
Log.error(e);
|
||||
this.resetFoundUnit();
|
||||
setTimeout(() => {
|
||||
this.findServer(cb);
|
||||
}, reconnectDelayMs);
|
||||
});
|
||||
|
||||
finder.search();
|
||||
unitFinderRetry = setInterval(() => {
|
||||
Log.info(
|
||||
`[MMM-IntelliCenter] didn't find any units within ${unitFinderTimeoutMs / 1000} seconds, trying again...`
|
||||
);
|
||||
finder.search();
|
||||
}, unitFinderTimeoutMs);
|
||||
},
|
||||
|
||||
connect(cb, reconnectCb) {
|
||||
if (
|
||||
!foundUnit &&
|
||||
typeof config !== "undefined" &&
|
||||
this.config.serverAddress &&
|
||||
this.config.serverPort
|
||||
) {
|
||||
Log.info(
|
||||
`[MMM-IntelliCenter] connecting directly to configured unit at ${this.config.serverAddress}:${this.config.serverPort}`
|
||||
);
|
||||
foundUnit = new Unit(this.config.serverAddress, this.config.serverPort);
|
||||
}
|
||||
|
||||
if (foundUnit) {
|
||||
this.setupUnit(cb, reconnectCb);
|
||||
} else {
|
||||
this.findServer(cb, reconnectCb);
|
||||
}
|
||||
},
|
||||
|
||||
setCircuitState(circuitState, cb) {
|
||||
if (!foundUnit) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.info(
|
||||
`[MMM-IntelliCenter] setting circuit ${circuitState.id} to ${circuitState.state}`
|
||||
);
|
||||
foundUnit.setCircuitState(0, circuitState.id, circuitState.state);
|
||||
foundUnit.getPoolStatus();
|
||||
},
|
||||
|
||||
setHeatpointState(heatpoint, cb) {
|
||||
if (!foundUnit) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.info(
|
||||
`[MMM-IntelliCenter] setting heatpoint for body ${heatpoint.body} to ${heatpoint.temperature} deg`
|
||||
);
|
||||
foundUnit.setSetPoint(0, heatpoint.body, heatpoint.temperature);
|
||||
foundUnit.getPoolStatus();
|
||||
},
|
||||
|
||||
setHeatstateState(heatstate, cb) {
|
||||
if (!foundUnit) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.info(
|
||||
`[MMM-IntelliCenter] setting heat state for body ${heatstate.body} to ${heatstate.state}`
|
||||
);
|
||||
foundUnit.setHeatMode(0, heatstate.body, heatstate.state);
|
||||
foundUnit.getPoolStatus();
|
||||
},
|
||||
|
||||
setLights(lightCmd, cb) {
|
||||
if (!foundUnit) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.info(`[MMM-IntelliCenter] sending light command ${lightCmd}`);
|
||||
foundUnit.sendLightCommand(0, lightCmd);
|
||||
foundUnit.getPoolStatus();
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user