本节利用三星Smartthings Classic物联网平台的web service smartapp,实现了一个Alexa智能家居skill的例子,由此来了解Alexa是如何控制其他云的智能家居设备的。
三星Smartthings平台是如何运行第三方云来控制其设备的
三星Smartthings Classic支持开发者自己编写SmartApp来控制智能家居设备。参考官网中Web Service SmartApps的教程就可以写一个允许使用Web API来远程控制该平台设备的SmartApp。简单来说,SmartApp是Groovy写的运行在Smartthings云上的沙盒中代码,该代码被用户安装得到授权后可以操作、监听用户的设备,并且允许向外自定义开放URL,即开发者可以用代码在SmartApp中处理发过来的HTTP请求参数,进而自定义控制设备;同时,SmartApp也可以自定义响应请求返回设备状态,甚至发送HTTP请求主动给Alexa上报设备状态。
那么,三星如何验证发来的消息呢?答案是使用Oauth。Web Service SmartApps在创建时会有OAuth的Client ID和Secret,使用这两个参数来向三星特定的URL请求获得access token,就可以向该SmartApp开放的URL发送消息了。在OAuth的时候,会让用户选择允许该token访问哪些设备资源。Smartthings还允许创建虚拟设备,所以测试起来非常方便,过多不赘述,详见官网。
Alexa中Skill是如何向其注册设备、控制设备的
亚马逊给出了一个Python的Smart home skill例子,并且有详细的说明,其中用到的AWS服务也都有免费额度的,不用担心扣钱。
- Alexa Smart Home Skill创建时首先需要设置好OAuth的信息,例如Authorization URI、Access Token URI、Client ID、Client Secret、Scope等,这些都可以从Smartthing的文档中找到。Alexa云会在用户enable skill的时候自动完成OAuth流程,不需要开发者自己来实现OAuth流程,同时,token也返回给了Alexa云。Skill只有在接到用户intent的时候,才会收到由Alexa云发来的对应的access token。
- 设备发现:在用户enable并关联账号后,首先会进入设备发现步骤,skill要把被控云(Smartthing)上该用户都有什么设备报告给Alexa云,换句话说,两个云的设备要有一个身份的映射,这样用户只用Alexa的App就可以看到他各种品牌的物联网设备的状态了。Alexa在设备发现时会发送
Discover
命令给Skill,并携带token。Skill这时候拿着token去SmartApp开放的URL去查询都有哪些设备,然后根据得到的内容回复如下内容给Alexa,关键的有这么几个:- endpointId:设备的唯一标识号。应该在该用户的skill中唯一,类似于设备ID。
- friendlyName:用户在Alexa App中看到的设备的名字。测试发现Alexa App中有一个BUG,friendlyName若重名,在Alexa App中显示面板中后发现的设备会覆盖掉之前同名的设备,用户没有方法分辨。因此,恶意的skill就有机会伪造用户之前的已发现的设备的状态,但是也称不上一个安全漏洞。
- manufacturerName、description:Alexa App中看到的设备详细信息,可以随意填写,随意伪造。导致恶意Skill可以在Alexa中随便号称该设备就是Smartthing生产的,结合伪造的friendlyName,使用户完全无法分辨真实skill上报的设备是否被恶意顶替了。
- displayCategories:说明设备的类型,必须是Alexa预定义的类型之一。
- capabilities:设备支持的能力,如开关,亮度,以及该能力是否可被主动询问获得,等等。这也是Alexa预定义好的。
- 控制与消息上报 在Echo收到用户的语音命令后(Smart home语音命令不能被定制),Alexa会发送特定的命令(directive),命令中携带了要操作的设备的唯一 标识endpoint以及用户在被控云的access token,skill程序只要向被控云特定的URL接口发送指令即可。 SmartApp也可以在获得了用户的亚马逊token后,向特定的event结点主动报告更新设备的状态。
{
"directive": {
"header": {
"namespace": "Alexa.Discovery",
"name": "Discover",
"payloadVersion": "3",
"messageId": "1bd5d003-31b9-476f-ad03-71d471922820"
},
"payload": {
"scope": {
"type": "BearerToken",
"token": "access-token-from-skill"
}
}
}
}
代码语言:javascript复制{
"event": {
"header": {
"correlationToken": "12345692749237492",
"messageId": "1bd5d003-31b9-476f-ad03-71d471922820",
"name": "Discover.Response",
"namespace": "Alexa.Discovery",
"payloadVersion": "3"
},
"payload": {
"endpoints": [
{
"endpointId": "demo_id",
"manufacturerName": "Smart Device Company",
"friendlyName": "Bedroom Outlet",
"description": "Smart Device Switch",
"displayCategories": ["SWITCH"],
"cookie": {
"key1": "arbitrary key/value pairs for skill to reference this endpoint.",
"key2": "There can be multiple entries",
"key3": "but they should only be used for reference purposes.",
"key4": "This is not a suitable place to maintain current endpoint state."
},
"capabilities": [
{
"type": "AlexaInterface",
"interface": "Alexa",
"version": "3"
},
{
"interface": "Alexa.PowerController",
"version": "3",
"type": "AlexaInterface",
"properties": {
"supported": [
{
"name": "powerState"
}
],
"retrievable": true
}
}
]
}
]
}
}
}
关于设备身份映射的解释
虽然恶意skill有可能在Alexa App中顶替到其他skill创建的设备,但是用户在Web控制页面和设置routine时能够看到是两个不同的设备。通过查看web页面的网络流量,发现Alexa在真正标识设备时加入了skill的id作为前缀(base64编码)来防止恶意skill之间冲突上报设备信息,Alexa中表示设备信息的数据结构见附录(从浏览器调试中获得)。
另外还有一个小问题是用户语音UI如何准确的翻译到要控制哪个设备,如有相似或同名,似乎Alexa会额外询问到底要选择控制哪一个,这点没有深入测试。
代码语言:javascript复制
附录代码
Smartapp
代码语言:javascript复制/**
* My web smartapp
*
* Copyright 2019 Ascii0x03
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*
*/
definition(
name: " My web smartapp",
namespace: "J_unique_Namespace",
author: "Ascii0x03",
description: "web smartapp for alexa",
category: "My Apps",
iconUrl: "https://img.yuanmabao.com/zijie/pic/2019/05/10/vhrkvlm34bp.png",
iconX2Url: "https://img.yuanmabao.com/zijie/pic/2019/05/10/ypej5zfkh3x.png",
iconX3Url: "https://img.yuanmabao.com/zijie/pic/2019/05/10/ypej5zfkh3x.png")
preferences {
section ("Allow external service to control these things1...") {
input "switches", "capability.switch", multiple: true, required: true
}
}
mappings {
path("/switches") {
action: [
GET: "listSwitches"
]
}
path("/switches/:command") {
action: [
PUT: "updateSwitches"
]
}
path("/switches/:deviceid/:command") {
action: [
PUT: "updateASwitch"
]
}
path("/amazontoken/:accesstoken/:refreshtoken") {
action: [GET: "getAmzToken"]
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
//unsubscribe()
initialize()
}
def initialize() {
// TODO: subscribe to attributes, devices, locations, etc.
subscribe(switches, "switch", eventDetectedHandler)
//subscribe(switch2, "switch.on", eventDetectedHandler)
//subscribe(switch1, "switch.off", eventDetectedHandler)
//subscribe(switch2, "switch.off", eventDetectedHandler)
}
// returns a list like
// [[name: "kitchen lamp", value: "off"], [name: "bathroom", value: "on"]]
def listSwitches() {
def resp = []
//def resp = [value:switch1.currentValue("switch")]
switches.each {
resp << [name: it.displayName, value: it.currentValue("switch")]
}
return resp
}
void updateSwitches() {
// use the built-in request object to get the command parameter
def command = params.command
// all switches have the command
// execute the command on all switches
// (note we can do this on the array - the command will be invoked on every element
switch(command) {
case "ON":
switches.on()
report_state_to_amazon("ON", "switch1")
break
case "OFF":
switches.off()
report_state_to_amazon("OFF", "switch1")
break
default:
httpError(400, "$command is not a valid command for all switches specified")
}
}
void updateASwitch() {
def command = params.command
def deviceid = params.deviceid
switches.each {
if(it.displayName == deviceid) {
switch(command) {
case "ON":
it.on()
report_state_to_amazon("ON", deviceid)
break
case "OFF":
it.off()
report_state_to_amazon("OFF", deviceid)
break
default:
httpError(400, "$command is not a valid command for $deviceid specified")
}
}
}
}
def getAmzToken() {
def accesstoken = params.accesstoken
def refreshtoken = params.refreshtoken
log.debug "accesstoken: $accesstoken"
state.amzaccesstoken = accesstoken
state.amzrefreshtoken = refreshtoken
}
def report_state_to_amazon(state_value, endpoint_id) {
pause(3000)
def amz_url = "https://api.amazonalexa.com/v3/events"
def sensor_value = "DETECTED"
if( state_value == "OFF"){
sensor_value = "NOT_DETECTED"
}
def body = """
{
"context": {
"properties": [
{
"namespace": "Alexa.BrightnessController",
"name": "brightness",
"value": 85,
"timeOfSample": "2017-02-03T16:20:50.52Z",
"uncertaintyInMilliseconds": 60000
}
]
},
"event": {
"header": {
"messageId": "c50bbb73-1ee8-44f8-af9b-19a0a2195474",
"namespace": "Alexa",
"name": "ChangeReport",
"payloadVersion": "3"
},
"endpoint": {
"scope": {
"type":"BearerToken",
"token":"$state.amzaccesstoken"
},
"endpointId" : "$endpoint_id"
},
"payload": {
"change": {
"cause": {
"type": "PHYSICAL_INTERACTION"
},
"properties": [
{
"namespace": "Alexa.PowerController",
"name": "powerState",
"value": "$state_value",
"timeOfSample": "2019-04-16T16:20:50.52Z",
"uncertaintyInMilliseconds": 0
},
{
"namespace": "Alexa.ContactSensor",
"name": "detectionState",
"value": "$sensor_value",
"timeOfSample": "2019-04-16T16:20:50.52Z",
"uncertaintyInMilliseconds": 0
}
]
}
}
}
}
"""
def params = [
uri: amz_url,
headers: ["Authorization":"Bearer " state.amzaccesstoken],
contentType:"application/json",
body:body
]
log.debug state.amzaccesstoken
// try {
httpPost(params) { resp ->
//log.debug "response data: ${resp.statusCode}"
//log.debug "response contentType: ${resp.contentType}"
}
// } catch (e) {
// log.debug "something went wrong sending http to Amazon: $e"
// }
}
// TODO: implement event handlers
def eventDetectedHandler(evt) {
log.debug "DetectedHandler called: $evt"
//log.debug evt.getDevice()
// get the value of this event, e.g., "on" or "off"
//log.debug "The value of this event is ${evt.value}"
if (evt.value == "on") {
report_state_to_amazon("ON", evt.getDevice());
} else {
report_state_to_amazon("OFF", evt.getDevice());
}
// get the Date this event happened at
//log.debug "This event happened at ${evt.date}"
// did the value of this event change from its previous state?
//log.debug "The value of this event is different from its previous value: ${evt.isStateChange()}"
}
Alexa Skill Lambda代码(只贴了lambda_function,其他与git中一致)
代码语言:javascript复制# -*- coding: utf-8 -*-
# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Amazon Software License (the "License"). You may not use this file except in
# compliance with the License. A copy of the License is located at
#
# http://aws.amazon.com/asl/
#
# or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific
# language governing permissions and limitations under the License.
from botocore.vendored import requests
import boto3
import json
from alexa.skills.smarthome import AlexaResponse
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('table_smart_home_skill1')
def lambda_handler(request, context):
# Dump the request for logging - check the CloudWatch logs
print('lambda_handler request -----')
print(json.dumps(request))
if context is not None:
print('lambda_handler context -----')
print(context)
# Validate we have an Alexa directive
if 'directive' not in request:
aer = AlexaResponse(
name='ErrorResponse',
payload={'type': 'INVALID_DIRECTIVE',
'message': 'Missing key: directive, Is the request a valid Alexa Directive?'})
return send_response(aer.get())
# Check the payload version
payload_version = request['directive']['header']['payloadVersion']
if payload_version != '3':
aer = AlexaResponse(
name='ErrorResponse',
payload={'type': 'INTERNAL_ERROR',
'message': 'This skill only supports Smart Home API version 3'})
return send_response(aer.get())
# Crack open the request and see what is being requested
name = request['directive']['header']['name']
namespace = request['directive']['header']['namespace']
# Handle the incoming request from Alexa based on the namespace
if namespace == 'Alexa.Authorization':
if name == 'AcceptGrant':
# Note: This sample accepts any grant request
# In your implementation you would use the code and token to get and store access tokens
grant_code = request['directive']['payload']['grant']['code']
grantee_token = request['directive']['payload']['grantee']['token']
###Send the amazon grant_code
data = {"grant_type":"authorization_code",
"code":grant_code,
"client_id":"amzn1.application-oa2-client.XXX",
"client_secret":"XXX"}
post_data = ""
for key in data:
post_data = post_data key '=' data[key] '&'
headers = {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
r = requests.post('https://api.amazon.com/auth/o2/token', data = post_data, headers = headers)
#print(r.status_code)
if(r.status_code == 200):
print(r.json())
resp = r.json()
access_token = resp['access_token']
refresh_token = resp['refresh_token']
###TODO:Send amazon access_token to SmartThings
smartthings_uri = smartthings_discover_endpoint(grantee_token)
headers = {'Authorization': 'Bearer ' grantee_token}
r = requests.get(smartthings_uri '/amazontoken' '/' access_token '/' refresh_token, headers = headers)
#print("JJJ:SmartThings sent amazon token")
#print(r.status_code)
table.put_item(
Item={
'ItemId': grantee_token,
'amazon_access_token': access_token,
'refresh_token': refresh_token,
}
)
else:
print("JJ:Get access_token Bug!")
return
aar = AlexaResponse(namespace='Alexa.Authorization', name='AcceptGrant.Response')
return send_response(aar.get())
if namespace == 'Alexa.Discovery':
if name == 'Discover':
adr = AlexaResponse(namespace='Alexa.Discovery', name='Discover.Response')
capability_alexa = adr.create_payload_endpoint_capability()
#capability_sensor = adr.create_payload_endpoint_capability()
capability_alexa_powercontroller = adr.create_payload_endpoint_capability(
interface='Alexa.PowerController',
supported=[{'name': 'powerState'}],
proactively_reported = True,
retrievable = True)
capability_ContactSensor = adr.create_payload_endpoint_capability(
type='AlexaInterface',
interface = 'Alexa.ContactSensor',
supported=[{'name':'detectionState'}],
proactively_reported = True,
retrievable = True
)
adr.add_payload_endpoint(
friendly_name='J_smart_sensor_switch',
endpoint_id='switch1',
description='SmartThings Switch1',
display_categories=['SWITCH'],
manufacturer_name='SmartThings_J',
capabilities=[capability_alexa, capability_alexa_powercontroller, capability_ContactSensor]
)
adr.add_payload_endpoint(
friendly_name='J_smart_sensor_switch2',
endpoint_id='switch2',
description='SmartThings Switch2',
display_categories=['SWITCH'],
manufacturer_name='SmartThings_J',
capabilities=[capability_alexa, capability_alexa_powercontroller, capability_ContactSensor]
)
return send_response(adr.get())
if namespace == 'Alexa.PowerController':
# Note: This sample always returns a success response for either a request to TurnOff or TurnOn
endpoint_id = request['directive']['endpoint']['endpointId']
##TODO: lookup smartthings according to id and find status
power_state_value = 'OFF' if name == 'TurnOff' else 'ON'
correlation_token = request['directive']['header']['correlationToken']
token = request['directive']['endpoint']['scope']['token']
# Check for an error when setting the state
smartthing_endpoint = smartthings_discover_endpoint(token)
state_set = smartthings_control_device(smartthing_endpoint, token, endpoint_id, power_state_value)
if not state_set:
return AlexaResponse(
name='ErrorResponse',
payload={'type': 'ENDPOINT_UNREACHABLE', 'message': 'Unable to reach endpoint database.'}).get()
apcr = AlexaResponse(correlation_token=correlation_token, token=token, endpoint_id=endpoint_id)
apcr.add_context_property(namespace='Alexa.PowerController', name='powerState', value=power_state_value)
if power_state_value == "ON":
apcr.add_context_property(namespace='Alexa.ContactSensor', name='detectionState', value='DETECTED')
else:
apcr.add_context_property(namespace='Alexa.ContactSensor', name='detectionState', value='NOT_DETECTED')
return send_response(apcr.get())
# if namespace == 'Alexa.LockController':
# Note: This sample always returns a success response for either a request to TurnOff or TurnOn
endpoint_id = request['directive']['endpoint']['endpointId']
state_value = 'LOCKED' if name == 'Lock' else 'UNLOCKED'
correlation_token = request['directive']['header']['correlationToken']
# Check for an error when setting the state
state_set = set_device_state(endpoint_id=endpoint_id, state='lockState', value=state_value)
if not state_set:
return AlexaResponse(
name='ErrorResponse',
payload={'type': 'ENDPOINT_UNREACHABLE', 'message': 'Unable to reach endpoint database.'}).get()
apcr = AlexaResponse(correlation_token=correlation_token)
apcr.add_context_property(namespace='Alexa.LockController', name='lockState', value=state_value)
return send_response(apcr.get())
if namespace == 'Alexa':
if name == 'ReportState':
endpoint_id = request['directive']['endpoint']['endpointId']
token = request['directive']['endpoint']['scope']['token']
smartthing_endpoint = smartthings_discover_endpoint(token)
power_state_value = smartthings_get_device_state(smartthing_endpoint, token, endpoint_id)
if power_state_value == 'ON':
sensor_state_value = 'DETECTED'
else:
sensor_state_value = 'NOT_DETECTED'
##TODO: retrive status of devices
correlation_token = request['directive']['header']['correlationToken']
apcr = AlexaResponse(correlation_token=correlation_token,token=token, endpoint_id=endpoint_id,name='StateReport')
apcr.add_context_property(namespace='Alexa.ContactSensor', name='detectionState', value=sensor_state_value)
apcr.add_context_property(namespace='Alexa.PowerController', name='powerState', value=power_state_value)
return send_response(apcr.get())
def send_response(response):
# TODO Validate the response
print('lambda_handler response -----')
print(json.dumps(response))
return response
def set_device_state(endpoint_id, state, value):
smartthings_discover_endpoint()
return True
def smartthings_get_device_state(smartthing_endpoint, token, endpoint_id):
headers = {'Authorization': 'Bearer ' token}
#print(smartthing_endpoint '/' endpoint_id)
r = requests.get(smartthing_endpoint '/' 'switches', headers=headers)
#print(r.json())
if (r.status_code == 200):
for i in r.json():
if i['name'] == endpoint_id:
if i['value'] == 'on':
return 'ON'
else:
return 'OFF'
else:
print("JJJ: get device state BUG!")
print(r.status_code)
def smartthings_control_device(smartthing_endpoint, token, endpoint_id, cmd):
headers = {'Authorization': 'Bearer ' token}
response = requests.put(smartthing_endpoint '/switches/' endpoint_id '/' cmd, headers=headers)
print("JJJ: Control device response: " str(response.status_code))
return True
def smartthings_discover_endpoint(token):
headers = {'Authorization': 'Bearer ' token}
r = requests.get("https://graph.api.smartthings.com/api/smartapps/endpoints", headers=headers)
resp = r.json()
#print(resp)
for i in resp:
url = i['uri']
return url
Alexa中设备、场景的数据结构
代码语言:javascript复制{
"networkDetail":"{" locationDetails":{
"locationDetails":{
"Default_Location":{
"locationId":"Default_Location",
"amazonBridgeDetails":{
"amazonBridgeDetails":{
"LambdaBridge_SKILL/eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjE3NTdjNjlmLTFhYzktNGZlYi05NWI3LWFkNTI4OTk1ZTNiNSIsInN0YWdlIjoiZGV2ZWxvcG1lbnQifQ==":{
"amazonBridgeIdentifier":{
"amazonBridgeDSN":"SKILL/eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjE3NTdjNjlmLTFhYzktNGZlYi05NWI3LWFkNTI4OTk1ZTNiNSIsInN0YWdlIjoiZGV2ZWxvcG1lbnQifQ==",
"amazonBridgeType":"LambdaBridge",
"lambdaBridge":true,
"amazonBridgeSource":"SKILL"
},
"applianceDetails":{
"applianceDetails":{
"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjE3NTdjNjlmLTFhYzktNGZlYi05NWI3LWFkNTI4OTk1ZTNiNSIsInN0YWdlIjoiZGV2ZWxvcG1lbnQifQ==_fake_end1":{
"applianceId":"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjE3NTdjNjlmLTFhYzktNGZlYi05NWI3LWFkNTI4OTk1ZTNiNSIsInN0YWdlIjoiZGV2ZWxvcG1lbnQifQ==_fake_end1",
"endpointTypeId":"",
"driverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjE3NTdjNjlmLTFhYzktNGZlYi05NWI3LWFkNTI4OTk1ZTNiNSIsInN0YWdlIjoiZGV2ZWxvcG1lbnQifQ=="
},
"manufacturerName":"SmartThings",
"friendlyDescription":"Fake SmartThings Switch",
"modelName":"",
"deviceType":"CLOUD_DISCOVERED_DEVICE",
"version":"0",
"friendlyName":"smartthings1",
"friendlyNameModifiedAt":1554150257260,
"capabilitiesModifiedAt":1554150257260,
"ipAddress":"",
"port":"",
"entityId":"6aa7c6ce-723f-4f0b-aca3-a467fa8f89cf",
"applianceNetworkState":{
"reachability":"REACHABLE",
"lastSeenAt":1554150273030,
"createdAt":1554150257260,
"lastSeenDiscoverySessionId":{
"value":"amzn1.HomeAutomation.ApplianceDiscovery.A1OZ7FH12OZY2A.LambdaBridge.fakeDSN.CUSTOMER.2019-04-01T20:24:17.180Z.22e16552-2ad2-4562-bb8d-20e5862326b6"
}
},
"tags":{
"tagNameToValueSetMap":{
}
},
"additionalApplianceDetails":{
"additionalApplianceDetails":{
}
},
"firmwareVersion":"0",
"actions":[
],
"capabilities":[
{
"capabilityType":"AVSInterfaceCapability",
"type":"AlexaInterface",
"version":"3",
"properties":{
"supported":[
{
"name":"powerState"
}
],
"proactivelyReported":true,
"retrievable":false,
"readOnly":false
},
"interfaceName":"Alexa.PowerController"
}
],
"applianceTypes":[
"SWITCH"
],
"isEnabled":true,
"aliases":[
],
"connectedVia":"",
"alexaDeviceIdentifierList":[
],
"ipaddress":"",
"applianceLambdaControlled":true,
"applianceDriverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjE3NTdjNjlmLTFhYzktNGZlYi05NWI3LWFkNTI4OTk1ZTNiNSIsInN0YWdlIjoiZGV2ZWxvcG1lbnQifQ=="
}
}
}
}
},
"LambdaBridge_SKILL/eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjI3MDZhOGNmLWUzYWItNGRjNi04ZTNkLWEwYjlkZWYxOWQ1NyIsInN0YWdlIjoiZGV2ZWxvcG1lbnQifQ==":{
"amazonBridgeIdentifier":{
"amazonBridgeDSN":"SKILL/eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjI3MDZhOGNmLWUzYWItNGRjNi04ZTNkLWEwYjlkZWYxOWQ1NyIsInN0YWdlIjoiZGV2ZWxvcG1lbnQifQ==",
"amazonBridgeType":"LambdaBridge",
"lambdaBridge":true,
"amazonBridgeSource":"SKILL"
},
"applianceDetails":{
"applianceDetails":{
"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjI3MDZhOGNmLWUzYWItNGRjNi04ZTNkLWEwYjlkZWYxOWQ1NyIsInN0YWdlIjoiZGV2ZWxvcG1lbnQifQ==_fake_end1":{
"applianceId":"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjI3MDZhOGNmLWUzYWItNGRjNi04ZTNkLWEwYjlkZWYxOWQ1NyIsInN0YWdlIjoiZGV2ZWxvcG1lbnQifQ==_fake_end1",
"endpointTypeId":"",
"driverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjI3MDZhOGNmLWUzYWItNGRjNi04ZTNkLWEwYjlkZWYxOWQ1NyIsInN0YWdlIjoiZGV2ZWxvcG1lbnQifQ=="
},
"manufacturerName":"SmartThings",
"friendlyDescription":"Fake SmartThings Switch2",
"modelName":"",
"deviceType":"CLOUD_DISCOVERED_DEVICE",
"version":"0",
"friendlyName":"smartthings1",
"friendlyNameModifiedAt":1554150257281,
"capabilitiesModifiedAt":1554150257281,
"ipAddress":"",
"port":"",
"entityId":"c792b2e7-e71b-41ec-b2e3-9e9476ab7e35",
"applianceNetworkState":{
"reachability":"REACHABLE",
"lastSeenAt":1554150273030,
"createdAt":1554150257281,
"lastSeenDiscoverySessionId":{
"value":"amzn1.HomeAutomation.ApplianceDiscovery.A1OZ7FH12OZY2A.LambdaBridge.fakeDSN.CUSTOMER.2019-04-01T20:24:17.180Z.22e16552-2ad2-4562-bb8d-20e5862326b6"
}
},
"tags":{
"tagNameToValueSetMap":{
}
},
"additionalApplianceDetails":{
"additionalApplianceDetails":{
}
},
"firmwareVersion":"0",
"actions":[
],
"capabilities":[
{
"capabilityType":"AVSInterfaceCapability",
"type":"AlexaInterface",
"version":"3",
"properties":{
"supported":[
{
"name":"powerState"
}
],
"proactivelyReported":true,
"retrievable":true,
"readOnly":false
},
"interfaceName":"Alexa.PowerController"
}
],
"applianceTypes":[
"SWITCH"
],
"isEnabled":true,
"aliases":[
],
"connectedVia":"",
"alexaDeviceIdentifierList":[
],
"ipaddress":"",
"applianceLambdaControlled":true,
"applianceDriverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjI3MDZhOGNmLWUzYWItNGRjNi04ZTNkLWEwYjlkZWYxOWQ1NyIsInN0YWdlIjoiZGV2ZWxvcG1lbnQifQ=="
}
}
}
}
},
"LambdaBridge_SKILL/eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9":{
"amazonBridgeIdentifier":{
"amazonBridgeDSN":"SKILL/eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9",
"amazonBridgeType":"LambdaBridge",
"lambdaBridge":true,
"amazonBridgeSource":"SKILL"
},
"applianceDetails":{
"applianceDetails":{
"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_e0401c4e-ff5e-43f6-af5f-4986afb8266e":{
"applianceId":"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_e0401c4e-ff5e-43f6-af5f-4986afb8266e",
"endpointTypeId":"",
"driverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
},
"manufacturerName":"SmartThings",
"friendlyDescription":"SmartThings Routine",
"modelName":"",
"deviceType":"CLOUD_DISCOVERED_DEVICE",
"version":"0",
"friendlyName":"Goodbye!",
"friendlyNameModifiedAt":1552940633050,
"capabilitiesModifiedAt":1552940633050,
"ipAddress":"",
"port":"",
"entityId":"147bd392-8ffd-4dc3-b954-0a91231ecea6",
"applianceNetworkState":{
"reachability":"REACHABLE",
"lastSeenAt":1554150273030,
"createdAt":1552940633050,
"lastSeenDiscoverySessionId":{
"value":"amzn1.HomeAutomation.ApplianceDiscovery.A1OZ7FH12OZY2A.LambdaBridge.fakeDSN.CUSTOMER.2019-04-01T20:24:17.180Z.22e16552-2ad2-4562-bb8d-20e5862326b6"
}
},
"tags":{
"tagNameToValueSetMap":{
}
},
"additionalApplianceDetails":{
"additionalApplianceDetails":{
"uri":"https://graph.api.smartthings.com:443/api/smartapps/installations/3f4b5154-1538-429d-9311-b095a17c18a8"
}
},
"firmwareVersion":"0",
"actions":[
],
"capabilities":[
{
"capabilityType":"AVSSceneControllerCapability",
"type":"AlexaInterface",
"version":"3",
"proactivelyReported":false,
"supportsDeactivation":false,
"interfaceName":"Alexa.SceneController"
}
],
"applianceTypes":[
"SCENE_TRIGGER"
],
"isEnabled":true,
"aliases":[
],
"connectedVia":"",
"alexaDeviceIdentifierList":[
],
"ipaddress":"",
"applianceLambdaControlled":true,
"applianceDriverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
}
},
"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_5178a3ef-b365-4338-b1b2-aab4fbbc5e1e":{
"applianceId":"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_5178a3ef-b365-4338-b1b2-aab4fbbc5e1e",
"endpointTypeId":"",
"driverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
},
"manufacturerName":"SmartThings",
"friendlyDescription":"SmartThings Routine",
"modelName":"",
"deviceType":"CLOUD_DISCOVERED_DEVICE",
"version":"0",
"friendlyName":"IAmBack",
"friendlyNameModifiedAt":1552940633063,
"capabilitiesModifiedAt":1552940633063,
"ipAddress":"",
"port":"",
"entityId":"a5c397bd-847b-45fa-89fb-f34eb556f207",
"applianceNetworkState":{
"reachability":"REACHABLE",
"lastSeenAt":1554150273030,
"createdAt":1552940633050,
"lastSeenDiscoverySessionId":{
"value":"amzn1.HomeAutomation.ApplianceDiscovery.A1OZ7FH12OZY2A.LambdaBridge.fakeDSN.CUSTOMER.2019-04-01T20:24:17.180Z.22e16552-2ad2-4562-bb8d-20e5862326b6"
}
},
"tags":{
"tagNameToValueSetMap":{
}
},
"additionalApplianceDetails":{
"additionalApplianceDetails":{
"uri":"https://graph.api.smartthings.com:443/api/smartapps/installations/3f4b5154-1538-429d-9311-b095a17c18a8"
}
},
"firmwareVersion":"0",
"actions":[
],
"capabilities":[
{
"capabilityType":"AVSSceneControllerCapability",
"type":"AlexaInterface",
"version":"3",
"proactivelyReported":false,
"supportsDeactivation":false,
"interfaceName":"Alexa.SceneController"
}
],
"applianceTypes":[
"SCENE_TRIGGER"
],
"isEnabled":true,
"aliases":[
],
"connectedVia":"",
"alexaDeviceIdentifierList":[
],
"ipaddress":"",
"applianceLambdaControlled":true,
"applianceDriverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
}
},
"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_f59f6427-db90-4402-8a6b-c2be09ae2ff0":{
"applianceId":"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_f59f6427-db90-4402-8a6b-c2be09ae2ff0",
"endpointTypeId":"",
"driverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
},
"manufacturerName":"SmartThings",
"friendlyDescription":"SmartThings Switch",
"modelName":"",
"deviceType":"CLOUD_DISCOVERED_DEVICE",
"version":"0",
"friendlyName":"smartthings2",
"friendlyNameModifiedAt":1554149203953,
"capabilitiesModifiedAt":1554149203953,
"ipAddress":"",
"port":"",
"entityId":"3b84b62c-4c56-4e6a-814a-5bd92df3511c",
"applianceNetworkState":{
"reachability":"REACHABLE",
"lastSeenAt":1554150273030,
"createdAt":1554149203953,
"lastSeenDiscoverySessionId":{
"value":"amzn1.HomeAutomation.ApplianceDiscovery.A1OZ7FH12OZY2A.LambdaBridge.fakeDSN.CUSTOMER.2019-04-01T20:24:17.180Z.22e16552-2ad2-4562-bb8d-20e5862326b6"
}
},
"tags":{
"tagNameToValueSetMap":{
}
},
"additionalApplianceDetails":{
"additionalApplianceDetails":{
"uri":"https://graph.api.smartthings.com:443/api/smartapps/installations/3f4b5154-1538-429d-9311-b095a17c18a8"
}
},
"firmwareVersion":"0",
"actions":[
],
"capabilities":[
{
"capabilityType":"AVSInterfaceCapability",
"type":"AlexaInterface",
"version":"3",
"properties":{
"supported":[
{
"name":"connectivity"
}
],
"proactivelyReported":false,
"retrievable":true,
"readOnly":false
},
"interfaceName":"Alexa.EndpointHealth"
},
{
"capabilityType":"AVSInterfaceCapability",
"type":"AlexaInterface",
"version":"3",
"properties":{
"supported":[
{
"name":"powerState"
}
],
"proactivelyReported":true,
"retrievable":true,
"readOnly":false
},
"interfaceName":"Alexa.PowerController"
}
],
"applianceTypes":[
"SWITCH"
],
"isEnabled":true,
"aliases":[
],
"connectedVia":"",
"alexaDeviceIdentifierList":[
],
"ipaddress":"",
"applianceLambdaControlled":true,
"applianceDriverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
}
},
"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_6848728a-6951-4457-8d1b-037fea3fea67":{
"applianceId":"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_6848728a-6951-4457-8d1b-037fea3fea67",
"endpointTypeId":"",
"driverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
},
"manufacturerName":"SmartThings",
"friendlyDescription":"SmartThings Routine",
"modelName":"",
"deviceType":"CLOUD_DISCOVERED_DEVICE",
"version":"0",
"friendlyName":"Good Morning!",
"friendlyNameModifiedAt":1552940633068,
"capabilitiesModifiedAt":1552940633068,
"ipAddress":"",
"port":"",
"entityId":"5c5d0a42-66a7-47f0-a2a1-3dd88da1e31d",
"applianceNetworkState":{
"reachability":"REACHABLE",
"lastSeenAt":1554150273030,
"createdAt":1552940633050,
"lastSeenDiscoverySessionId":{
"value":"amzn1.HomeAutomation.ApplianceDiscovery.A1OZ7FH12OZY2A.LambdaBridge.fakeDSN.CUSTOMER.2019-04-01T20:24:17.180Z.22e16552-2ad2-4562-bb8d-20e5862326b6"
}
},
"tags":{
"tagNameToValueSetMap":{
}
},
"additionalApplianceDetails":{
"additionalApplianceDetails":{
"uri":"https://graph.api.smartthings.com:443/api/smartapps/installations/3f4b5154-1538-429d-9311-b095a17c18a8"
}
},
"firmwareVersion":"0",
"actions":[
],
"capabilities":[
{
"capabilityType":"AVSSceneControllerCapability",
"type":"AlexaInterface",
"version":"3",
"proactivelyReported":false,
"supportsDeactivation":false,
"interfaceName":"Alexa.SceneController"
}
],
"applianceTypes":[
"SCENE_TRIGGER"
],
"isEnabled":true,
"aliases":[
],
"connectedVia":"",
"alexaDeviceIdentifierList":[
],
"ipaddress":"",
"applianceLambdaControlled":true,
"applianceDriverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
}
},
"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_c4940aaa-4e5c-46fe-9419-2d9f77c7cee8":{
"applianceId":"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_c4940aaa-4e5c-46fe-9419-2d9f77c7cee8",
"endpointTypeId":"",
"driverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
},
"manufacturerName":"SmartThings",
"friendlyDescription":"SmartThings Routine",
"modelName":"",
"deviceType":"CLOUD_DISCOVERED_DEVICE",
"version":"0",
"friendlyName":"哈哈",
"friendlyNameModifiedAt":1552940633074,
"capabilitiesModifiedAt":1552940633074,
"ipAddress":"",
"port":"",
"entityId":"476ee698-1638-41eb-a8a0-e963b60d85c6",
"applianceNetworkState":{
"reachability":"NOT_REACHABLE",
"lastSeenAt":1554150273030,
"createdAt":1552940633050,
"lastSeenDiscoverySessionId":{
"value":"amzn1.HomeAutomation.ApplianceDiscovery.A1OZ7FH12OZY2A.A3S5BH2HU6VAYF.G090L91072720DQ7.CUSTOMER.2019-03-18T20:23:52.425Z.78cc347a-2f85-4c12-8c82-30555a1c75c0"
}
},
"tags":{
"tagNameToValueSetMap":{
}
},
"additionalApplianceDetails":{
"additionalApplianceDetails":{
"uri":"https://graph.api.smartthings.com:443/api/smartapps/installations/aa14d7cf-2510-42fc-b49a-61a3201d7688"
}
},
"firmwareVersion":"0",
"actions":[
],
"capabilities":[
{
"capabilityType":"AVSSceneControllerCapability",
"type":"AlexaInterface",
"version":"3",
"proactivelyReported":false,
"supportsDeactivation":false,
"interfaceName":"Alexa.SceneController"
}
],
"applianceTypes":[
"SCENE_TRIGGER"
],
"isEnabled":true,
"aliases":[
],
"connectedVia":"",
"alexaDeviceIdentifierList":[
],
"ipaddress":"",
"applianceLambdaControlled":true,
"applianceDriverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
}
},
"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_403dd373-7940-4edb-ad96-88bf3f28e4cc":{
"applianceId":"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_403dd373-7940-4edb-ad96-88bf3f28e4cc",
"endpointTypeId":"",
"driverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
},
"manufacturerName":"SmartThings",
"friendlyDescription":"SmartThings Device",
"modelName":"",
"deviceType":"CLOUD_DISCOVERED_DEVICE",
"version":"0",
"friendlyName":"11111",
"friendlyNameModifiedAt":1554149203958,
"capabilitiesModifiedAt":1554149203958,
"ipAddress":"",
"port":"",
"entityId":"7cec84af-4f7a-49f0-92d6-e3403ea910fd",
"applianceNetworkState":{
"reachability":"REACHABLE",
"lastSeenAt":1554150273030,
"createdAt":1554149203953,
"lastSeenDiscoverySessionId":{
"value":"amzn1.HomeAutomation.ApplianceDiscovery.A1OZ7FH12OZY2A.LambdaBridge.fakeDSN.CUSTOMER.2019-04-01T20:24:17.180Z.22e16552-2ad2-4562-bb8d-20e5862326b6"
}
},
"tags":{
"tagNameToValueSetMap":{
}
},
"additionalApplianceDetails":{
"additionalApplianceDetails":{
"uri":"https://graph.api.smartthings.com:443/api/smartapps/installations/3f4b5154-1538-429d-9311-b095a17c18a8"
}
},
"firmwareVersion":"0",
"actions":[
],
"capabilities":[
{
"capabilityType":"AVSInterfaceCapability",
"type":"AlexaInterface",
"version":"3",
"properties":{
"supported":[
{
"name":"powerState"
}
],
"proactivelyReported":true,
"retrievable":true,
"readOnly":false
},
"interfaceName":"Alexa.PowerController"
},
{
"capabilityType":"AVSInterfaceCapability",
"type":"AlexaInterface",
"version":"3",
"properties":{
"supported":[
{
"name":"connectivity"
}
],
"proactivelyReported":true,
"retrievable":true,
"readOnly":false
},
"interfaceName":"Alexa.EndpointHealth"
}
],
"applianceTypes":[
"SMARTPLUG"
],
"isEnabled":true,
"aliases":[
],
"connectedVia":"",
"alexaDeviceIdentifierList":[
],
"ipaddress":"",
"applianceLambdaControlled":true,
"applianceDriverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
}
},
"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_d956f54a-b71a-4c49-b92e-234e880e2bef":{
"applianceId":"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_d956f54a-b71a-4c49-b92e-234e880e2bef",
"endpointTypeId":"",
"driverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
},
"manufacturerName":"SmartThings",
"friendlyDescription":"SmartThings Switch",
"modelName":"",
"deviceType":"CLOUD_DISCOVERED_DEVICE",
"version":"0",
"friendlyName":"smartthings1",
"friendlyNameModifiedAt":1554149203970,
"capabilitiesModifiedAt":1554149203970,
"ipAddress":"",
"port":"",
"entityId":"a7431ebe-3631-4ad4-ac58-112a092df4be",
"applianceNetworkState":{
"reachability":"REACHABLE",
"lastSeenAt":1554150273030,
"createdAt":1554149203953,
"lastSeenDiscoverySessionId":{
"value":"amzn1.HomeAutomation.ApplianceDiscovery.A1OZ7FH12OZY2A.LambdaBridge.fakeDSN.CUSTOMER.2019-04-01T20:24:17.180Z.22e16552-2ad2-4562-bb8d-20e5862326b6"
}
},
"tags":{
"tagNameToValueSetMap":{
}
},
"additionalApplianceDetails":{
"additionalApplianceDetails":{
"uri":"https://graph.api.smartthings.com:443/api/smartapps/installations/3f4b5154-1538-429d-9311-b095a17c18a8"
}
},
"firmwareVersion":"0",
"actions":[
],
"capabilities":[
{
"capabilityType":"AVSInterfaceCapability",
"type":"AlexaInterface",
"version":"3",
"properties":{
"supported":[
{
"name":"connectivity"
}
],
"proactivelyReported":false,
"retrievable":true,
"readOnly":false
},
"interfaceName":"Alexa.EndpointHealth"
},
{
"capabilityType":"AVSInterfaceCapability",
"type":"AlexaInterface",
"version":"3",
"properties":{
"supported":[
{
"name":"powerState"
}
],
"proactivelyReported":true,
"retrievable":true,
"readOnly":false
},
"interfaceName":"Alexa.PowerController"
}
],
"applianceTypes":[
"SWITCH"
],
"isEnabled":true,
"aliases":[
],
"connectedVia":"",
"alexaDeviceIdentifierList":[
],
"ipaddress":"",
"applianceLambdaControlled":true,
"applianceDriverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
}
},
"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_63c09df9-6d13-40f8-bec0-c1217c5dd9ed":{
"applianceId":"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_63c09df9-6d13-40f8-bec0-c1217c5dd9ed",
"endpointTypeId":"",
"driverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
},
"manufacturerName":"SmartThings",
"friendlyDescription":"SmartThings Light (dimmable)",
"modelName":"",
"deviceType":"CLOUD_DISCOVERED_DEVICE",
"version":"0",
"friendlyName":"smartthings3",
"friendlyNameModifiedAt":1554149203964,
"capabilitiesModifiedAt":1554149203964,
"ipAddress":"",
"port":"",
"entityId":"1cf0ab83-b1fe-405b-bd00-f1f07a7927a0",
"applianceNetworkState":{
"reachability":"REACHABLE",
"lastSeenAt":1554150273030,
"createdAt":1554149203953,
"lastSeenDiscoverySessionId":{
"value":"amzn1.HomeAutomation.ApplianceDiscovery.A1OZ7FH12OZY2A.LambdaBridge.fakeDSN.CUSTOMER.2019-04-01T20:24:17.180Z.22e16552-2ad2-4562-bb8d-20e5862326b6"
}
},
"tags":{
"tagNameToValueSetMap":{
}
},
"additionalApplianceDetails":{
"additionalApplianceDetails":{
"uri":"https://graph.api.smartthings.com:443/api/smartapps/installations/3f4b5154-1538-429d-9311-b095a17c18a8"
}
},
"firmwareVersion":"0",
"actions":[
],
"capabilities":[
{
"capabilityType":"AVSInterfaceCapability",
"type":"AlexaInterface",
"version":"3",
"properties":{
"supported":[
{
"name":"brightness"
}
],
"proactivelyReported":true,
"retrievable":true,
"readOnly":false
},
"interfaceName":"Alexa.BrightnessController"
},
{
"capabilityType":"AVSInterfaceCapability",
"type":"AlexaInterface",
"version":"3",
"properties":{
"supported":[
{
"name":"connectivity"
}
],
"proactivelyReported":false,
"retrievable":true,
"readOnly":false
},
"interfaceName":"Alexa.EndpointHealth"
},
{
"capabilityType":"AVSInterfaceCapability",
"type":"AlexaInterface",
"version":"3",
"properties":{
"supported":[
{
"name":"powerState"
}
],
"proactivelyReported":true,
"retrievable":true,
"readOnly":false
},
"interfaceName":"Alexa.PowerController"
}
],
"applianceTypes":[
"SWITCH",
"LIGHT"
],
"isEnabled":true,
"aliases":[
],
"connectedVia":"",
"alexaDeviceIdentifierList":[
],
"ipaddress":"",
"applianceLambdaControlled":true,
"applianceDriverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
}
},
"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_93a23d5f-c61c-44b1-b41e-5bdf6ebd66e8":{
"applianceId":"SKILL_eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9_93a23d5f-c61c-44b1-b41e-5bdf6ebd66e8",
"endpointTypeId":"",
"driverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
},
"manufacturerName":"SmartThings",
"friendlyDescription":"SmartThings Routine",
"modelName":"",
"deviceType":"CLOUD_DISCOVERED_DEVICE",
"version":"0",
"friendlyName":"Good Night!",
"friendlyNameModifiedAt":1552940633087,
"capabilitiesModifiedAt":1552940633087,
"ipAddress":"",
"port":"",
"entityId":"302b9711-6998-4865-9204-7a4ea5c2d2af",
"applianceNetworkState":{
"reachability":"REACHABLE",
"lastSeenAt":1554150273030,
"createdAt":1552940633050,
"lastSeenDiscoverySessionId":{
"value":"amzn1.HomeAutomation.ApplianceDiscovery.A1OZ7FH12OZY2A.LambdaBridge.fakeDSN.CUSTOMER.2019-04-01T20:24:17.180Z.22e16552-2ad2-4562-bb8d-20e5862326b6"
}
},
"tags":{
"tagNameToValueSetMap":{
}
},
"additionalApplianceDetails":{
"additionalApplianceDetails":{
"uri":"https://graph.api.smartthings.com:443/api/smartapps/installations/3f4b5154-1538-429d-9311-b095a17c18a8"
}
},
"firmwareVersion":"0",
"actions":[
],
"capabilities":[
{
"capabilityType":"AVSSceneControllerCapability",
"type":"AlexaInterface",
"version":"3",
"proactivelyReported":false,
"supportsDeactivation":false,
"interfaceName":"Alexa.SceneController"
}
],
"applianceTypes":[
"SCENE_TRIGGER"
],
"isEnabled":true,
"aliases":[
],
"connectedVia":"",
"alexaDeviceIdentifierList":[
],
"ipaddress":"",
"applianceLambdaControlled":true,
"applianceDriverIdentity":{
"namespace":"SKILL",
"identifier":"eyJza2lsbElkIjoiYW16bjEuYXNrLnNraWxsLjJiZGJjNzRmLWNlNGQtNGUyZC1iNzQxLTMyNmM3YmEzNThmMCIsInN0YWdlIjoibGl2ZSJ9"
}
}
}
}
}
}
},
"applianceGroups":{
"applianceGroups":{
}
}
}
}
},
"version":"1.0",
"relations":[
]
}"
}