ebaauw / homebridge-rpi

Homebridge plugin for Raspberry Pi.
Apache License 2.0
308 stars 18 forks source link

Please add an option to set initial GPIO switch state #32

Closed ffaamm closed 4 years ago

ffaamm commented 4 years ago

I try to explain how I use this plugin and how 1.1.x has broke my setup.

First, versions:

Node.js 12.16.3
npm 6.14.5
Homebridge 1.0.4
Homebridge RPi 1.1.3

I have a 4 relay board (like this) and I use Homebridge RPi for command its relays by means of 4 switches, two static and two pulsed (1s):

        {
            "platform": "RPi"
            "name": "GPIO relays",
            "hosts": [
                {
                    "host": "localhost:8888",
                    "devices": [
                        {
                            "device": "switch",
                            "name": "Switch 1",
                            "gpio": 17,
                            "reversed": true,
                            "pulse": 1000
                        },
                        {
                            "device": "switch",
                            "name": "Switch 2",
                            "gpio": 27,
                            "reversed": true
                        },
                        {
                            "device": "switch",
                            "name": "Switch 3",
                            "gpio": 22,
                            "reversed": true,
                            "pulse": 1000
                        },
                        {
                            "device": "switch",
                            "name": "Switch 4",
                            "gpio": 23,
                            "reversed": true
                        }
                    ]
                }
            ]
        }

My problem, and I already had it before 1.1.x but I had managed to solve it with my own hack, is the initial status of the GPIO outputs, which I need to be reversed.

The 4 relays can all be wired either NO or NC, but, because of the device I'm commanding by means of them, I must wire them NO, because they must stay open also when the plugin (or Homebridge, or the whole Raspberry Pi) is shut down. They must be allowed to switch to closed state only when I command them from the Home app.

Unfortunately for me, the GPIO logical and electrical output is that when the logic state is LOW (pigs write 0) the electrical output is high and the relay engages from Normally Open to Closed, and instead when the logic state is HIGH (pigs write 1) the electrical output is low.

This plugin doesn't allow to reverse the GPIO initial state (the switch device features the reversed option, but that's useful just for reverse the state of the switch as shown on the Home app. In order to solve my issue, I added this to /etc/rc.local:

pigs write 17 1
pigs write 27 1
pigs write 22 1
pigs write 23 1

This effectively switched off (GPIO logic high, electrical low) the relays, and because this plugin didn't noticed this hack, the relays where to engage only when I activated them trough the Home app.

Now with 1.1 this is not working anymore, and my understanding is that it's because of the improved error detection listed in the changelog. Unfortunately this means that now I have to ask proper support for reverse the initial GPIO state.

Here is an example: in homebridge-gpio-device, another plugin for interact with the GPIO, its DigitalOutput/switch device features these two options: inverted: "reverse the behaviour of the GPIO output pin (on: LOW, off: HIGH)" initState: "default state of the switch at startup (0: off, 1: on)"

homebridge-rpi reversed is like homebridge-gpio-device initState, where instead there is no equivalent to homebridge-gpio-device inverted.

In other words, I ask to be able to set from the plugin itself the default state of the GPIO outputs, like the pigs write xx 1 above.

Thank you

ebaauw commented 4 years ago

Now with 1.1 this is not working anymore, and my understanding is that it's because of the improved error detection listed in the changelog.

I don't understand how. Homebridge RPi does not change the GPIO output on startup or re-connect. It does (re-)initialise the output mode (the equivalent of pigs modes 17 1), but it did that in v1.0.x as well. As far as I'm aware that doesn't change the state. Could you try and see if it does for your relays?

Are you running Homebridge on the Pi to which the relays are connected? In a container, or directly?

Do the relays also change if you stop the pigpio daemon (sudo systemctl stop pigpiod) and, a couple of minutes later, restart it (sudo systemctl start pigpiod).

In other words, I ask to be able to set from the plugin itself the default state of the GPIO outputs, like the pigs write xx 1 above.

When would this default state be applied:

initState would reflect the HomeKit value, not the inverted value (so in your case, you'd set it to 0 for Off, which translates to a GPIO setting of 1).

ffaamm commented 4 years ago

I don't understand how. Homebridge RPi does not change the GPIO output on startup or re-connect.

I was changing the GPIO output on startup, and now the plugin seems (in my understanding) to detect it... but after I disabled my hack in /etc/rc.local, it still persist... I'm thinking that my initial assumption is wrong and something else is now broken in the switch device (more below at the end).

It does (re-)initialise the output mode (the equivalent of pigs modes 17 1), but it did that in v1.0.x as well. As far as I'm aware that doesn't change the state. Could you try and see if it does for your relays?

I have now tried this, but I am not sure that is what you are asking:

Removed pigs w 17 1 w 27 1 w 22 1 w 23 1 from /etc/rc.local $ sudo hb-service uninstall $ sudo shutdown -r now

After reboot (therefore, without Homebridge):

$ pigs mg 0 mg 1 mg 2 mg 3 mg 4 mg 5 mg 6 mg 7
0
0
0
0
0
0
0
0
$ pigs r 17 r 27 r 22 r 23
0
0
0
0

All GPIO pins are LOW (0V). All 4 relays are activated, because the board works "active low", thus a 0V pin lets the relay activate, while a 3v3 pin disactivate it); this is why I need to reverse this initial state, and this is what I accomplish with pigs w 17 1 w 27 1 w 22 1 w 23 1 in /etc/rc.local.

If I run:

$ pigs w 17 1 w 27 1 w 22 1 w 23 1

