Closed teymur1988 closed 4 years ago
Hi @Supereg Could you please help with this? I think my problem is related to the server response, because it responds "on" or "off" and this plugin doesn't understand that. I've tried using : { "accessory": "HTTP-SWITCH", "name": "L-Test", "switchType": "stateful", "onUrl": "http://10.10.10.54/on", "offUrl": "http://10.10.10.54/off", "statusUrl": "http://10.10.10.54/state", "statusPattern": "on" } But no joy.
Is it still the issue with "Invalid header token". It seems that your http server returns some http headers which are not standardized. What I found out ready this: https://stackoverflow.com/questions/36628420/nodejs-request-hpe-invalid-header-token
Hi Thanks for your reply! Yes it is invalid header token issue. This is what the device responds when statusUrl is sent to it. Is there anything wrong with this? Couldn't paste the html code here. Attached a file. status.txt
This is what the device responds when statusUrl is sent to it. Is there anything wrong with this?
Nothing wrong with that (that's also just the http body).
The problem is the http header the server seems to return. Http headers are some special options which the browser can interpret. And the parsing of those headers seems to have become more strict in nodes v12.
Is there anything I can do to get this fixed?
Could you quickly confirm what version of node you are running, something like >= v12?
Sure:
C:\Users\teymu>node -v v12.13.0
C:\Users\teymu>
If that's true you could just add the following node command line argument --http-parser=legacy
when you startup your homebridge instance. This will revert the parsing to the old way.
You're probably better in this than I am. I'm running Homebridge on windows as you see. And I used nssm to create a service. Below is the argument from nssm. Where do I exactly paste --http-parser=legacy ??? I tried pasting it in cmd like homebridge -I --http-parser=legacy but it won't take it. Probably not right way of doing it
C:\Users\teymu\AppData\Roaming\npm\node_modules\homebridge-config-ui-x\dist\bin\hb-service.js run -I -U C:\Users\teymu.homebridge
Oh yeah, I forgot, that homebridge brings its own executable (the argument would need to be passed to the node
executable).
Maybe I could add some property to the config file which tries to change the http parsing programmatically. Currently no time for that, but will come back to it.
Thanks, will be waiting for that!
Okay so the thing is, I could programmatically change the http parsing to the legacy one. However not in node v12 😅
So the best solution would be that you investigate where exactly homebridge is started (I don't know how nssm handles service definitions). The thing is that you are running homebridge-config-ui-x (?) and that it handles the startup of homebridge as far as I could identify. Some around this line you would probably somehow explicitly call node and pass the --http-parser=legacy
option the the node process.
You have no chance of changing the http headers of your http server I guess?
Maybe you could reach out to somebody at homebridge-config-ui-x and ask how to pass command line options to the node process.
As time of writing there could also be another solution to the problem. You could pass the http-parser option via the environment variable NODE_OPTIONS. Check some tutorial for windows and set the variable NODE_OPTIONS
to --http-parser=legacy
Hello @Supereg Sorry been away for a while, couldn't get onto the web. Thanks very much for your reply. I erased that firmware from the device that was sending invalid header token. My new "problem" has still to do with getting the device status, now it's sending the correct headers, plus bunch of other info as well. I'll give an example down below. Could you please explain if it is possible at all to use the "StatusPattern" to parse this, and take the highlighted line value. I've looked at the regex, but found it rather difficult to implement.
So requesting status url looks like this: "http://device_ip:port/get_status.cgi?user=admin&pwd=password"
Response from the server is:
var alarm_mail=0; var alarm_audio=0; var alarm_temperture=0; var alarm_iolinkage=0; var alarm_ioout_level=0; var alarm_upload_interval=0; var alarm_presetsit=0; var alarm_snapshot=1; var alarm_record=0; var alarm_schedule_enable=0; var alarm_http=1; var alarm_http_url="url.com/trigger"; var alarm_schedule_sun_0=0; var alarm_schedule_sun_1=0; var alarm_schedule_sun_2=0; var alarm_schedule_mon_0=0; var alarm_schedule_mon_1=0; var alarm_schedule_mon_2=0; var alarm_schedule_tue_0=0; var alarm_schedule_tue_1=0; var alarm_schedule_tue_2=0; var alarm_schedule_wed_0=0; var alarm_schedule_wed_1=0; var alarm_schedule_wed_2=0; var alarm_schedule_thu_0=0; var alarm_schedule_thu_1=0; var alarm_schedule_thu_2=0; var alarm_schedule_fri_0=0; var alarm_schedule_fri_1=0; var alarm_schedule_fri_2=0; var alarm_schedule_sat_0=0; var alarm_schedule_sat_1=0; var alarm_schedule_sat_2=0; var alarm_note=1; var alarm_server=""; var alarm_user=""; var alarm_pwd=""; var alarm_port=0;
A value of "statusPattern"="var alarm_audio=0;"
should work (or "statusPattern"="var alarm_audio=1;"
, whatever you want it to be considered as 'on').
Regular expressions is pretty powerful when you want to match certain patterns. However in your case you can just use it without any special patterns and it is somewhat of a check if the given string is contained in the http request.
Hi @Supereg ,
Thanks for your reply!
I've tried the above solution before opening this discussion again, however the only difference I had was: "statusPattern": "var alarm_audio=1;",
and it seemed to me that it didn't work. I've read all the wiki here, and of coursein my case this is pretty simple. Maybe sometime is needed to get the switch status updated. I'll play with the pullinterval.
Could maybe post the relevant parts of your homebridge config for this plugin? So I can verify the property is placed at the right spot. Additionally enable the debug option in the plugin config. This will print all configured settings at startup and also what happens when comparing the pattern. This could help troubleshoot
Hey I think I did manage to get it working! Thank you. I just set the pullInterval to 1 second, so for that to be more or less realtime. The reason is that the option I'm after isn't only controlled via homekit but from the device's app and I'm not the only one controlling it (there are some android guys as well). Here's the config part.
{ "accessory": "HTTP-SWITCH", "name": "Switch", "switchType": "stateful", "onUrl": "http://ip:port/set_alarm.cgi?user=admin&pwd=password&audio=1", "offUrl": "http://ip:port/set_alarm.cgi?user=admin&pwd=password&audio=0", "statusUrl": "http://ip:port/get_params.cgi?user=admin&pwd=password", "statusPattern": "var alarm_audio=1;", "pullInterval": 1000, "debug": true }
I want to thank you again for this cool plugin and for the quick help!
Describe the bug Can't get a stateful switch to work. The logs report invalid header token. I have a relay which works with REST APIs. simply by sending a get request like: http:/IP/on http:/IP/off http:/IP/state http:/IP/toggle
Everyting works if doing from a browser or a command line. It also works if I use a stateless switch. But I need a stateful.
Version (output of
npm list -g homebridge homebridge-http-switch
)Configuration