Node-red-contrib-home-assistant-websocket

and my next guess would be that the timestamp field of the service doesn’t accept templates. You can use a moment node before the call-service node and use { "datetime": "{{payload}}"}

ok thanks
I tried that and it works perfectly, even probably simpler to adapt!

Just finally migrated over to this from the LLAT node after procrastinating for about a year :slight_smile:

Works a treat and the migration was quite easy. Thanks @Kermit for all your hard work.

I’m trying your example but get an error in the debug window of

"Call-service API error. Error Message: must contain at least one of temperature, target_temp_high, target_temp_low."

image

Just using a inject node with a value of 18. What could I be missing?

image

You’re trying to extract msg.payload from msg. Just use payload in that field

Release of Documentation

The groundwork for external documentation is in place:

https://zachowj.github.io/node-red-contrib-home-assistant-websocket/


Buy me a coffee For those that enjoy my work.

2 Likes

That’s looking good

So I’ve been using this node happily for a while on a node red server running separately from my HA instance .

A couple of days ago I migrated to a NUC and am now running Node Red as a Hassio Addon .

After importing all my flows everything works flawlessly except for this node and my sensors no longer receive the updates in HA .

When Node Red is running from my original install the values update normally but after importing the flows to this new Node Red install the sensors won’t update anymore even though I can see all the values changing in the flow .

Any clue on what might be wrong ? Would really rather not have to create new sensors all over again as I have a lot of sensor templates tied to these … @Kermit ?

Edit : Just realized I am getting this error : “Sensor update attempted without connection to server.”
Apparently it creates new sensor entities after importing the flow, I suppose no way to keep the same entities as before ?

In tracing through my connection issues, it appears it’s related to this websocket library.

@Kermit, Any insight into why?

Node-Red disconnects and never reconnects after a debug “dump” happens with [object Object]:

1 Jan 10:38:06 - [info] [server:Home Assistant] WebSocket Closed http://hassio/homeassistant
1 Jan 10:38:06 - [debug] [server:Home Assistant] config server event listener closed
1 Jan 10:38:06 - [debug] [server:Home Assistant] config server event listener closed
1 Jan 10:38:11 - [debug] [server:Home Assistant] WebSocket Connecting http://hassio/homeassistant
1 Jan 10:38:11 - [debug] [server:Home Assistant] config server event listener connecting
1 Jan 10:38:11 - [debug] [server:Home Assistant] [object Object]
1 Jan 10:38:11 - [debug] [server:Home Assistant] config server event listener closed

I’m running NR 5.0.7, within a Dockerized environment on a NUC PC.

PS: Looks like it might be this line of code, nodes/config-server/config-server.js:289:

        onHaEventsError(err) {
            this.setOnContext('isConnected', false);
            this.debug(err);
        }

err is an object unable to be properly decoded by the log handler.

Latest version: v1.0.3

Where are you seeing NR 5.0.7?

^^ Node-Red Addon. It’s the version of the Docker container: https://github.com/hassio-addons/addon-node-red/releases

The UI, however, is showing 1.0.3:

OK. So it’s the version for the add-on, which isn’t the Node Red version, or Node Red’s Docker version. Got it. Had me confused for a minute.

Teehee… My efforts to decode the object didn’t work. Seems to be an anonymous function:

1 Jan 11:23:10 - [debug] [server:Home Assistant] WebSocket Connecting http://hassio/homeassistant
1 Jan 11:23:10 - [debug] [server:Home Assistant] config server event listener connecting
(node:915) UnhandledPromiseRejectionWarning: TypeError: Converting circular structure to JSON
    at JSON.stringify (<anonymous>)
    at ConfigServerNode.onHaEventsError (/opt/node_modules/node-red-contrib-home-assistant-websocket/nodes/config-server/config-server.js:291:29)

Good news is I was right as to the location of the error. How can we see what this error is?

Did you create your token and add it in, etc for your connection to Home Assistant?

I logged in directly via Docker cli. Edited the file, restarted nodered via s6. In-line editing, baby. :wink:

Unfortunate (or fortunately?) HA’s Addon “Restart” downs and recreates the container - blowing away any local changes.

It would appear the err object is not an error object. That’s why it’s difficult to pin-down, nothing is shown. It’s an HaWebsocket object. :confused:

Still no clue as to why the connection is closing.