and then:

$ pigs r 17 r 27 r 22 r 23
1
1
1
1

that is the GPIO startup status that I need. Again, no problem if the plugin can do this or I have to do it in /etc/rc.local (the third solution would be to add a transistor on each of them for reverse the signal).

Are you running Homebridge on the Pi to which the relays are connected? In a container, or directly?

Running directly on the Raspberry Pi Zero WH to which they are connected. No Docker, no remote commands trough the network. Raspbian lite installed on my own, all available updates installed. Of course, being a Zero, Node.js is the unofficial built for arm6 (installed as per the official Homebridge installation guide advises).

Do the relays also change if you stop the pigpio daemon (sudo systemctl stop pigpiod) and, a couple of minutes later, restart it (sudo systemctl start pigpiod).

No, either if they are on or off, they keep their status both on stop an start of the service.

In other words, I ask to be able to set from the plugin itself the default state of the GPIO outputs, like the pigs write xx 1 above. When would this default state be applied:

On Homebridge startup? On (re-) connect to the pigpio server? On Homebridge shutdown? initState would reflect the HomeKit value, not the inverted value (so in your case, you'd set it to 0 for Off, which translates to a GPIO setting of 1).

I'm not sure of what I wrote in my original message, maybe I have inverter something... and I would rephrase if not that, as you wrote in the beginning of your message, "Homebridge RPi does not change the GPIO output on startup or re-connect". So, if this plugin doesn't perform an explicit "pigs w 17 0" it's effectively useless to as for a "pigs w 17 1" alternative.

I have noticed something else, and maybe that is the problem that I wrongly identified here in the beginning. The switch device doesn't seem to work right anymore.

The two of them that I have configured with "pulse": 1000", never automatically resets themself anymore. I toggle them, and they keep the new status until I toggle them again (and so on). The other two without pulse are behaving even more strange... like I have to push them two times for have them toggle, and then just one time for toggle them back. But I'm not sure... it's reproducible all the times, but I have still not fully understood the action/reaction sequence. Also the pulse switches not pulse anymore... 100% reproducible, even across reboots, either with or without pigs w ... in /etc/rc.local.

Maybe I should try to test it in a more proper way (for better reporting) or record it. Is there a way to run Homebridge and/or this plugin (or pigpiod) in debug mode for try to collect some meaningful information?

ebaauw commented 4 years ago

Please run homebridge -D or enable debugging from the UI. You should get a debug message for every command sent to and response received from the pigpio server. If you set the Log Level characteristic on the Pi service to 3 (in Eve) the raw data buffers are logged as well.

ebaauw commented 4 years ago

Also the pulse switches not pulse anymore... 100% reproducible, even across reboots, either with or without pigs w ... in /etc/rc.local.

This happens when the switch is on when Homebridge starts. In case of reversed: when the GPIO is low. Setting the GPIO high through pigs w 18 1 should fix the behaviour. I suppose when pulse is set, Homebridge RPi should force-set the switch to off on startup?

Are you sure pigpiod has started and is already accepting commands when /etc/rc.local is executed? I've been doing some research: You can set defaults for GPIO pins on boot through /boot/config.txt, see https://www.raspberrypi.org/documentation/configuration/config-txt/gpio.md. This is probably more reliable that calling pigs from /etc/rc.local.

Any luck getting the logging? You should be seeing something like:

[5/18/2020, 22:22:43] [RPi] pi3 Switch: On changed from false to true
[5/18/2020, 22:22:43] [RPi] pi3: command WRITE (4) 18 0 
[5/18/2020, 22:22:43] [RPi] pi3: command WRITE (4) => 0
[5/18/2020, 22:22:43] [RPi] pi3 Switch History: add entry 14: {"time":1589833363,"on":1}
[5/18/2020, 22:22:43] [RPi] pi3 Switch History: set history status to: 75020000 00000000 9e237324 [01 0e01] 0f00 c00f 00000000 000000000101
[5/18/2020, 22:22:43] [RPi] pi3 Switch History: set History Status from "XgIAAAAAAACeI3MkAQ4BDgDADwAAAAAAAAAAAQE=" to "dQIAAAAAAACeI3MkAQ4BDwDADwAAAAAAAAAAAQE="
[5/18/2020, 22:22:43] [RPi] pi3 Switch: gpio false
[5/18/2020, 22:22:44] [RPi] pi3: command WRITE (4) 18 1 
[5/18/2020, 22:22:44] [RPi] pi3: command WRITE (4) => 0
[5/18/2020, 22:22:44] [RPi] pi3 Switch: gpio true
[5/18/2020, 22:22:44] [RPi] pi3 Switch: set On from true to false
[5/18/2020, 22:22:44] [RPi] pi3 Switch History: add entry 15: {"time":1589833364,"on":0}
[5/18/2020, 22:22:44] [RPi] pi3 Switch History: set history status to: 76020000 00000000 9e237324 [01 0e01] 1000 c00f 00000000 000000000101
[5/18/2020, 22:22:44] [RPi] pi3 Switch History: set History Status from "dQIAAAAAAACeI3MkAQ4BDwDADwAAAAAAAAAAAQE=" to "dgIAAAAAAACeI3MkAQ4BEADADwAAAAAAAAAAAQE="

This is with a config.json of:

                {
                    "host": "pi3",
                    "devices": [
                        {
                            "device": "switch",
                            "gpio": 18,
                            "reversed": true,
                            "pulse": 1000
                        }
                    ]
                },
ebaauw commented 4 years ago

v1.1.5 has improved handling of switch devices.