SensorsIot / IOTstack

Docker stack for getting started on IOT on the Raspberry PI
GNU General Public License v3.0
1.44k stars 304 forks source link

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

Open frooonk opened 4 years ago

frooonk commented 4 years ago

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 commented 4 years ago

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.

Paraphraser commented 4 years ago

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 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
$

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 ps --format "table {{.Names}}\t{{.Ports}}"
NAMES               PORTS
nodered             
…
$ 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
$ 

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

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.

frooonk commented 4 years ago

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 :-)

Paraphraser commented 4 years ago

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). 🤣

S474N commented 4 years ago

Same problem, resolved with network_mode: "host"

But also "problem" with missing assigned ports.

Nurgak commented 2 years ago

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".

Paraphraser commented 2 years ago

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.