The best I can figure out, at some point a reconnect-error is triggered by the polling tick. This then starts a down-stream of errors, not captured anywhere. The best I can see is this might be a home-assistant-js-websocket bug – failing to properly pass the resulting error? However, I can’t trace that as it’s all uncompiled .ts libraries on the filesystem. :confused:

root@a0d7b954-nodered:/var/run/s6/services$ ls -l /opt/node_modules/home-assistant-js-websocket/lib/connection.ts
ls: /opt/node_modules/home-assistant-js-websocket/lib/connection.ts: No such file or directory
root@a0d7b954-nodered:/var/run/s6/services$ ls -l /opt/node_modules/home-assistant-js-websocket/
total 40
-rw-r--r--    1 root     root         10480 Oct 26  1985 LICENSE.md
-rw-r--r--    1 root     root         17875 Oct 26  1985 README.md
drwxr-xr-x    1 root     root          4096 Jan  1 13:05 dist
-rw-r--r--    1 root     root          2365 Dec 17 05:20 package.json
root@a0d7b954-nodered:/var/run/s6/services$ ls -l /opt/node_modules/home-assistant-js-websocket/dist
total 308
-rw-r--r--    1 root     root          1177 Oct 26  1985 auth.d.ts
-rw-r--r--    1 root     root           832 Oct 26  1985 collection.d.ts
-rw-r--r--    1 root     root           597 Oct 26  1985 commands.d.ts
-rw-r--r--    1 root     root           217 Oct 26  1985 config.d.ts
-rw-r--r--    1 root     root          2409 Oct 26  1985 connection.d.ts
-rw-r--r--    1 root     root           330 Oct 26  1985 entities.d.ts
-rw-r--r--    1 root     root           240 Oct 26  1985 errors.d.ts
-rw-r--r--    1 root     root         12025 Oct 26  1985 haws.es.js
-rw-r--r--    1 root     root         70597 Oct 26  1985 haws.es.js.map
-rw-r--r--    1 root     root         12076 Oct 26  1985 haws.js
-rw-r--r--    1 root     root         70307 Oct 26  1985 haws.js.map
-rw-r--r--    1 root     root         12120 Oct 26  1985 haws.umd.js
-rw-r--r--    1 root     root         70301 Oct 26  1985 haws.umd.js.map
-rw-r--r--    1 root     root           446 Oct 26  1985 index.d.ts
-rw-r--r--    1 root     root          1184 Oct 26  1985 messages.d.ts
-rw-r--r--    1 root     root           223 Oct 26  1985 services.d.ts
-rw-r--r--    1 root     root           133 Oct 26  1985 socket.d.ts
-rw-r--r--    1 root     root           628 Oct 26  1985 store.d.ts
-rw-r--r--    1 root     root          2569 Oct 26  1985 types.d.ts
-rw-r--r--    1 root     root            64 Oct 26  1985 util.d.ts

Here’s a full trace of the onClientError() event trigger:

