nebhead / garage-zero

Garage door opener/closer/controller with status using a Raspberry Pi Zero W and Flask w/Bootstrap

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Open / Close with voice using Google Home

silentfire619 opened this issue · comments

Is it possible to integrate this with Google Home to use voice command to open and close the door?

As it stands currently, I haven't yet implemented an API to do this, however it is definitely in the plan to implement this API in an upcoming version. That said, there are some items to remember:

  1. Google Home (or Alexa) integration requires a third party server that sits on the internet that can connect with your Google Assistant services, and send a SSL Webhook to the garage door on your network. That means you'll need to use something like IFTTT, or HomeAssistant to be that intermediary. Both of these are pay services to use outside of your network (although it's possible to get some of these for free).
  2. Security: Adding an API to the garage door may require you open a port to this device. Exposing your IoT devices to the internet can be tricky business and may put your home network at risk. I'll do my best to make this as secure as I can, but there are always risks. My plan is to create this API for use with HomeAssistant, behind your firewall, to let HomeAssistant do all of the security for you.

No timeline yet, but i'm looking at tackling this in the next few weeks, along with another companion project for an outdoor keypad to open the door without your cell phone.

One other thing is that for home security, you might not want to have some be able to shout at your home assistant (inside your house) to open your garage door. So might be good to have a passcode to open the door, but no such passcode to close it.

Thank you for your quick reply. I have IFTTT and was trying to get it working with that but had no luck (I do not really know what I am doing there.) I have already allowed outside access to the PI by forwarding port XXXX to port 80. I appreciate all the work you have and continue to do. I will be looking for to this if / when you complete it.

Sure no problem. I would highly recommend closing up that port for now. After we get the updated feature implemented, we'll likely open up 443 (for HTTPS communication to the API only). But for now, your Pi is exposed on port 80 and it can be exploited by a malicious actor.

Wouldn't they need to know the port I am using to redirect to port 80 in order to really do anything?

So right now, if you have your Pi's port 80 opened to the internet, then someone could do remote discovery (port scan) and find your open port. If it's GarageZero, then it would be the entire interface available on that port - and whatever else the Flask server is providing. It might be possible for someone really smart to manipulate the commands on port 80 to do more malicious things.

In the future, we'll open up port 443 via the nginx reverse proxy to just the API. And to use the API, a unique API key will need to be passed through, encrypted with SSL. All other traffic on that port will be ignored. We can provide the API key to the webhook on IFTTT which can send commands that way. The attack surface is much more limited, even if they discover your external port.

I would love to have the API feature added to this version. Do you take kickbacks/donations to enable?

I would love to have the API feature added to this version. Do you take kickbacks/donations to enable?

Do you mean similar to the API that is implemented in v2 for Home Assistant (or other apps)? I think it could be done pretty easily. I could take a crack at it.

Exactly that, thank you. I tried to install V2 with the HW setup from this build with no success. Thank you for putting this out there. Do you have a patreon to contribute?

Exactly that, thank you. I tried to install V2 with the HW setup from this build with no success. Thank you for putting this out there. Do you have a patreon to contribute?

