openhab / openhab-addons

Add-ons for openHAB
https://www.openhab.org/
Eclipse Public License 2.0
1.86k stars 3.57k forks source link

[GPIO] feature request for output channels and maybe even the input channels #14605

Open MarkusThur opened 1 year ago

MarkusThur commented 1 year ago

Your Environment

openHABian with openHAB in newest release version with GPIO Binding in newest release version on a Raspberry Pi 3B (14.03.2023)

By intention I am using the UI Configuration only and not the configuration by config files.

openHABian shall provide output control over 4 relais connected to GPIO 4, 6, 22, 26, those four get initialized during boot to output mode and state low. The Kernel overlay GPIO-Fan gets loaded and initiaized to use GPIO 26 as the FAN Control pin. pigpiod is up, running and working.

The output pins can be set and read properly with the propriate pigs command. The fan works as exspected turning on at 60°C, turning off at 50°C as by the kernel overlay.

Configuration in UI of openHAB 3, first try

added via UI a thing Identifier: gpio:pigpio-remote:openHAB networkadress: 127.0.0.1 Port: 8888

then added 4 channels for the four output pins 4, 6, 22, 26

which lead to a code looking like this:

UID: gpio:pigpio-remote:TutesopenHAB
label: Pigpio-Gerät
thingTypeUID: gpio:pigpio-remote
configuration:
  host: 127.0.0.1
  heartbeat: 10000
  port: 8888
location: Energieraum
channels:
  - id: channel1_gpio26
    channelTypeUID: gpio:pigpio-digital-output
    label: Kanal 1 (GPIO26)
    description: ""
    configuration:
      gpioId: 26
  - id: channel2_gpio6
    channelTypeUID: gpio:pigpio-digital-output
    label: Kanal 2 (GPIO6)
    description: ""
    configuration:
      gpioId: 6
  - id: channel3_gpio22
    channelTypeUID: gpio:pigpio-digital-output
    label: Kanal 3 (GPIO22)
    description: ""
    configuration:
      gpioId: 22
  - id: channel4_gpio4
    channelTypeUID: gpio:pigpio-digital-output
    label: Kanal 4 (GPIO4)
    description: ""
    configuration:
      gpioId: 4

Then created Model and items from those channels and added controls for the Items to pages overview:

config:
  label: Overview
blocks:
  - component: oh-block
    config: {}
    slots:
      default:
        - component: oh-grid-cells
          config: {}
          slots:
            default:
              - component: oh-cell
                config:
                  action: toggle
                  actionCommand: ON
                  actionCommandAlt: OFF
                  actionItem: PigpioGerat_Kanal_1_GPIO26
                  color: red
                  item: PigpioGerat_Kanal_1_GPIO26
                  stateAsHeader: true
                  title: Lüfter (GPIO26)
              - component: oh-cell
                config:
                  action: toggle
                  actionCommand: ON
                  actionCommandAlt: OFF
                  actionItem: PigpioGerat_Kanal_2_GPIO6
                  color: green
                  item: PigpioGerat_Kanal_2_GPIO6
                  stateAsHeader: true
                  title: Kanal 2 (GPIO6)
              - component: oh-cell
                config:
                  action: toggle
                  actionCommand: ON
                  actionCommandAlt: OFF
                  actionItem: PigpioGerat_Kanal_3_GPIO22
                  color: blue
                  item: PigpioGerat_Kanal_3_GPIO22
                  stateAsHeader: true
                  title: Kanal 3 (GPIO22)
              - component: oh-cell
                config:
                  action: toggle
                  actionCommand: ON
                  actionCommandAlt: OFF
                  actionItem: PigpioGerat_Kanal_4_GPIO4
                  color: yellow
                  item: PigpioGerat_Kanal_4_GPIO4
                  stateAsHeader: true
                  title: Kanal 4 (GPIO4)
        - component: oh-grid-row
          config: {}
          slots:
            default:
              - component: oh-grid-col
                config: {}
                slots:
                  default:
                    - component: oh-toggle-card
                      config:
                        item: PigpioGerat_Kanal_1_GPIO26
              - component: oh-grid-col
                config: {}
                slots:
                  default:
                    - component: oh-toggle-card
                      config:
                        item: PigpioGerat_Kanal_2_GPIO6
              - component: oh-grid-col
                config: {}
                slots:
                  default:
                    - component: oh-toggle-card
                      config:
                        item: PigpioGerat_Kanal_3_GPIO22
              - component: oh-grid-col
                config: {}
                slots:
                  default:
                    - component: oh-toggle-card
                      config:
                        item: PigpioGerat_Kanal_4_GPIO4
