MisterWil / abodepy

A thin Python wrapper for the Abode alarm API
MIT License
49 stars 17 forks source link

List and Activate/Deactivate CUE Automations #41

Closed ontl closed 4 years ago

ontl commented 5 years ago

Are the new CUE Automations built in such a way that it would be possible to list and activate/deactivate them similar to how legacy automations work? Or are they not accessible via API?

shred86 commented 4 years ago

Edit: Disregard, see the post below!

~I looked into this yesterday and it doesn't appear CUE automations are accessible like the legacy automations were.~

MisterWil commented 4 years ago

They are, I think. The old automation's were at the https://my.goabode.com/api/v1/automation url.

I set up some CUE automation's and they're available via the https://my.goabode.com/integrations/v1/automations endpoint with a response of:

[ 
   { 
      "name":"Auto Away",
      "enabled":true,
      "version":2,
      "id":"e064cdd5643943828c0034aa28f8c82c",
      "subType":"",
      "actions":[ 
         { 
            "directive":{ 
               "trait":"panel.traits.panelMode",
               "name":"panel.directives.arm",
               "state":{ 
                  "panelMode":"AWAY"
               }
            }
         }
      ],
      "conditions":{ 

      },
      "triggers":{ 
         "operator":"OR",
         "expressions":[ 
            { 
               "mobileDevices":[ 
                  "3212",
                  "30197"
               ],
               "property":{ 
                  "trait":"mobile.traits.location",
                  "name":"location",
                  "rule":{ 
                     "location":"920",
                     "equalTo":"LAST_OUT"
                  }
               }
            }
         ]
      }
   },
   { 
      "name":"Auto Home",
      "enabled":true,
      "version":2,
      "id":"654087b9fbf946758d2c22843eaa19bf",
      "subType":"",
      "actions":[ 
         { 
            "directive":{ 
               "trait":"panel.traits.panelMode",
               "name":"panel.directives.disarm"
            }
         }
      ],
      "conditions":{ 

      },
      "triggers":{ 
         "operator":"OR",
         "expressions":[ 
            { 
               "mobileDevices":[ 
                  "3212",
                  "30197"
               ],
               "property":{ 
                  "trait":"mobile.traits.location",
                  "name":"location",
                  "rule":{ 
                     "location":"920",
                     "equalTo":"FIRST_IN"
                  }
               }
            }
         ]
      }
   },
   { 
      "name":"Lock when Armed",
      "enabled":true,
      "version":2,
      "id":"346f8612013946ae8bb344945f74fef5",
      "subType":"",
      "actions":[ 
         { 
            "directive":{ 
               "trait":"device.traits.lockUnlock",
               "name":"device.directives.lock"
            },
            "devices":[ 
               "ff768e78c604bc6269257ea59a26bb20",
               "a1c734ef94a8e900465614432da28dbc",
               "6997e48db6af871e9bd5015f9f84d64d"
            ]
         }
      ],
      "conditions":{ 

      },
      "triggers":{ 
         "operator":"OR",
         "expressions":[ 
            { 
               "property":{ 
                  "trait":"panel.traits.panelMode",
                  "name":"panelMode",
                  "rule":{ 
                     "equalToAny":[ 
                        "AWAY",
                        "HOME"
                     ],
                     "modifier":{ 
                        "timerState":"EXIT_TIMER_STOPS"
                     }
                  }
               }
            }
         ]
      }
   }
]

Enabling an automation sends a PATCH request to https://my.goabode.com/integrations/v1/automations/e064cdd5643943828c0034aa28f8c82c which is the ID of the automation, with a body of:

{"enabled":false}

and the response is

{ 
   "name":"Auto Away",
   "enabled":false,
   "version":2,
   "id":"e064cdd5643943828c0034aa28f8c82c",
   "subType":"",
   "actions":[ 
      { 
         "directive":{ 
            "trait":"panel.traits.panelMode",
            "name":"panel.directives.arm",
            "state":{ 
               "panelMode":"AWAY"
            }
         }
      }
   ],
   "conditions":{ 

   },
   "triggers":{ 
      "operator":"OR",
      "expressions":[ 
         { 
            "mobileDevices":[ 
               "3212",
               "30197"
            ],
            "property":{ 
               "trait":"mobile.traits.location",
               "name":"location",
               "rule":{ 
                  "location":"920",
                  "equalTo":"LAST_OUT"
               }
            }
         }
      ]
   }
}
shred86 commented 4 years ago

