IOTstack icon indicating copy to clipboard operation
IOTstack copied to clipboard

Node-Red-Contrib-HomeKit-Bridged (NRCHKB) not working

Open frooonk opened this issue 5 years ago • 7 comments

Because the repo https://github.com/gcgarner/IOTstack is no longer active and has been migrated over to here, I post my problem as a new issue:

First I have installed the NRCHKB-Node in Node-Red (docker-container from the github-Repo "gcgarner/IOTstack") and I could see the device in Homekit but if I try to add that device it just runs into a timeout.

Then I have installed the NRCHKB-Node in Node-Red (docker-container from the forked github-Repo "SensorsIot/IOTstack") and now I can't see any new Homekit-device anymore !!!

The problems above don't occur with Node-Red standard installation. So it must have something to do with Docker or the network configuration in Docker. All Firewall-Rules between my VLAN's are de-activated...

On the github repo to the NRCHKB docker file (https://github.com/RaymondMouthaan/node-red-homekit-docker) is mentioned that you have to add network_mode: "host" to your config otherwise it will not work. When I do this, however, it has no effect on the network settings: in the Portainer Web-UI, the nodered-container still remains assigned to the network "iotstack_default" (network mode bridged). When I try to connect the nodered container to the "host" network in the Portainer Web UI, an error message appears.

Maybe I would have more information if I could start node-red in debug mode as described by Shaquu (https://github.com/NRCHKB/node-red-contrib-homekit-bridged/issues/252) but I don't know how to use the extended debug command "DEBUG = NRCHKB, Accessory, HAPServer, EventedHTTPServer node-red" on a docker container.

frooonk avatar May 18 '20 12:05 frooonk

OK. I will try to get more precise:

Can the nodered-container be connected to the network "host" instead of the network "iotstack_default" (network mode "bridged")?

I tried to set network_mode: "host" in the config-file ~/IOTstack/services/nodered/service.yml and in the config-file ~/IOTstack/docker-compose.yml. Both changes have no effect: in the Portainer Web-UI, the nodered-container still remains assigned to the network "iotstack_default" (network mode bridged).

When I try to connect the nodered-container manually in the Portainer Web-UI to the "host" network, an error message appears there.

frooonk avatar May 20 '20 16:05 frooonk

Hi @frooonk - I don't use HomeKit (which is surprising for someone who has been a card-carrying Mac person since 1987 so perhaps I should say "I haven't found any need for HomeKit - yet").

You did not explain exactly what you were doing but I did not have any trouble getting "host mode" to work so I'm going to make a guess that your own experimentation has involved some variation on the node-red-homekit-docker quick-start command:

docker run -d --net=host -v <path_on_host>:/data --name=node-red-homekit raymondmm/node-red-homekit

I don't (yet) have any need to run Node-Red in host mode but I was reading about this only yesterday in the Using Bluetooth section of the Node-Red documentation of IOTstack. What it says to do is add this line to the nodered section of docker-compose.yml:

    network_mode: "host"

What's the difference between adding that line to docker-compose.yml and the docker run command? I have absolutely no idea!

Anyway, I just added the line. My complete "nodered" section looks like:

  nodered:
    container_name: nodered
    build: ./services/nodered/.
    restart: unless-stopped
    user: "0"
    privileged: true
    env_file: ./services/nodered/nodered.env
    ports:
      - 1880:1880
    volumes:
      - ./volumes/nodered/data:/data
    network_mode: "host"

The instruction says to be sure to use correct indentation and to do it with spaces not tabs. I did that. Then I brought it up via:

$ cd ~/IOTstack
$ docker-compose up -d

Command-line output

(where "…" means "line(s) omitted for brevity and to focus on the essential bits.")

Before

$  docker ps --format "table {{.Names}}\t{{.Ports}}"
NAMES               PORTS
nodered             0.0.0.0:1880->1880/tcp
…
  • docker ps is showing a mapping from external port 1880 to internal port 1880.
$ docker exec -it nodered bash
# traceroute 192.168.132.1
traceroute to 192.168.132.1 (192.168.132.1), 30 hops max, 38 byte packets
 1  172.19.0.1 (172.19.0.1)  0.030 ms  0.028 ms  0.021 ms
 2  192.168.132.1 (192.168.132.1)  0.318 ms  0.337 ms  0.304 ms
# exit
$
  • a traceroute run from inside the container to my local router shows a hop across the internal network. The nodered container is not in the same broadcast domain as the RPi hardware.

Interpretation: a packet sent from another device to raspberrypi.local:1880 will be picked up by Docker and then routed across the internal iotstack_default network to nodered.

After

$ docker-compose up -d
…
Recreating nodered ... 
…
Recreating nodered ... done
  • docker-compose up -d senses the configuration change and recreates nodered.
$ docker ps --format "table {{.Names}}\t{{.Ports}}"
NAMES               PORTS
nodered             
…
  • docker ps shows no port mapping for the new container.
$ docker exec -it nodered bash
# traceroute 192.168.132.1
traceroute to 192.168.132.1 (192.168.132.1), 30 hops max, 38 byte packets
 1  192.168.132.1 (192.168.132.1)  0.305 ms  0.224 ms  0.218 ms
# exit
$ 
  • a traceroute run from inside the container to my local router shows no additional hop. As far as the nodered container is concerned, it is in the same broadcast domain as the RPi hardware.

Interpretation: a packet sent from another device to raspberrypi.local:1880 will be picked up by nodered, directly. No Docker relay is involved.

External tests

  • Connecting via browser to Node-Red on port 1880 has the same behaviour for both host and non-host modes.
  • Connecting via browser to Portainer, then clicking "Networks", then "Host", and examining the "Containers in network" area:
    • in host mode, the area shows "nodered";
    • in non-host mode, the area is empty.

I didn't go any further than that, such as trying to confirm that Node-Red flows still worked without modification. I am pretty sure the flows would need editing to work in host mode. For example, in non-host mode a Node-Red flow will refer to Mosquitto as mosquitto:1883. In host mode, that will have to become 127.0.0.1:1883 so that external port 1883 being listened to by Docker gets routed via iotstack_default to port 1883 of the Mosquitto container.

All up, I reckon adding network_mode: "host" to docker-compose.yml does the trick. If you're using the same approach but not seeing similar patterns then we probably need to dig deeper.

Paraphraser avatar May 21 '20 00:05 Paraphraser

Thanks to @Paraphraser for the helpful response!

I did the same modification network_mode: "host" in the docker-compose.yml, too. But I didn't know that I have to bring it up via docker-compose up -d. That will probably be because I still have little experience with docker containers and I'm working in HVAC building control (I'm no IT-developer).

Now it works and I can use all my existing nodered-flows (there are many!) to my new IOTstack-System.

Thank you very much again :-)

frooonk avatar May 21 '20 08:05 frooonk

It's a black art. Sometimes "docker-compose up -d" does the trick. Sometimes "docker-compose restart nodered" (or whichever container you're working on). Sometimes "docker-compose stop nodered" followed by "docker-compose up -d". There's probably some logic to it but I usually keep pounding away until something works. I call this the "head banging approach". If you keep smacking your head into a brick wall, eventually the wall will give way (or you'll get concussed and give up). 🤣

Paraphraser avatar May 21 '20 09:05 Paraphraser

Same problem, resolved with network_mode: "host"

But also "problem" with missing assigned ports.

S474N avatar Aug 16 '20 18:08 S474N

I just wanted to confirm that the network_mode: "host" trick works.

However, what doesn't work is the access to the Homekit devices defined in Node-RED when connected via Wireguard. Perhaps related to DNS?

Note that anything that has to do with connections to other containers from within Node-RED, such as InfluxDB or Mosquitto needs to be changed from their container name to localhost to continue working. This is because Node-RED cannot resolve the other containers by name when using network_mode: "host".

Nurgak avatar Oct 20 '21 05:10 Nurgak

This is "one of those things that you just have to know." But it might be a good idea to document this so leave it open for now.

Paraphraser avatar Jun 19 '22 08:06 Paraphraser