masonry: []
grid: null
canvas: null

In this try it in principle worked fine, I could turn on and of the channels with the toggel cards, as well as the oh-cards are representing the status according to the toggle cards. But this starts to fail, once the overlay starts the ventilator on GPIO26 (channel1) or something else turns on or off one of the outputs.. (e.g. I with a pigs command from console or another Raspi using the remoteGPIO Interface). The gui does not represent that. This seems to be, because the channel for a gpio-output is a "write only channel". This maybe right behaviour or not.. I found in the documentations of openHAB both philospophies as well as I found in other plug ins both behaviours.. There are plugins like the Hue Bridge plugin, that updates the channel once the state of a Zigbee device changed (ok, zigbee protocol may send a confirm after a successful command), where pigpio does not automatical send a notification if something changed (but it is possible to read a output pin to get awareness of the actual state, which is also represented in the advanced value of a input-channel delay time, which allows to wait for a configurable time after a command before next read attempt).

<feature request part 1> Furthermore there is the change from @jeremyrumpf , which allows to control a heartbeat, and behaviour of in and outputs on disconnect, reconnect and so on. This is not propagated to the config UI, which could help a bit. As u can see, I manually added heartbeat to the config as u can see, but those values shoud be settable through a advanced option in the UI

After this it tried to work around that by also defining a input-channels on those four channels.. (yes this workaround works, but is critical and instable as I will discribe here).. so my Configuration of the pins and channels looks like this:

UID: gpio:pigpio-remote:TutesopenHAB
label: Pigpio-Gerät
thingTypeUID: gpio:pigpio-remote
configuration:
  host: 127.0.0.1
  heartbeat: 10000
  port: 8888
location: Energieraum
channels:
  - id: channel1_gpio26
    channelTypeUID: gpio:pigpio-digital-output
    label: Kanal 1 (GPIO26)
    description: ""
    configuration:
      gpioId: 26
  - id: channel2_gpio6
    channelTypeUID: gpio:pigpio-digital-output
    label: Kanal 2 (GPIO6)
    description: ""
    configuration:
      gpioId: 6
  - id: channel3_gpio22
    channelTypeUID: gpio:pigpio-digital-output
    label: Kanal 3 (GPIO22)
    description: ""
    configuration:
      gpioId: 22
  - id: channel4_gpio4
    channelTypeUID: gpio:pigpio-digital-output
    label: Kanal 4 (GPIO4)
    description: ""
    configuration:
      gpioId: 4
  - id: channel1_gpio26_readback
    channelTypeUID: gpio:pigpio-digital-input
    label: Kanal 1 (GPIO26) readback
    description: ""
    configuration:
      gpioId: 26
  - id: channel2_gpio6_readback
    channelTypeUID: gpio:pigpio-digital-input
    label: Kanal 2 (GPIO6) readback
    description: ""
    configuration:
      gpioId: 6
  - id: channel3_gpio22_readback
    channelTypeUID: gpio:pigpio-digital-input
    label: Kanal 3 (GPIO22) readback
    description: null
    configuration:
      gpioId: 22
  - id: channel4_gpio4_readback
    channelTypeUID: gpio:pigpio-digital-input
    label: Kanal 4 (GPIO4) readback
    description: null
    configuration:
      gpioId: 4

This imediately has a issue, as those pins may get initialized as inputs and output by this, as the binding does initialize them. This means you have to take control that the pin is first set to input and then to output and not vice versa. This is not properly controllable by the UI. <feature request part 2> Option that controlls if the binding tries to initialize a GPIO Pin or not, with default behaviour "do not initialize", as someone using GPIOs should have set them to correct operation mode during boot already (e.g. to prevent flicker during boot on outputs).