Oh shoot, you're right - I just checked again and sure enough, I'm seeing the same thing. Well, I just spent a little bit of time messing around with it. It's obviously fairly easy to get the on/off functionality working, but what I'm noticing is there's nothing being sent from the SocketIO side, so when I enable/disable it via Home Assistant, the switch position doesn't save its new state since there's no event to set the new state.

So if I'm understanding this right, we really need a way to set the device state in Home Assistant using the response message. If we could do that, I think it could also apply to every other switch and light as there's currently a small delay from switching something on/off to seeing the device state in HA correctly reflected (I'm suspecting because it's waiting for the socketio message).

MisterWil commented 4 years ago

abodepy already does that: https://github.com/MisterWil/abodepy/blob/v0.16.5/abodepy/devices/switch.py#L10-L17

So I suspect its the HASS devices that are waiting for the event.

shred86 commented 4 years ago

If I'm reading that right, abodepy is updating the device self._json_state['status'] but I guess the issue is on the Home Assistant side - I don't think it's using the return to set the entity state in HA. From switch.py in the Abode component in HA:

def turn_on(self, **kwargs):
        """Turn on the device."""
        self._device.switch_on()

Hmm... so really just need a way to set the device state immediately in HA if abodepy returns something other than None I suppose. Or maybe it already does and I'm just thinking about this completely wrong. :)

Edit: Can't seem to figure it out after messing around for a bit. However, there doesn't appear to be a socketio event if you enable/disable the automation from the Abode web UI. Obviously will result in it being out of sync until the automations are refreshed, but that's a pretty niche case I'm not too worried about (plus if you're using HA, you're probably not using Abode's UI, lol).

shred86 commented 4 years ago

So I've started working on this but I'm not sure what the best way to implement it will be. Both legacy automations and quick actions are going away. The way to do "quick actions" with CUE is simply create an automation with no triggers, and manually trigger it from the Abode mobile/web app.

While we can keep the same concept of using switches for Abode automations in Home Assistant, there is a chance the automation states may become out of sync since there's no web socket event that gets pushed when the automation is enabled/disabled. Edit: Actually, disregard. With no Abode events being pushed, I don't think there's an (easy) way to set the switch state correctly, even after toggling the switch on/off.

The other option is to create two Abode services in Home Assistant for enabling and disabling automations. If we do this, then the plan would be to add automations as binary sensors similar to what is being done with quick actions right now. This is currently how I have it implemented and it seems to work fine. Binary sensors still have a state (on/off) so the same issue applies as with switches, it's just less noticeable.

shred86 commented 4 years ago

JSON response of timeline event when a CUE automation is triggered both manually or automatically (for reference):

{
    "mac": "<rescinded>",
    "id": "1183637320",
    "xml": null,
    "date": "02/02/2020",
    "time": "06:55 PM",
    "event_utc": "1580698522",
    "event_cid": "",
    "event_code": "5206",
    "device_id": null,
    "device_type_id": "",
    "device_type": "",
    "timeline_ha_device": "Test",
    "d_name": null,
    "delete_by_user": null,
    "pin_code_user": " ",
    "file_del_at": "",
    "nest_has_motion": null,
    "nest_has_sound": null,
    "nest_has_person": null,
    "neaz": null,
    "hasFaults": "0",
    "file_path": "",
    "deep_link": null,
    "file_name": "",
    "file_size": "",
    "file_count": "",
    "file_is_del": "0",
    "event_type": "Automation",
    "severity": "8",
    "pos": "l",
    "color": "#000000",
    "is_alarm": "0",
    "triggered_by_str": "",
    "ha_type": "manual",
    "ha_device_name": null,
    "ha_location": null,
    "ha_mobile": null,
    "ha_cond": null,
    "h_location": null,
    "ha_trigger": null,
    "icon": "assets/email/automtion_v2.png",
    "user_id": "<redacted>",
    "user_name": "Home",
    "mobile_name": "",
    "parent_tid": "",
    "app_type": null,
    "viewed_by_uid": null,
    "verified_by_tid": null,
    "la_applied_by": null,
    "la_event_type": null,
    "la_culprit_mobiles": null,
    "la_executed": null,
    "la_applied_at": null,
    "device_name": "Test",
    "event_name": "Automation : Test",
    "event_by": null,
    "file_delete_by": ""
}