mikejac / node-red-contrib-google-smarthome

A collection of Node-RED nodes to control your smart home devices via Google Assistant.
GNU General Public License v3.0
119 stars 38 forks source link

[request] support for Security System device + Secondary User Verification #208

Closed nostroff closed 2 years ago

nostroff commented 2 years ago

Hello.

First, a sincere thanks for the excellent work.

Second, would you please consider adding support for the Security System device type (see: https://developers.google.com/assistant/smarthome/guides/securitysystem) with PIN challenge verification (see: https://developers.google.com/assistant/smarthome/develop/secondary-user-verification#request)? Support for multiple arming levels is not important (at least for me).

Please note that basic arm/disarm functionality can use the already implemented Switch device (where disarmed = off and armed = on). The hard part is how to support secondary user verification, which should probably be done in a generic manner. For example, possibly enhancing the properties for all devices to include a pull down item labelled "Secondary Verification" with options "None", "Ack Needed" and "PIN needed" (where the user would also enter the PIN value).

Paul-Reed commented 2 years ago

+1 for PIN challenge verification. I discussed this feature with a colleague recently to prevent his garage door being inadvertently opened.

FireWizard52 commented 2 years ago

@nostroff

The Security System is supported in the Google Device node, however this does not support PIN verification. Of course in principle a Security device is a switch, switching between armed and disarmed. So this can be done with a Switch device. I think, most people will need at least two alarm levels (armed_home and armed away). I think the PR of @ckhmer1 will solve this.

I think your issue is how to configure the Google Device node. In principle the Google device node can handle almost everything but this node is undocumented and it depends in this case on the contents of the file "availableArmLevels.json"

I use 2 Alarm levels and have it in 2 languages. (English and Dutch) See picture:

Screenshot_Google_Device_security

The contents of the availableArmLevels.json is as follows:

[
    {
        "level_name": "L1",
        "level_values": [
            {
                "level_synonym": [
                    "armed_home",
                    "SL1"
                ],
                "lang": "en"
            },
            {
                "level_synonym": [
                    "thuis en ingeschakeld",
                    "SL1"
                ],
                "lang": "nl"
            }
        ]
    },
    {
        "level_name": "L2",
        "level_values": [
            {
                "level_synonym": [
                    "armed_away",
                    "SL2"
                ],
                "lang": "en"
            },
            {
                "level_synonym": [
                    "afwezig en ingeschakeld",
                    "SL2"
                ],
                "lang": "nl"
            }
        ]
    }
]

Also for me are a number of things still unclear.

  1. What does Ordered arm levels mean? What is it intended use?
  2. Why does the status under the node indicate "unknown"?
  3. I also noticed that "If msg arrives on input, pass through to output:" does not function and I have seen that in other nodes as well.

Perhaps we can improve this Device node, as it has a lot of potential Have a look to Smartnora, which has al this functionality included.

Paul-Reed commented 2 years ago

Just patched the Secondary user verification PR and works great here. It's also very well implemented, and easy to setup and use. Thanks @ckhmer1 for implementing.

ckhmer1 commented 2 years ago

Thanks, I'll use it to switch on and off with Pin my 3D printer, in this way I don't risk to switch off by mistake.

I know I have to improve documentations, i have in my to-do list

Paul-Reed commented 2 years ago

I've created a post in the node-RED forum - https://discourse.nodered.org/t/node-red-contrib-google-smarthome-user-verification-feature/55355 to let other users know.

nostroff commented 2 years ago

@Paul-Reed - Your responsiveness to this request is amazing. The updated node has been installed and tested.

Test result summary:

Suggested follow-up:

  1. Verify PIN feature for a Switch device type when using the Google Home app.
  2. Verify Security system device type (with or without the PIN feature) status is correctly displayed on Node-RED UI.

Thanks again for the awesome turn-around. Please let me know if you would like any help with documentation.

Detailed test results:

  1. Successfully added a "Google Device" type Switch with a PIN. User interface looks great.
  2. Then used Google Voice Assistant to turn the switch on and off and was prompted for a PIN - worked perfectly.
  3. Next, tried to use the Google Home Android app to turn the switch on and off and was not prompted for a PIN - UI on app showed the switch state changed (which was not correct). /var/log/syslog contents are as follows (for privacy, asterisks replace personal information): Dec 17 20:17:25 Node-RED[5805]: HttpActions:httpActionsRegister(/smarthome): request.headers = {"content-type":"application/json;charset=UTF-8","google-assistant-api-version":"v1","authorization":"Bearer **********","host":"**********.com:3003","content-length":"284","connection":"keep-alive","user-agent":"Mozilla/5.0 (compatible; Google-Cloud-Functions/2.1; +http://www.google.com/bot.html)","accept-encoding":"gzip, deflate, br"} Dec 17 20:17:25 Node-RED[5805]: HttpActions:httpActionsRegister(/smarthome): reqdata = {"inputs":[{"context":{"locale_country":"US","locale_language":"en"},"intent":"action.devices.EXECUTE","payload":{"commands":[{"devices":[{"id":"**********"}],"execution":[{"command":"action.devices.commands.OnOff","params":{"on":true}}]}]}}],"requestId":"**********"} Dec 17 20:17:25 Node-RED[5805]: HttpActions:httpActionsRegister(/smarthome): user: **********@gmail.com Dec 17 20:17:25 Node-RED[5805]: HttpActions:httpActionsRegister(/smarthome): EXECUTE Dec 17 20:17:25 Node-RED[5805]: HttpActions:_exec() Dec 17 20:17:25 Node-RED[5805]: HttpActions:_execDevice(): command = {"command":"action.devices.commands.OnOff","params":{"on":true}} Dec 17 20:17:25 Node-RED[5805]: Device:execCommand(): device = {"id":"**********","states":{},"command":"action.devices.commands.OnOff"} Dec 17 20:17:25 Node-RED[5805]: google-smarthome:DeviceNode[Security System] .execCommand: command {"command":"action.devices.commands.OnOff","params":{"on":true}} Dec 17 20:17:25 Node-RED[5805]: google-smarthome:DeviceNode[Security System] .execCommand: states {"online":true,"on":false} Dec 17 20:17:25 Node-RED[5805]: Device:execCommand(): result = {"status":"ERROR","errorCode":"challengeNeeded","challengeNeeded":{"type":"pinNeeded"}} Dec 17 20:17:25 Node-RED[5805]: HttpActions:_exec(): executionResponse = {"status":"ERROR","errorCode":"challengeNeeded","challengeNeeded":{"type":"pinNeeded"}} Dec 17 20:17:25 Node-RED[5805]: HttpActions:_exec(): no execution states were found for this device Dec 17 20:17:25 Node-RED[5805]: HttpActions:_exec(): resBody = {"requestId":"**********","payload":{"commands":[{"ids":["**********"],"status":"ERROR","errorCode":"challengeNeeded","states":{},"challengeNeeded":{"type":"pinNeeded"}}]}} Dec 17 20:17:25 Node-RED[5805]: #033[0mPOST /smarthome #033[32m200#033[0m 12.665 ms - 188#033[0m
  4. Status on Node-RED UI for a Security system device type always shows "Unknown". /var/log/syslog contents are as follows (for privacy, asterisks replace personal information): Dec 17 19:40:24 Node-RED[5805]: Device:setStates(): deviceId = "**********" Dec 17 19:40:24 Node-RED[5805]: google-smarthome:DeviceNode[Alarm] .input: topic = undefined Dec 17 19:40:24 Node-RED[5805]: google-smarthome:DeviceNode[Alarm] .input: some other topic Dec 17 19:40:24 Node-RED[5805]: google-smarthome:DeviceNode[Alarm] .updateState: set "currentArmLevel" to "L2" Dec 17 19:40:24 Node-RED[5805]: google-smarthome:DeviceNode[Alarm] .updateState: new State true {"online":true,"isArmed":false,"currentArmLevel":"L2"} Dec 17 19:40:24 Node-RED[5805]: Devices:SetState(): state = {"online":true,"isArmed":false,"currentArmLevel":"L2"} Dec 17 19:40:24 Node-RED[5805]: HttpActions:reportState(): deviceId = ********** Dec 17 19:40:24 Node-RED[5805]: HttpActions:reportState(): states = {"online":true,"isArmed":false,"currentArmLevel":"L2"} Dec 17 19:40:24 Node-RED[5805]: HttpActions:reportState(): postData = {"requestId":"**********","agentUserId":"0","payload":{"devices":{"states":{"**********":{"online":true,"isArmed":false,"currentArmLevel":"L2"}}}}}
Caprico85 commented 2 years ago

Released v0.1.15 including @ckhmer1's PR.

Paul-Reed commented 2 years ago

@Paul-Reed - Your responsiveness to this request is amazing.

I wish!! The credit belongs to @ckhmer1 & @Caprico85

I never use the 'Home' app, but I'm seeing the same as @nostroff which he describes in point 3)

ChutneyMary commented 2 years ago

I've tested the Challenge type "Ack needed" and have some intermittent issues.

Turning a switch ON is typically 100% successful with acknowledgement.

Turning a switch OFF sees a habit of Google saying "Are you sure you want to turn OFF the XYZ"?

I say - "Yes"

Google says "Turning XYZ ON".

The item remains on.

ckhmer1 commented 2 years ago
  • Why does the status under the node indicate "unknown"?
  • I also noticed that "If msg arrives on input, pass through to output:" does not function and I have seen that in other nodes as well.

I've sent a new PR fixing the following points:

From the docs Smart Home ArmDisarm Trait Schema docs ordered means:

_

If set to true, additional grammar for increase/decrease logic applies, in the order of the levels array. For example, "Hey Google, increase my security level by 1", results in the Assistant determining the current security level and then increasing that security level by one. If this value is set to false, additional grammar for increase/decrease logic is not supported.

_

lu4t commented 2 years ago

First of al: congrats for the great work!.

As I was trying this out, I was thinking of the following use case mixing the features of two nodes. It could be applied to prevent the PIN getting leaked... if you enroll your whatsapp number with this node: https://flows.nodered.org/node/node-red-contrib-whin you could receive a PIN on your whatsapp, randomly generated everytime you trigger an event that needs your authorization.

Just an idea... keep on with the inspiring work!

ckhmer1 commented 2 years ago

First of al: congrats for the great work!.

As I was trying this out, I was thinking of the following use case mixing the features of two nodes. It could be applied to prevent the PIN getting leaked... if you enroll your whatsapp number with this node: https://flows.nodered.org/node/node-red-contrib-whin you could receive a PIN on your whatsapp, randomly generated everytime you trigger an event that needs your authorization.

Just an idea... keep on with the inspiring work!

Thanks, I'm happy that someone uses the Google Device node.

I've sent an update of the PR, with this update, the node sends in output a message with the current pin when a PIN user verification is needed.

This message has the topic configured in the node and in the payload the following attributes:

name: the name configured in the node. pin: the actual pin command: the command invoked. In this way, You can build a message to send to Telegram (I don't like WhatsApp) with all the info needed.

I've set in my flow a delay to 20 seconds, after this time a new pin is generated and a message is sent in input to the node, The message to change the pin has the topic with value 'SetChallengePIN' the payload with the following attributes:

pin: the new pin to set command: the command taken from the output message before.

This allows the flow to change the PIN.

Paul-Reed commented 2 years ago

Quick question; is the payload.pin a string or a number (thinking about leading zeros - "0023", or should pin's be a number and always start with 1-9 for example 1023)

ckhmer1 commented 2 years ago

It is a string, it can have leading zeros

nostroff commented 2 years ago

Follow-up thoughts/suggestions...

  1. Heartfelt appreciation to the project contributors - you exemplify successful collaborative software development. Please feel free to close the issue, or if you prefer, I'm happy to close the issue.

  2. As a newbie on using node-red-contrib-google-smarthome, my experience is that the learning curve would be easier if there were only 2 nodes: Management and Google Device. I'm guessing there's history behind the device type-specific nodes, but it seems needlessly confusing for a new user. Perhaps I'm missing something. If not, please consider cleaning up the unnecessary redundancy by removing the device type-specific nodes.

  3. The set_state management message could use some attention. To ensure the Google Home Graph has accurate state for my devices, my flow sends a set_state message whenever the Management node payload = start, as shown below (yes, it's a bit complicated because I'm controlling devices in a house and a cabin where each location loops through getting state from each of my devices to construct the set_state message payload):

image

Currently, the set_state message is not well documented. Also, it's awkward to use as it requires the id value instead of the device name. IMHO, it would be easier if the device type/name were used since these values are assigned by the user and would be more obvious (the id is an obscure value that is automagically assigned). This suggestion would likely resolve issue #205 "Devices don't update in google home immediately without restarting flows".

  1. Regarding the PIN being a dynamic value... that seems very clever. Rather than relying on WhatsApp or Telegram, you may want to consider relying on the Google Authenticator app to provide 2 factor authentication. Perhaps integrating parts of https://flows.nodered.org/node/node-red-contrib-google-oauth2 into this project (either using the existing Google Project Settings Client ID and Client Secret, or adding a second pair of Client ID/Client Secret values specific to 2 factor authentication of PIN-based secondary user verification). From the UI, a user could simply select Challenge type = "Two factor PIN needed". The motivation for this suggestion is to streamline the user experience as it already relies on Google Voice Assistant and Google Home - adding a dependency on Google Authenticator seems more natural than relying on WhatsApp or Telegram.
ckhmer1 commented 2 years ago

Hi,

  1. Thanks, I(we)'ll try to do as much as possible to improve the plugin.

  2. The first nodes were device-specific nodes. I've created the Google Device node after a user request, including all the Google devices and traits. I agree with You, we should remove the older nodes and leave only the Management and Google device nodes. We need to improve the Google device documentation and but there are still several users using the other nodes.

  3. The set_state message was built as a complement of the get_state message to allow to save the state to persistent storage and replace it back on restart. I've updated my last PR in order to allow also the device name.

  4. The way to generate the PIN should be outside the Google Device node. When Google asks You the PIN the node sends the message ChallengePIN with the actual PIN, You can use this trigger to get the PIN from the authentication system and set it back to the node, like the following flow:

image

nostroff commented 2 years ago

Thanks for the wonderful response!

Caprico85 commented 2 years ago

Regarding the old device nodes:

I totally agree. I thought about removing them too. Even more after trying to migrate the old device nodes to use the new Google device as base class (#88). That's a lot of work trying to replicate all the old inputs and outputs.

I currently working on adding " (deprecated)" to the name of each device. I'll also add some deprecation notices to the device config and the Readme. After some weeks or months, when hopefully everyone has updated, we can remove the old nodes.

MuadDibVV commented 2 years ago

Hello, thanks for your great job ! Is the security system device concerned by : "Some devices can be controlled via voice, but not via Google Home App. For example windows and sensors. These devices only show a general page with their room assignments in the app, but they don't show their current state or buttons to control it. There is nothing we can do about it, this has to be implemented by Google." ? I implement it and can do nothing with the application, only with voice ? In general, where can we find this type of information for each device ?