Closed n0rt0nthec4t closed 4 years ago
Very simple,
setTimeout(function () { console.log('timeout completed'); udpSocket.close(); return foundDevices; }, 5000);
Wont the still mean the doDiscovery function will exit before the timeout is completed? So if you do a test after var devices = doDisovery() to see if teh array contains any data, it'll be null?
Sorry, wasn't paying attention to the question. With javascript you need to use callbacks, which if your not familiar with is a steep learning curve.
function doDisovery(callback) {
var foundDevices = [];
var updQuery = "DAIKIN_UDP/common/basic_info";
var udpSocket = dgram.createSocket({type:"udp4", reuseAddr:true});
udpSocket.bind(30000, "0.0.0.0", function () {
udpSocket.addMembership('224.0.0.1');
udpSocket.setBroadcast(true);
});
udpSocket.on('message', function (chunk, info) {
// Callback triggered when we've received a UDP response
if (foundDevices.indexOf(info.address) == -1) {
//doSomeProcessing
foundDevices.push(info.address);
}
});
udpSocket.on('listening', function() {
// UDP socket opened fro listen, so send the queries
udpSocket.send(updQuery, 0, updQuery.length, 30050, "255.255.255.255");
});
udpSocket.on('close', function() {
console.log("closed");
});
// Need to wait some time to allow the on(message) event to process before proceeding to exit this function
setTimeout(function () {
console.log('timeout completed');
udpSocket.close();
callback(foundDevices);
}, 5000);
}
doDisovery(function(devices) {
console.log('your devices', devices);
});
Hrrmm.. This issue is still, that the code sequencing is wrong, so the HAP-NodeJS accessory loader exits before get the chance to create the accessories. doDiscovery callback gets called after the _accfactory.js code has exited full code below, so HPA-NodeJS doesn't know about them.
function doDiscovery(callback) { var foundDevices = []; var updQuery = "DAIKIN_UDP/common/basic_info"; var udpSocket = dgram.createSocket({type:"udp4", reuseAddr:true});
udpSocket.bind(30000, "0.0.0.0", function () {
udpSocket.addMembership('224.0.0.1');
udpSocket.setBroadcast(true);
});
udpSocket.on('message', function (chunk, info) {
// Callback triggered when we've received a UDP response
// Callback triggered when we've received a UDP response
var daikinACInfo = JSON.parse(convertDaikinToJSON(chunk.toString('utf8')));
if (foundDevices.indexOf(info.address) == -1) {
// Have not found this Daikin before, so add to array of discovered systems
foundDevices.push({IPaddress: info.address, MACaddress: daikinACInfo.mac.substr(0,2) + ":" + daikinACInfo.mac.substr(2,2) + ":" + daikinACInfo.mac.substr(4,2) + ":" + daikinACInfo.mac.substr(6,2) + ":" + daikinACInfo.mac.substr(8,2) + ":" + daikinACInfo.mac.substr(10,2), name: hex2ascii(daikinACInfo.name), version: daikinACInfo.ver.replace(/_/g, ".")});
}
});
udpSocket.on('listening', function() {
// UDP socket opened to listen, so send the queries
udpSocket.send(updQuery, 0, updQuery.length, 30050, "255.255.255.255");
});
setTimeout(function () {
udpSocket.close();
callback(foundDevices);
}, 5000);
}
doDiscovery(function(devices) { var daikinACs = []; if (devices.length > 0) { for (var index in devices) {
// Create the main airconditioner accessory and associated accessories
daikinACs[index] = new AirconditionerClass();
daikinACs[index].__accessory = exports.accessory = new Accessory(AccessoryName, uuid.generate("hap-nodejs:accessories:daikin_"+devices[index].name));
daikinACs[index].__accessory.username = devices[index].MACaddress;
daikinACs[index].__accessory.pincode = AccessoryPincode;
daikinACs[index].__accessory.category = Accessory.Categories.AIR_CONDITIONER; // Air-conditioner type accessory
daikinACs[index].__accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Manufacturer, "Daikin");
daikinACs[index].__accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.Model, "Some Model");
daikinACs[index].__accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.SerialNumber, "Some Serial");
daikinACs[index].__accessory.getService(Service.AccessoryInformation).setCharacteristic(Characteristic.FirmwareRevision, devices[index].version);
daikinACs[index].__airconIP = devices[index].IPaddress;
daikinACs[index].addAirconditioner(daikinACs[index].__accessory, devices[index].name, 1);
daikinACs[index].addDehumidifier(devices[index].name, 1);
daikinACs[index].addFan(devices[index].name, 1);
daikinACs[index].addOutsideTempSensor(devices[index].name, 1);
// Do update of current air-con system status for HomeKit, before setting refresh schedule
daikinACs[index].__DaikinStatus();
daikinACs[index].refreshHomeKit(2000);
accessories.push(daikinACs[index].__accessory); // Push onto export array for HAP-NodeJS "accessory factory"
}
}
});
Sorry can't help with that, I code my devices with the homebridge API
Anyone have any further ideas how to achieve this?
... so the HAP-NodeJS accessory loader exits before get the chance to create the accessories ...
I assume you are using the Core.ts/BridgedCore.ts and placing your file into the accessories folder? You could also create your program by using hap-nodejs as a dependency and publishing your accessories on your own/by hand. So there is no AccessoryLoader or something waiting for your response.
... so the HAP-NodeJS accessory loader exits before get the chance to create the accessories ...
I assume you are using the Core.ts/BridgedCore.ts and placing your file into the accessories folder?
Yep, thats correct.. Its also running multiple accessories.. Was trying to avoid hard-coding device IPs into the source, hence doing auto-discovery sigh
I have done this in homebridge, using dynamic plugins
https://github.com/NorthernMan54/homebridge-mculed
Device discovery using mdns etc
Thanks, dont want to switch the a home bridge code base. Might have to see there is another way to modify the accessory loader code to perhaps allow and init function in the _accessory.js code its loading.
Homebridge is just a wrapper around hap-nodejs, so it is feasible. Might be a place to start
It seems the coding is different though, and I dont want a bridge to host the accessories
... so the HAP-NodeJS accessory loader exits before get the chance to create the accessories ...
I assume you are using the Core.ts/BridgedCore.ts and placing your file into the accessories folder?
Yep, thats correct.. Its also running multiple accessories.. Was trying to avoid hard-coding device IPs into the source, hence doing auto-discovery sigh
Yes simply restructure you project to include hap-nodejs as dependency and publish accessories at any time. Here is a basic example how it looks like, though not the best or most detailed one (just picked some random plugin). Compare that with the source of Core.js and pick the lines you need.
This issue has been automatically marked as stale because it has not had recent activity, and will be closed if no further activity occurs. If this issue was overlooked, forgotten, or should remain open for any other reason, please reply here to call attention to it and remove the stale status. Thank you for your contributions.
Not technically a HAP-NodeSJ issue, but I'm trying to make my accessories bit smart by doing auto discovery of devices on the network. I have a function, doDiscovery which does UDP scans and then depending on results, builds list of devices that response. Code Below:
My issue is, I need where commented // Need to wait some time to allow the on(message) event to process before proceeding to exit this function
So the function needs to wait say, 3-5seconds before it exist with a return
function doDisovery() { var foundDevices = []; var updQuery = "DAIKIN_UDP/common/basic_info"; var udpSocket = dgram.createSocket({type:"udp4", reuseAddr:true});
}
var devices = doDisovery();