Open pipje2001 opened 4 years ago
Hi Pipje, looking into this now. I think the issue is related to removing the async, which leads to a race condition whereas the DTLS socket trys to connect before {"stream": "active"}. But additionally, it may be the way that the library is interacting with your server library threading/context.
I like the idea of hiding the library behind an HTTP API. It is a nice way to main a home server. What web framework are using (ExpressJS?). In your case, is the bridge being created on a global or local context? You'll need the async's for now, and potentially need to keep the bridge object in the global context. If you can provide a larger gist, I may be able to point you in the correct direction.
Regarding async, I'm trying to reconcile with myself if this is a JS anti-pattern. Give me sometime tow/ think about this, but startup procedure code wise needs to be sequential (eventually safety can be built in):
Another fun idea with this one: I wonder if this library can somehow be interfaced through WASM and imported directly into Python. I'd love this as a (usually) Python first dev. In fact, the reason this library is written in Node is that Node's cross-platform support for DTLS sockets was better at the time. I'm not sure if python has improved in this area.
I like the idea of hiding the library behind an HTTP API. It is a nice way to main a home server. What web framework are using (ExpressJS?). In your case, is the bridge being created on a global or local context? You'll need the async's for now, and potentially need to keep the bridge object in the global context. If you can provide a larger gist, I may be able to point you in the correct direction.
I am indeed using ExpressJS, the bridge is created as a global context otherwise the next time you send a request to the api it will not know what the bridge is. What do you mean with a larger gist?
Another fun idea with this one: I wonder if this library can somehow be interfaced through WASM and imported directly into Python. I'd love this as a (usually) Python first dev. In fact, the reason this library is written in Node is that Node's cross-platform support for DTLS sockets was better at the time. I'm not sure if python has improved in this area.
Nope python has not improved in this erea, the whole reason i am doing this with a nodeAPI is because python doesn't support this type of dtls connection
Hey pipje, I just updated the library. #7 was a similar bug to yours and I was able to pinpoint a bug causing lights not to change when their IDs were not sequential starting at "1". Give it a try and let me know if it resolves your issue.
Just made issue #8 to add functionality somehow (this library or child library) for an HTTP server version of this.
Hey pipje, I just updated the library. #7 was a similar bug to yours and I was able to pinpoint a bug causing lights not to change when their IDs were not sequential starting at "1". Give it a try and let me know if it resolves your issue.
Yep it fixed it so far!
Just made issue #8 to add functionality somehow (this library or child library) for an HTTP server version of this.
I will help with this if i have the time, but it should be to difficult
Alright i tested the basicExample which worked but when i try to do it via a http request from python the server trows this error:
(node:14372) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'transitionColor' of undefined
at PheaEngine.<anonymous> (b:\NAS CloudStation\PC\Prive\visual_studio_code\GitHub\WOT-Huenify\Hue Entertainment API\nodeAPI\node_modules\phea\build\phea-engine.js:58:50)
at Generator.next (<anonymous>)
at b:\NAS CloudStation\PC\Prive\visual_studio_code\GitHub\WOT-Huenify\Hue Entertainment API\nodeAPI\node_modules\phea\build\phea-engine.js:8:71
at new Promise (<anonymous>)
at __awaiter (b:\NAS CloudStation\PC\Prive\visual_studio_code\GitHub\WOT-Huenify\Hue Entertainment API\nodeAPI\node_modules\phea\build\phea-engine.js:4:12)
at PheaEngine.transition (b:\NAS CloudStation\PC\Prive\visual_studio_code\GitHub\WOT-Huenify\Hue Entertainment API\nodeAPI\node_modules\phea\build\phea-engine.js:51:16)
at lightId.forEach (b:\NAS CloudStation\PC\Prive\visual_studio_code\GitHub\WOT-Huenify\Hue Entertainment API\nodeAPI\node_modules\phea\build\hue-bridge.js:87:37)
at Array.forEach (<anonymous>)
at HueBridge.<anonymous> (b:\NAS CloudStation\PC\Prive\visual_studio_code\GitHub\WOT-Huenify\Hue Entertainment API\nodeAPI\node_modules\phea\build\hue-bridge.js:79:21)
at Generator.next (<anonymous>)
(node:14372) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function
without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:14372) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I connect to the bridge with this function, which works fine i think:
// Connect to the bridge
router.post('/connect', async (req, res) => {
try {
const { hubIP, userName, psk } = req.body;
let options = {
address: hubIP,
username: userName,
psk: psk
};
console.log(`Connecting with bridge on ${hubIP}`);
bridge = await Phea.bridge(options);
console.log('Connected');
res.send('Connected');
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}a
i start the stream with:
router.get('/start', async (req, res) => {
try {
const { groupID } = req.body;
await bridge.start(groupID);
running = true;
console.log('Started');
res.send('Started');
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
and send a stream like this:
router.post('/stream', async (req, res) => {
try {
const { lightID = 0, RGB, transitionTime = 1000 } = req.body;
console.log(lightID, RGB, transitionTime);
bridge.transition(lightID, RGB, transitionTime);
console.log('Streamed');
res.send('Streamed');
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
somehow this doesn't work and the example does....
ACK. I'll see if I can get this working when I have a moment. I need to play with Express to get a feel for the namespacing. The code looks fine, so I imagine that the application context is getting misplaced or that theres a race. Here is where the error is originating from:
constructor(id, options) {
this.id = id;
this.opts = options;
this.rgb = [0, 0, 0];
this.gen = null;
this.transitionColor([0, 0, 0], 0);
}
transitionColor(rgb, tweenTime) {
this.gen = this.setTransition(rgb, tweenTime);
}
...```
So it sounds like the constructor is calls this.transitionColor just fine, but the secondary call during the stream exchange, the lights are undefined. I'd have to look, but as long as the stream is active from bridge.start(groupId), lights should be defined. Hmm if its not a context issue, I wonder if the bridge closes at some point. Two action items from this as well for enhancing the libraries debugging:
1) Create a configState message on bridge to dump a dictionary of bridge state and configuration.
2) If socket is not open, retry to open or throw.
I'll let you know when I am able to test this out.
Just to be clear, it isn't nessecary to keep sending new messages to phea right?
Yeah. PheaEngine schedules an interval to send a message every (1000/dtlsUpdatesPerSecond) milliseconds. Does express.js have any known issues with setInterval()? Nothing immediately shows up through my searching, but something keeps itching at me that we're dealing with a closed socket.
I have no idea, i am not that experianced with express or js at all actually
So i found the problem, i was sending a lightID of 5 which should be a light in the stream group, but there are only 2 lights in the group and it matched those lights to an id of 1 and 2, is this supposed to happen?
This is awesome! finnaly after like half a year trying i can finnaly stream from a game for which i am making a mod. Thanks mate without this library and your help i would not have been able to do this.
I do get these errors an awfull lot of times which breaks the nodeAPI:
throw err;
^
Error: Error: The DTLS handshake timed out
No problem! Glad to see people get this library in action.
So regarding your light ID issue, were you able to get that worked out? Looking at the code, there's not a clear explanation for why this should be happening (assuming your using the latest build). The process is for building light id's is parsing the IDs from the bridge. The routine is:
The IDs used for these groups should come directly from the bridge. Not sure why they aren't matching.
For the DTLS timeout error occurs, I am familiar. I think there is an action item to currently rebuild the socket creation to attempt retrys and establish. Currently the creation is suffers from racing, which explains a bit of the behavior. Definitely a todo here.
For the DTLS timeout errors, are you seeing them on bridge.start() or does this error occur well into runtime. I think that error is coming from the DTLS library I'm using.
Hello Jake, thanks for the API :) I am your biggest fan
Hello and thanks a lot for your work !
I'm having the same DTLS handshake issue. Basically if my server is restarted i need to wait some time before the Bridge actually closes the connection and allows a new one to be opened (or at least that's my undesrtanding of it) The problem is that this package throws exceptions asynchronously which makes them uncatchable which stops the server's execution.
I made a fork that gets rid of those uncatchable errors if you wish : https://github.com/Durss/node-phea
I haven't tested it properly yet but i'll make a pull request later if you wish !
Hey guys! :) Thanks for this lib, it is really great so far! I have the same issue like @pipje2001 with the transition Method. I'm using Typescript, and the documentation/definition doesn't fit (or maybe I don't understand it correctly).
Here you say you need a string or number (0 to change all): https://github.com/JakeBednard/node-phea/blob/master/src/phea-engine.ts#L70
But here you need an array of string or number: https://github.com/JakeBednard/node-phea/blob/master/build/hue-bridge.d.ts#L11
If I just ignore it and send 0, it works :)
Thanks again!
I am trying to get this module to work in a nodeAPI, so i can use the hue entertainment api in python via this api of mine, now i am kinda running into a lot of problems, mainly that the lights don't change color or do anything at all:
i have this connect function:
which works fine, i removed the let before the bridge = await Phea.bridge(options);, so it can be used in different fucntions
i got a start and a stop function, stop just runs brige.stop and stops the loop which is running in basicExample (your example):
so bassically it does nothing whith the lights at all, it does change the stream to active, but doesn't change any lights.