Cool, yeah, I think I can make the changes with v1. I was just looking at the v2 code to see if we could make the v1 hardware work properly - but I realized that there is a breaking change with the v2 implementation, to make it work with the old hardware configuration. The relay gate is not implemented in the v2 (because it's not needed for the new hardware) and thus, is wouldn't work with the old hardware configuration.

However, you could operate without the relay gate at all (just like the v2 hardware). This means a minor change to your relay wiring. Basically have one end of the button wire into the common side of relay2 and the other to the NO (normally open) side of relay2. And of course, remove the jumper wire that you have between relay1 & relay2. This would only use one relay, which would be controlled by the raspberry Pi for simulating the button press.

If you make the above hardware change to the v1 setup, you can configure the v2 software settings in the webui as follows:

  1. Edit door settings (settings -> door settings -> edit default door:

image

  1. Remove the second sensor which isn't part of the original design

image

  1. Change the GPIO's to match the original design

image

relay_pin = 15 # GPIO 15, Pin 10 (RasPi Header) -> Goes to relay IN2 (Relay2)
switch_pin = 18 # GPIO 18, Pin 12 (RasPi Header) -> Goes to magnetic switch

And that should be all you really need to do.

One item of note, is that GPIO 14 & 15 may toggle on boot because they are used for console output/input. This behavior can be disabled in raspi-config.

Interfacing Options -> Serial -> Would you like a login shell to be accessible over serial? No

If that doesn't appeal to you, I can still make the changes to the Garage Zero v1 code, but will probably be at least this weekend before I get a chance to work on it.

Thanks!

I actually tried V2 with the exact hardware setup you suggested earlier. I ran into the door being triggered on device reboot, as well as notifications not being saved. I reverted back to keep the house secure.
Thank you for maintaining this!

I actually tried V2 with the exact hardware setup you suggested earlier. I ran into the door being triggered on device reboot, as well as notifications not being saved. I reverted back to keep the house secure. Thank you for maintaining this!

Got it. I think the issue with the door triggering on reboot is due to GPIO 14 & 15. If you move to another GPIO, this shouldn't happen anymore. Or you could disable the serial interface on those pins and that should also help. As for the notifications, not exactly sure what's going on there. Regardless, let me look into updating the original garage zero this weekend and hopefully it's not too bad. Might need your help to test it out and make sure it's good to go.

Working on this in the development branch... should push soon, but will definitely need you to test because I don't have this setup with real hardware.

I actually tried V2 with the exact hardware setup you suggested earlier. I ran into the door being triggered on device reboot, as well as notifications not being saved. I reverted back to keep the house secure. Thank you for maintaining this!

OK, that wasn't too bad. Added this to the development branch for you to check out. Link to the commit is here: 1dcaea2

First, you'll need to pull down the development branch on your instance. SSH into your Pi, then navigate to the garage zero folder:

$ cd ~/garage-zero

Next, stop all of the currently running garage-zero services:

$ supervisorctl stop all

Then you will want to fetch the latest from github and change the branch to development:

$ git pull
$ git checkout development

Assuming that goes well, you'll need to backup your settings.json file, or delete it. Unfortunately, there are some updates that require it to be regenerated. This means you will need reset your settings in the UI.

$ sudo mv settings.json settings.backup

Then, reboot and test!

$ sudo reboot

Once you have rebooted, go to your browser and bring up the garage-zero WebUI. Go to the admin/settings screen and enable the API. Then in the API card, click the link to show the example Home Assistant YAML file. Copy this information (confirm the IP address is correct) into your Home Assistant YAML file. Check the configuration in Home Assistant and make sure you restart Home Assistant (this is important, because otherwise it may not proper install the cover components). You should then be able to go to your dashboard and add the Garage Door entity.

Please test and let me know how it goes. If it's all good, I will move this to the main branch for all to benefit from.

If the mood strikes you, you can feel free to gift me what you think is fair here: https://paypal.me/benparmeter

Good luck!

Works flawlessly! Thank you for integrating the capability.

Outstanding! You are very welcome and thanks for contributing to the wine fund. I'll go ahead and merge this into the main branch.

I have setup Home Assistant and integrated it into Google Assistant. The only issue I am having is that it does not check if the garage door is open or closed before running the command. So if the garage door is closed and you tell google to close the garage door it will open the door. Is there a way to remedy this?

@silentfire619 - This is likely to be a Home Assistant configuration thing. What card are you using to control your garage door? I'm using a Mushroom card which will disable the close/open button depending on state.
image
However, as we know, there is technically only one button, so it's up to Home Assistant to decide how to display it.

Capture

This is what I am using.

Oh man, that's a good catch! I may have to disable this entity on Google Assistant until I can figure out how to remedy this. Anyone could open this with their voice without a passcode. :(

Capture
So I found out that when that is added to Google Assistant that it does not work at all. What is opening and closing the door is the switch not the cover.

So I found out that when that is added to Google Assistant that it does not work at all. What is opening and closing the door is the switch not the cover.

Hmm... I don't have my switch exposed to Google, just the cover. But I found a fix for the cover in the HA community and have updated and tested my configuration.

In the cover template, I've added some logic to check if the cover is closed already on the 'close_cover' command. This will only activate the switch if it is already in a closed state. This fixes the issue for me.

# Cover Template for Garage Door
cover garagedoor:
  - platform: template
    covers:
      garage_door:
        device_class: garage
        friendly_name: "Garage Door"
        value_template: "{{ states('sensor.garage_door') }}"
        open_cover:
          - service: switch.turn_on
            target:
              entity_id: switch.garage_door
        close_cover:
          - service: >- 
              {% if states('sensor.garage_door') == 'open' %}
                switch.turn_off
              {% endif %}
            target:
              entity_id: switch.garage_door
        stop_cover:
          service: switch.turn_on
          target:
            entity_id: switch.garage_door
        icon_template: >-
          {% if states('sensor.garage_door') == 'open' %}
            mdi:garage-open
          {% else %}
            mdi:garage
          {% endif %}

The key change is this:

        close_cover:
          - service: >- 
              {% if states('sensor.garage_door') == 'open' %}
                switch.turn_off
              {% endif %}

Definitely remove the switch from your Google Assistant settings in Home Assistant:
image

Make sure only the Cover is exposed, and then tell your Google Assistant 'Synch all my devices' to make sure it's synched up properly. Hope that helps!

I have made the changes but now I cannot open or close the garage door. Which is the same thing that happened to me previously when I just added the cover.

Can you send me your YAML that you are using in the configuration.yaml file for the sensor, switch and cover? Remember to obscure the API Key, if you have one.

homeassistant: 
  external_url: https://xxx.xxxxx.org
  internal_url: http://192.168.1.xxx:8123
  
http:
  ssl_certificate: /ssl/fullchain.pem
  ssl_key: /ssl/privkey.pem
  ip_ban_enabled: true
  login_attempts_threshold: 5
  
google_assistant:
 project_id: garage-xxxxx
 service_account: !include SERVICE_ACCOUNT.json
 secure_devices_pin: "####"
 report_state: true
  
# Loads default set of integrations. Do not remove.
default_config:

# Load frontend themes from the themes folder
frontend:
  themes: !include_dir_merge_named themes

# Text to speech
tts:
  - platform: google_translate

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml

# Sensor garage_door
sensor garage_door:
  - platform: rest
    scan_interval: 30
    resource: http://192.168.1.x/api/xxxxxxxxxxxxxxxxxx
    name: "Garage Door Sensor"
    value_template: "{{ value_json['Garage Door']['status']['limitsensorclosed'] }}"

# Switch garage_door 
switch garage_door:
  - platform: rest
    name: "Garage Door Switch"
    resource: http://192.168.1.x/api/xxxxxxxxxxxxxxxxxx
    scan_interval: 30
    body_on: '{"DoorButton" : "Garage Door"}'
    body_off: '{"DoorButton" : "Garage Door"}'
    is_on_template: "{{ value_json['Garage Door']['status']['limitsensorclosed'] }}"
    headers:
      Content-Type: application/json
    verify_ssl: false
    
# Cover Template for Garage Door
cover garagedoor:
  - platform: template
    covers:
      garage_door:
        device_class: garage
        friendly_name: "Garage Door Cover"
        value_template: "{{ states('sensor.garage_door') }}"
        open_cover:
          - service: switch.turn_on
            target:
              entity_id: switch.garage_door
        close_cover:
          - service: >- 
              {% if states('sensor.garage_door') == 'open' %}
                switch.turn_off
              {% endif %}
            target:
              entity_id: switch.garage_door
        stop_cover:
          service: switch.turn_on
          target:
            entity_id: switch.garage_door
        icon_template: >-
          {% if states('sensor.garage_door') == 'open' %}
            mdi:garage-open
          {% else %}
            mdi:garage
          {% endif %}

Hate to be a bother, but could you put that code between the code tags? Example:

```yaml

Your code goes here.

```

YAML has very particular formatting with indentations, so it make a difference looking at the proper formatting.

Not a bother at all. I have edited the original post with the code. I appreciate all your help!

Honestly, this YAML looks perfectly fine to me. I would restart the Home Assistant server, perhaps manually, to reload all of the elements (i.e. cover integrations). This can sometimes be the culprit when things are misbehaving.

Ok thank you for you help. I will mess around with this more tomorrow.

Ok thank you for you help. I will mess around with this more tomorrow.

Sounds good. Good luck and let me know if you discover anything. Home Assistant can sometimes be infuriating, until it works.

So I have removed all the code, unlinked Home Assistant from Google Assistant, updated Home Assistant, added the code back in with your change, and linked Home Assistant. I have only added the cover to Google and now the door opens and closes but I am back at the original problem where the door will open if it is told to close while being closed already.

So I have removed all the code, unlinked Home Assistant from Google Assistant, updated Home Assistant, added the code back in with your change, and linked Home Assistant. I have only added the cover to Google and now the door opens and closes but I am back at the original problem where the door will open if it is told to close while being closed already.

Hmm... and we are sure it's only the cover that is exposed to Google Assistant? Same code as above? It shouldn't execute the command switch.turn_off if the sensor is open. Maybe check your developer tools, to make sure that the sensor is reporting closed when the door is closed.

image

I was mistaken it is working now. When I was testing it I told Google to close the garage door as pretty much as soon as it closed.

I was mistaken it is working now. When I was testing it I told Google to close the garage door as pretty much as soon as it closed.

Woohoo! Success. Thanks for pointing this out. Huge security concern. BTW... I have updated the repo with the new YAML template. I've also applied the same fix to the pause function.

You are welcome and thank you for the help and everything you do.

You are welcome and thank you for the help and everything you do.

You are welcome! Happy to help.