From those things i created a item pigpio-Gerät, which hosts four Channel items (Kanal 1 to Kanal 4), each of Type: switch Semantic class: point

which are linked to both the input-channel and the output-channel of the corresponding GPIO of the pigpio thing.

This in principle works, but has at least by UI configuration some flaws.

  1. you need to make sure it is done in the right order
  2. in Model and item view of the UI it is accidental if it gets recognized as a input or a output. so if it only shows the status or you control it. There is even a further flaw, after a boot, this is accidental, if you open the item, and save it again it gets recognized correctly as output until after a reload of the ui. (this is not part of this feature request, as it is not a issue of the binding)

And here we come to <feature request 3> which has two option: Option a, prefered: introduce a third type of channel to the gpio device

gpio-digital-output (in/out)

additional to the existing channel types

gpio-digital-input
gpio-digital-output

gpio-digital-output (in/out) then could read the state of the GPIO in a controlled manner, which could be set by a parameter {e.g. every 500ms, 1s, 5s, 10s etc) this would be fast enough.

Option b, not prefered: change the behaviour of gpio-digital-output to be a read / write channel, and update rate 0s would mean it is a outputchannel with the old behaviour.

Thank you for reading that much :-)

jeremyrumpf commented 1 year ago

I see a few issues here.

  1. You cannot configure the disconnect/reconnect/etc Thing actions in the UI. These should be under the "Show Advanced" section. Once that check box is selected the options should show with text of their value. Or in YAML:
UID: gpio:pigpio-remote:shoppi
label: ShopPi GPIO
thingTypeUID: gpio:pigpio-remote
configuration:
  port: 8888
  host: 192.168.164.5
  heartBeatInterval: 10000
  outputConnectAction: REFRESH
  outputReconnectAction: REFRESH
  outputDisconnectAction: SETUNDEF
  inputConnectAction: REFRESH
  inputReconnectAction: REFRESH
  inputDisconnectAction: NOTHING
  1. You cannot read the native state of an output pin. The native state of the pin can be read at connect or reconnect to pigpiod by setting outputConnectAction: REFRESH outputReconnectAction: REFRESH. But I believe this only is partially what you want because this only happens at specific times (connect and reconnect). If I understand correctly, you would like the output pin to be aware of changes made externally to OpenHAB? One way to do this would be to periodically issue a REFRESH command to the Channel that the output pin is configured for. The output will respond to the REFRESH command by polling the physical state of the gpio pin and reflecting it on the Channel and up through to any linked Items. Though, this does not occur automatically and would have to be done manually or via some timer mechanism.

I do not think that a third pin type of gpio-digital-input-output would be beneficial. But, there may be a possibility of establishing a pigpiod listener on an output pin to where the pigpiod daemon on the Raspi would report external changes back to OpenHAB. I have not tested this and do not know if it is possible or if it is supported by pigpiod. I do know that you can poll the state of an output pin, but I am not sure if you can listen for events on an output pin. My current binding just simply polls the state when needed.

Let's start by seeing if you can configure the Connect/Reconnect actions and see if they are working. Then we can see if a periodic REFRESH on the outputs would work for reporting external changes to the outputs.

Regards, Jeremy

jeremyrumpf commented 1 year ago

As a follow up, the binding does initialize the direction (INPUT/OUTPUT) of a gpio pin. Does this cause flicker? I would think that if the kernel overlay sets a pin to OUTPUT at boot and then OpenHAB re-initializes a pin to OUTPUT there would be no corresponding flicker. I could be wrong though.

Regards, Jeremy

MarkusThur commented 1 year ago

@jeremyrumpf

sorry, that I respond a bit late, as I was very busy.. And I have a lot of thank you and answers for you :-)

Thank you for the thing with the advanced button, didn't see it before.. Yes a timer induced or event induced REFRESH also does do the trick.. Am not sure it is elegant or if it uses more or less ressources, but it definitely works.

Configuring the same pin within openHAB as input and then as output also does do the trick. (that's why I ask for a third PIN Mode (output [read/write]) which would make it possible to do it more easy.

Answer to your question: