How I managed to controll the gate

I have a set of rules devices and items to controll a Gate. I want to show how I realized it.
So a requirement was to not make any changes to the gate. It has multiple encrypted remotes. So yeah, maybe I could have just progrmmed a pi on it or so, but for that I would have to make changes and therefore must ask my dad ^^.
So I used a construction out of Fischertechnik pneumatics and an ESP32 with a relay. So I built a holder for the remote and some pneumatics on top of that.
That is then connected to the relay which is controlled by the ESP.
On the ESP is a sketch that subscribes to a MQTT topic for the button and triggers the press of the button to control the gate. So with that we have the control part.

But there is a problem: The remote has exactly one button for three actions:

  • Open
  • Close
  • Stop

So when you are pressing it, it either opens OR closes. When you press while it moves it stops.
So I needed to know in which state the gate is.
I ended up using an ultrasonic sensor mounted on the pile of the gate. Since no WLAN is available at this position, I used an old telephone cable that was luckily going from the cellar to the gate. So then I spend an afternoon getting the cable out of the dirt and find the cable pairs.

In the cellar I now have another ESP32 reading the ultrasonic sensor.
All that was left is to create a proxy item to link them and a smart rule to position the gate with a slider.
In OH2 I was using an external python script communicating with openhab through the HTTP API.
But as I migrated OH3 (yesterday, and I actually did a clean setup, no migration) I used Jython to do it.

Here is the rule:

import time

def invert_position(pos):
    return 100 - pos


target = int(float(str(ir.getItem("gate").state)))

def get_current():
    return invert_position(int(float(str(ir.getItem("gate_status").state))))


def is_ok():
    return get_current() in range(target - 5, target + 5)


def press_button():
    events.sendCommand('gate_button', 'ON')


if is_ok():
    events.sendCommand('stdout', "OK.")
else:
    events.sendCommand('gate_working', "working...")
    press_button()
    # keep checking if posititon reached press button again
    # when position is 0 or 100 press button again.
    # TODO: Cancel after 5 tries or so to prevent bugs
    iterations = 0
    while True:
        iterations = iterations + 1
        if is_ok():
            if get_current() > 98 or get_current() < 3:
              break
            press_button()
            break
        if iterations > 90:
            press_button()
            iterations = 0
            continue
        current = get_current()
        if current > 98 or current < 2:
            time.sleep(4)
            if get_current() > 98 or get_current() < 2:
                press_button()
                iterations = 0
        time.sleep(0.5)
events.sendCommand('gate_working', "ready!")

The stdout thing is just for debugging. (BTW, errors in the WebUI for python scripts or logs would be cool. Currently it all just fails silently.)

Then I have two more rules:

triggers:
  - id: "1"
    configuration:
      itemName: gate_working
      state: ""
      previousState: ""
    type: core.ItemStateChangeTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: gate.label = "Tor (" + gate_working.state.toString + ")"
    type: script.ScriptAction

This one updates the label (not working with openHAB 3 UI, the label does not live update. I will create an Issue for this.) so you always know if the gate is still moving. I will later implement a lock feature in it so I don’t have the rule running twice (Or is there a better way?)

Gate proxy state updater:

triggers:
  - id: "1"
    configuration:
      itemName: gate_status
      previousState: ""
    type: core.ItemStateChangeTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: if(gate.state != gate_status.state) gate.postUpdate((100 -
        gate_status.state as DecimalType).toString)
    type: script.ScriptAction

This just inverts the position from the sensor and applies it to the proxy.

1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.