1 Jan 13:23:10 - [debug] [server:Home Assistant] config server event listener connecting
Trace: o {
  options:
   { setupRetry: 0,
     createSocket: [Function: createSocket],
     self:
      HaWebsocket {
        _events: [Object],
        _eventsCount: 13,
        _maxListeners: 0,
        config: [Object],
        connectionState: 0,
        states: [Object],
        services: [Object],
        statesLoaded: false,
        client: [Circular],
        subscribedEvents: [Set],
        unsubCallback: [Object],
        integrationVersion: 0,
        servicesLoaded: false } },
  commandId: 11,
  commands:
   Map {
     2 => { resolve: [Function],
       reject: [Function],
       callback: [Function],
       subscribe: [Function: subscribe],
       unsubscribe: [Function: unsubscribe] },
     3 => { resolve: [Function],
       reject: [Function],
       callback: [Function],
       subscribe: [Function: subscribe],
       unsubscribe: [Function: unsubscribe] },
     5 => { resolve: [Function],
       reject: [Function],
       callback: [Function],
       subscribe: [Function: subscribe],
       unsubscribe: [Function: unsubscribe] },
     6 => { resolve: [Function],
       reject: [Function],
       callback: [Function],
       subscribe: [Function: subscribe],
       unsubscribe: [Function: unsubscribe] },
     8 => { resolve: [Function],
       reject: [Function],
       callback: [Function],
       subscribe: [Function: subscribe],
       unsubscribe: [Function: unsubscribe] },
     9 => { resolve: [Function],
       reject: [Function],
       callback: [Function],
       subscribe: [Function: subscribe],
       unsubscribe: [Function: unsubscribe] },
     11 => { resolve: [Function],
       reject: [Function],
       callback: [Function],
       subscribe: [Function: subscribe],
       unsubscribe: [Function: unsubscribe] } },
  eventListeners:
   Map {
     'ready' => [ [Function: bound onClientOpen],
       [Function: u],
       [Function: u],
       [Function: u] ],
     'disconnected' => [ [Function: bound onClientClose] ],
     'reconnect-error' => [ [Function: bound onClientError] ] },
  closeRequested: false,
  socket:
   WebSocket {
     _events:
      [Object: null prototype] { message: [Function], close: [Function] },
     _eventsCount: 2,
     _maxListeners: undefined,
     readyState: 3,
     protocol: '',
     _binaryType: 'nodebuffer',
     _closeFrameReceived: true,
     _closeFrameSent: true,
     _closeMessage: '',
     _closeTimer:
      Timeout {
        _called: false,
        _idleTimeout: -1,
        _idlePrev: null,
        _idleNext: null,
        _idleStart: 74563,
        _onTimeout: null,
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(unrefed)]: false,
        [Symbol(asyncId)]: 1783,
        [Symbol(triggerId)]: 1358 },
     _closeCode: 1000,
     _extensions: { 'permessage-deflate': [PerMessageDeflate] },
     _receiver:
      Receiver {
        _writableState: [WritableState],
        writable: false,
        _events: [Object: null prototype] {},
        _eventsCount: 0,
        _maxListeners: undefined,
        _binaryType: 'nodebuffer',
        _extensions: [Object],
        _maxPayload: 104857600,
        _bufferedBytes: 0,
        _buffers: [],
        _compressed: true,
        _payloadLength: 2,
        _mask: undefined,
        _fragmented: 0,
        _masked: false,
        _fin: true,
        _opcode: 8,
        _totalPayloadLength: 0,
        _messageLength: 0,
        _fragments: [],
        _state: 0,
        _loop: false,
        [Symbol(websocket)]: [Circular] },
     _sender:
      Sender {
        _extensions: [Object],
        _socket: [Socket],
        _firstFragment: true,
        _compress: false,
        _bufferedBytes: 0,
        _deflating: false,
        _queue: [] },
     _socket:
      Socket {
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'hassio',
        _readableState: [ReadableState],
        readable: false,
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        parser: null,
        _httpMessage: null,
        timeout: 0,
        write: [Function: writeAfterFIN],
        [Symbol(asyncId)]: 1358,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 40143,
        [Symbol(kBytesWritten)]: 1010,
        [Symbol(websocket)]: undefined },
     _bufferedAmount: 0,
     _isServer: false,
     _redirects: 0,
     url: 'ws://hassio/homeassistant/websocket',
     _req: null },
  _ent:
   { state: [Getter],
     refresh: [Function: c],
     subscribe: [Function: subscribe] },
  _srv:
   { state: [Getter],
     refresh: [Function: c],
     subscribe: [Function: subscribe] },
  _cnf:
   { state: [Getter],
     refresh: [Function: c],
     subscribe: [Function: subscribe] } }
    at HaWebsocket.callback [as onClientError] (/opt/node_modules/node-red-contrib-home-assistant-websocket/lib/ha-websocket.js:266:10)
    at forEach (/opt/node_modules/home-assistant-js-websocket/lib/connection.ts:153:7)
    at Array.forEach (<anonymous>)
    at o.fireEvent (/opt/node_modules/home-assistant-js-websocket/lib/connection.ts:152:48)
    at /opt/node_modules/home-assistant-js-websocket/lib/connection.ts:327:18
    at process._tickCallback (internal/process/next_tick.js:68:7)

This is a dump of the result of this addition:
@node_modules/node-red-contrib-home-assistant-websocket/lib/ha-websocket.js:266

    onClientError(data) {
        console.trace(data);
        this.closeClient(
            data,
            'events connection error, cleaning up connection'
        );
    }

The websocket object has a closeCode 1000, and according to the docs: this is a perfectly normal closure – https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent

So, something else is broken. :frowning:

Hi all,

Just a few days ago I noticed some weird behavior in my Node-Red and I cannot pin-point what the problem is (driving me mad :stuck_out_tongue: ). So hoping someone can help me troubleshoot (Hass logs are not saying anything as well as Node-Red…).

Running Hass and Node-Red in a separate Docker.

I have this input_boolean in home-assistant to indicate if we are sleeping or not. It always has worked perfectly:

image

In some Node-Red flows I check the state of this Switch like so:

However, recently I’m getting the result “Initializing at: …” constantly on this boolean:

image

Does not matter if it’s On/Off, always the same result and treated as “false” by the node…

The debug shows as follows, the first line is the payload before it enters this node, second is the result “initializing”.

image

Am I missing something obvious??

@flamingm0e - according to HA Websocket’s documents, reconnect-error is supposed to be only called on ERR_INVALID_AUTH

Looks like somewhere, somehow, the auth token is expiring? However, there is a bug in the websocket’s implementation. According to the docs reconnect-error is supposed to pass the code not a websocket object.

This may very well be an HA bug (maybe?). NR hasn’t changed from what I can tell.

Kind of… :slight_smile:

input_boolean.sleeping_global is a boolean and you are comparing its value to a string.
So, you are comparing “true” with “on” and it is always “false”.
Choose boolean in the drop down menu “if state”. It should be better.
GV

Turns out this IS due an auth error! – The debug() messages within ha-websocket aren’t showing up in the logs, making it hard to debug this issue. I added my own commands and here we go:

[Auth Phase] New connection ws://hassio/homeassistant/websocket
1 Jan 14:08:38 - [debug] [server:Home Assistant] WebSocket Connecting http://hassio/homeassistant
1 Jan 14:08:38 - [debug] [server:Home Assistant] config server event listener connecting
[Auth Phase] Received { type: 'auth_required', ha_version: '0.103.5' }
[Auth Phase] Received { type: 'auth_ok', ha_version: '0.103.5' }
1 Jan 14:08:38 - [info] [server:Home Assistant] WebSocket Connected to http://hassio/homeassistant
1 Jan 14:08:38 - [debug] [server:Home Assistant] config server event listener connected
1 Jan 14:13:05 - [info] [server:Home Assistant] WebSocket Closed http://hassio/homeassistant
1 Jan 14:13:05 - [debug] [server:Home Assistant] config server event listener closed
events connection closed, cleaning up connection
1 Jan 14:13:05 - [debug] [server:Home Assistant] config server event listener closed
[Auth Phase] Initializing ws://hassio/homeassistant/websocket
[Auth Phase] New connection ws://hassio/homeassistant/websocket
1 Jan 14:13:10 - [debug] [server:Home Assistant] WebSocket Connecting http://hassio/homeassistant
1 Jan 14:13:10 - [debug] [server:Home Assistant] config server event listener connecting
[Auth Phase] New connection ws://hassio/homeassistant/websocket
1 Jan 14:13:15 - [debug] [server:Home Assistant] WebSocket Connecting http://hassio/homeassistant
1 Jan 14:13:15 - [debug] [server:Home Assistant] config server event listener connecting
[Auth Phase] Received { type: 'auth_required', ha_version: '0.103.5' }
[Auth Phase] Received { type: 'auth_ok', ha_version: '0.103.5' }
1 Jan 14:13:15 - [info] [server:Home Assistant] WebSocket Connected to http://hassio/homeassistant
1 Jan 14:13:15 - [debug] [server:Home Assistant] config server event listener connected
1 Jan 14:18:05 - [info] [server:Home Assistant] WebSocket Closed http://hassio/homeassistant
1 Jan 14:18:05 - [debug] [server:Home Assistant] config server event listener closed
events connection closed, cleaning up connection
1 Jan 14:18:05 - [debug] [server:Home Assistant] config server event listener closed
[Auth Phase] Initializing ws://hassio/homeassistant/websocket
[Auth Phase] New connection ws://hassio/homeassistant/websocket
1 Jan 14:18:10 - [debug] [server:Home Assistant] WebSocket Connecting http://hassio/homeassistant
1 Jan 14:18:10 - [debug] [server:Home Assistant] config server event listener connecting
[Auth Phase] Received { type: 'auth_required', ha_version: '0.103.5' }
[Auth Phase] Received { type: 'auth_invalid', message: 'Invalid access' }
events connection error, cleaning up connection

I’ve opened up two tickets on this, first one is a real bug, other may be resolved some other way (?):

Now, I’m dead in the water. … NR can’t stay connected. :frowning:
(*note: I can reconnect NR simply by manually redeploying the flows … but it won’t stay connected)