HTTP Request "Error: socket hang up"

#1

Hi,

Short version of the problem:
I am sending a URL to an http request node to control my air conditioning, but node red returns, "Error: socket hang up". I know the URL is valid, because when pasted into a browser, it works (e.g. aircon powers on) and returns a valid json message with acknowledgement. Furthermore, the request does successfully execute the command from node red (e.g. aircon powers on), but node red returns the hang up error.

Longer version of the problem, with more detail, at the end of this post.

What I have discovered so far
I researched as far as I can, and found a discussion on stackoverflow, indicating that the hang up error occurs when a 'connection end event' is not sent to end the request, or if there is no timely response from the server.

Here's the link to the discussion: https://stackoverflow.com/questions/16995184/nodejs-what-does-socket-hang-up-actually-mean

What can I do?
I don't know what to do from here; it appears that either:

  1. node red is not sending a connection end event

or

  1. node red does not receive a timely response

Can anyone advise how I can proceed?

Long version of the problem:
I have created a flow for controlling my air conditioning which is connected my home network (via WiFi), and accepts json commands. (I learnt the commands by proxying my iphone to my PC using Fiddler).

If I paste one of the aircon commands into my web browser, the command is executed successfully (e.g. aircon turns on), and an acknowledgement is returned to the browser, for example:

When pasted into a browser window, this:
http://192.168.99.99:2025/setAircon?json={"ac1":{"info":{"state":"on","countDownToOn":"0","countDownToOff":"0"}}}

Returns this...
{"request":"setAircon","ack":true}

However, if I paste exactly the same URL into an http request node, the command executes on the aircon, but the following error is displayed as an error by the http request node:
Error: socket hang up

0 Likes

#2

Sounds like an url encoding issue. Can you post your flow (for the get request part) ?
Are you using the http request node with a url filled in url are you using msg.url ?

The http request node accepts mustache style formatting, which could fail on urls containing { } as it tries to parse it. I have never seen json as url parameter, is this something that can be changed ?

0 Likes

#3

Thank you for your response (and my apologies for not responding sooner).

I have certainly learnt something from your post, thank you... I wasn't aware of the mustache formatting in the http request node, but I am now!

I have created a basic test 'rig', using typicode.com to pass information into a query string using mustache formatting. It's a simple:

Inject > change [set msg.query] > http request

This works fine.

However, as you have suggested, I think the problem is that the json style required for my aircon query is causing problems because of the {} delimiters. I would have thought that there is some way to escape the {}, but I cannot find a way of doing it in node-red.

Unfortunately, I have no choice about the json formatting; it's the way the aircon works, and I have no control over the formatting for the query.

If someone can advise on escaping the characters in node-red, I'd be grateful.

0 Likes

#4

Curly braces are considered insecure in an url and not according to the RFC standard.

You can replace { with %7B and } with %7D

0 Likes

#5

Thank you for your prompt response.

I have already tried encoding as you have suggested, but with the same result.

I suppose air conditioning suppliers aren't particularly interested in security! I suppose they are assuming that security is not an issue because it runs on a private network, or they are just ignorant.

I wonder if the {} are a red herring; I get the socket hang-up regardless of whether they are encoded or not. I am 100% certain that I have got the URL formatting correct; if I copy the 'failing' URL from node red and paste into a web browser, I get an ack in a json response from the air conditioning controller.

I am not knowledgeable enough to diagnose any further, to determine what is causing the lack of response / not sending a connection end event.

I do appreciate your input. Thank you.

0 Likes

#6

there may be some extra headers your browser is setting that the far end expects... (as you are sending json like payload). Other thing to try is to try it with a curl command
eg curl http://192.168.99.99:2025/setAircon?json={"ac1":{"info":{"state":"on","countDownToOn":"0","countDownToOff":"0"}}} which should be fairly unadorned and see if that works.
Is there a manual for the AC unit that details the interface at all ?

0 Likes

#7

Thanks for the suggestion about headers; yes that's definitely something to examine.

curl doesn't like the exact command that you suggested ( [globbing] nested brace in column 53), however, your suggestion has pointed me in the right direction, thank you.

I'm planning on going back to my original network sniffing exercise (which is how I discovered the json packages), so I can examine those headers. The aircon app for iphone sends the json request out raw, so I should be able to get the headers (I'm no expert, but hopefully I can figure it out).

I was thinking that, ultimately, if all else fails in Node Red, I can make the json calls in Python (just because I am familiar with Python), and then I can call the Python script from Node Red and get the results back too; the airon unit sends useful results back in json).

Unfortunately, the aircon manual does not include anything useful (other than typical user controls!); supplier is not interested in providing information; they make money from selling home automation systems, so they wouldn't want me implementing my own Siri & Google compatible home automation system for the price of a Raspberry Pi!

Incidentally, node red is switching the aircon on and off successfully as mentioned in my original post; it's just that I can't get the ack back because of the socket hangup issue. I can trap the error with a node red catch, but I'd like to keep it nice and tidy and feed that results from the aircon back into the flow.

It's very satisfying to ask Google to turn off the aircon, and then to see the fan icon spinning down on the iOS Home app!

I won't have a chance to do anything with this until the weekend, but thanks for your help.

1 Like

#8

Try this:
curl -H 'Content-Type: application/json' -H 'Accept: application/json' -X PUT -d '{"ac1":{"info":{"state":"on","countDownToOn":"0","countDownToOff":"0"}}}' http://192.168.99.99:2025/setAircon?json=

Not sure if the url will work correctly but json data can be send by curl if it has a header apperently.

0 Likes

#9

I just wanted to note that I have chosen an alternative solution to the problem; I have tried a number of solutions within node red, and whatever I do, I still get the hangup error.

My solution was to write a script in Python that handles the node red commands and queries via MQTT...

When node red receives a message from Google Home, Apple Homekit, or the node red UI, to change or query the status of the aircon, it publishes an MQTT message with the appropriate command or query. The MQTT message is received by the Python script, which sends the request to the aircon unit. The script then parses the response from the aircon, and feeds that result back to node red via an MQTT message, so node red can update the UI, Google Home and Apple Homekit with the current status.

I spent many hours trying to solve this issue in node red (with the help of forum contributors), and decided to take the pragmatic approach; I created a proof of concept in Python within an hour, and then finished script after an additional hour (it's a while since I used MQTT in Python). Fewer than 50 lines of Python code were needed.

Incidentally, it appears that some of the 'json' that is returned from the aircon (specifically when I do a full status query), is malformed; I had to write my own parser to pull out the data that I needed. I now only need to add a few lines of code to be able to do things like query and set the temperatures in individual rooms.

I'd like to thank those of you who offered assistance; your help is much appreciated. I'm a little disappointed that I couldn't solve it in node red, but more than happy to have a working solution with accurate feedback from the aircon.

1 Like