Skip to content

Commit

Permalink
several improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
cekk committed Jan 25, 2020
1 parent daaae92 commit ef048ce
Show file tree
Hide file tree
Showing 21 changed files with 418 additions and 113 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ deploy_lambda:
pipenv run pip install --target ./lambda_function/package -r lambda_function/requirements.txt
cd lambda_function/package && zip -r9 ../../function.zip .
cd lambda_function && zip -g ../function.zip lambda_function.py
cd lambda_function && zip -g ../function.zip capabilities_settings.py
cd lambda_function && zip -r9 -g ../function.zip alexa
aws2 lambda update-function-code --function-name gestore_tapparelle --zip-file fileb://function.zip
14 changes: 5 additions & 9 deletions development.cfg
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
[buildout]

extensions = mr.developer
extends =
base.cfg

parts +=
flask-instance


[flask-instance]
recipe = zc.zdaemonrecipe
program =
${buildout:bin-directory}/flask run
sources = sources

[supervisor]
programs =
100 mosquitto /usr/local/Cellar/mosquitto/1.6.8/sbin/mosquitto [-c /usr/local/etc/mosquitto/mosquitto.conf] true

[sources]
Flask-MQTT = git [email protected]:cekk/Flask-MQTT.git branch=fix_dependence
38 changes: 21 additions & 17 deletions lambda_function/alexa/skills/smarthome/alexa_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,23 +104,27 @@ def create_payload_endpoint_capability(self, **kwargs):
"interface": kwargs.get("interface", "Alexa"),
"version": kwargs.get("version", "3"),
}
instance = kwargs.get("instance", None)
if instance:
capability["instance"] = instance
supported = kwargs.get("supported", None)
if supported:
capability["properties"] = {}
capability["properties"]["supported"] = supported
capability["properties"]["proactivelyReported"] = kwargs.get(
"proactively_reported", False
)
capability["properties"]["retrievable"] = kwargs.get("retrievable", False)
semantics = kwargs.get("semantics", None)
if semantics:
capability["semantics"] = semantics
capability_resources = kwargs.get("capability_resources", None)
if capability_resources:
capability["capabilityResources"] = capability_resources
# instance = kwargs.get("instance", None)
# if instance:
# capability["instance"] = instance
# supported = kwargs.get("supported", None)
# if supported:
# capability["properties"] = {}
# capability["properties"]["supported"] = supported
# capability["properties"]["proactivelyReported"] = kwargs.get(
# "proactively_reported", False
# )
# capability["properties"]["retrievable"] = kwargs.get("retrievable", False)
# semantics = kwargs.get("semantics", None)
# if semantics:
# capability["semantics"] = semantics
# configuration = kwargs.get("configuration", None)
# if configuration:
# capability["configuration"] = configuration
# capability_resources = kwargs.get("capability_resources", None)
# if capability_resources:
# capability["capabilityResources"] = capability_resources
capability.update(kwargs)
return capability

def get(self, remove_empty=True):
Expand Down
138 changes: 138 additions & 0 deletions lambda_function/capabilities_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
TOGGLE_CAPABILITY = {
"version": "3",
"interface": "Alexa.ToggleController",
"properties": {
"proactivelyReported": True,
"retrievable": True,
},
"instance": "Blind.BlindState",
"capabilityResources": {
"friendlyNames": [
{"@type": "text", "value": {"text": "tapparella", "locale": "it-IT"},}
]
},
"semantics": {
"actionMappings": [
{
"@type": "ActionsToDirective",
"actions": ["Alexa.Actions.Close"],
"directive": {"name": "TurnOff", "payload": {}},
},
{
"@type": "ActionsToDirective",
"actions": ["Alexa.Actions.Open"],
"directive": {"name": "TurnOn", "payload": {}},
},
],
"stateMappings": [
{
"@type": "StatesToValue",
"states": ["Alexa.States.Closed"],
"value": "OFF",
},
{"@type": "StatesToValue", "states": ["Alexa.States.Open"], "value": "ON",},
],
},
}


RANGE_CAPABILITY = {
"interface": "Alexa.RangeController",
"instance": "Blind.Lift",
"version": "3",
"properties": {
"supported": [{"name": "rangeValue"}],
"proactivelyReported": True,
"retrievable": True,
},
"capabilityResources": {
"friendlyNames": [
{"@type": "asset", "value": {"assetId": "Alexa.Setting.Opening"}}
]
},
"configuration": {
"supportedRange": {"minimumValue": 0, "maximumValue": 100, "precision": 1},
"unitOfMeasure": "Alexa.Unit.Percent",
},
"semantics": {
"actionMappings": [
{
"@type": "ActionsToDirective",
"actions": ["Alexa.Actions.Close"],
"directive": {"name": "SetRangeValue", "payload": {"rangeValue": 0}},
},
{
"@type": "ActionsToDirective",
"actions": ["Alexa.Actions.Open"],
"directive": {"name": "SetRangeValue", "payload": {"rangeValue": 100}},
},
{
"@type": "ActionsToDirective",
"actions": ["Alexa.Actions.Lower"],
"directive": {
"name": "AdjustRangeValue",
"payload": {
"rangeValueDelta": -10,
"rangeValueDeltaDefault": False,
},
},
},
{
"@type": "ActionsToDirective",
"actions": ["Alexa.Actions.Raise"],
"directive": {
"name": "AdjustRangeValue",
"payload": {"rangeValueDelta": 10, "rangeValueDeltaDefault": False},
},
},
],
"stateMappings": [
{"@type": "StatesToValue", "states": ["Alexa.States.Closed"], "value": 0},
{
"@type": "StatesToRange",
"states": ["Alexa.States.Open"],
"range": {"minimumValue": 1, "maximumValue": 100},
},
],
},
}

MODE_CAPABILITY = {
"interface": "Alexa.ModeController",
"instance": "Blind.Calibrated",
"proactively_reported": True,
"retrievable": True,
"capabilityResources": {
"friendlyNames": [
{"@type": "text", "value": {"text": "wash cycle", "locale": "en-US"}},
{"@type": "text", "value": {"text": "wash setting", "locale": "en-US"}},
]
},
"configuration": {
"ordered": False,
"supportedModes": [
{
"value": "Blind.Calibrated",
"modeResources": {
"friendlyNames": [
{
"@type": "text",
"value": {"text": "calibrata", "locale": "it-IT"},
}
]
},
},
{
"value": "Blind.NotCalibrated",
"modeResources": {
"friendlyNames": [
{
"@type": "text",
"value": {"text": "non calibrata", "locale": "it-IT"},
}
]
},
},
],
},
}
107 changes: 53 additions & 54 deletions lambda_function/lambda_function.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
from alexa.skills.smarthome import AlexaResponse
from capabilities_settings import MODE_CAPABILITY
from capabilities_settings import RANGE_CAPABILITY
from capabilities_settings import TOGGLE_CAPABILITY

import boto3
import json
Expand Down Expand Up @@ -68,73 +71,64 @@ def lambda_handler(request, context):

adr = AlexaResponse(namespace="Alexa.Discovery", name="Discover.Response")
capability_alexa = adr.create_payload_endpoint_capability()
capability_alexa_togglecontroller = adr.create_payload_endpoint_capability(
interface="Alexa.ToggleController",
supported=[{"name": "toggleState"}],
instance="Blind.BlindState",
capability_resources={
"friendlyNames": [
{
"@type": "text",
"value": {"text": "tapparella", "locale": "it-IT"},
}
]
},
semantics={
"actionMappings": [
{
"@type": "ActionsToDirective",
"actions": ["Alexa.Actions.Close"],
"directive": {"name": "TurnOff", "payload": {}},
},
{
"@type": "ActionsToDirective",
"actions": ["Alexa.Actions.Open"],
"directive": {"name": "TurnOn", "payload": {}},
},
],
"stateMappings": [
{
"@type": "StatesToValue",
"states": ["Alexa.States.Closed"],
"value": "OFF",
},
{
"@type": "StatesToValue",
"states": ["Alexa.States.Open"],
"value": "ON",
},
],
},
togglecontroller = adr.create_payload_endpoint_capability(
**TOGGLE_CAPABILITY
)
rangecontroller = adr.create_payload_endpoint_capability(**RANGE_CAPABILITY)
# capability_alexa_modecontroller = adr.create_payload_endpoint_capability(
# **MODE_CAPABILITY
# )

for blind in res.json():
adr.add_payload_endpoint(
friendly_name=blind.get("name"),
endpoint_id=blind.get("id"),
description="Remote controlled blind",
capabilities=[capability_alexa, capability_alexa_togglecontroller],
capabilities=[capability_alexa, rangecontroller],
display_categories=["INTERIOR_BLIND"],
)
return send_response(adr.get())

if namespace == "Alexa.ToggleController":
# if namespace == "Alexa.ToggleController":
# # Note: This sample always returns a success response for either a request to TurnOff or TurnOn
# device_id = request["directive"]["endpoint"]["endpointId"]
# action = "close" if name == "TurnOff" else "open"
# call_api(
# endpoint="roller/{device_id}/{action}".format(
# device_id=device_id, action=action
# )
# )
# correlation_token = request["directive"]["header"]["correlationToken"]

# apcr = AlexaResponse(correlation_token=correlation_token)
# state_value = "OFF" if name == "TurnOff" else "ON"
# apcr.add_context_property(
# namespace="Alexa.ToggleController", name="toggleState", value=state_value,
# )
# return send_response(apcr.get())

if namespace == "Alexa.RangeController":
# Note: This sample always returns a success response for either a request to TurnOff or TurnOn
device_id = request["directive"]["endpoint"]["endpointId"]
action = "close" if name == "TurnOff" else "open"
call_api(
endpoint="roller/{device_id}/{action}".format(
device_id=device_id, action=action
)
if name == 'AdjustRangeValue':
value = request["directive"]["payload"]["rangeValueDelta"]
else:
value = request["directive"]["payload"]["rangeValue"]
res = call_api(
endpoint="blind/position",
method="POST",
data={"id": device_id, "value": int(value), "type": name},
)
print("-- RESPONSE --")
print(res.json())
correlation_token = request["directive"]["header"]["correlationToken"]

apcr = AlexaResponse(correlation_token=correlation_token)
state_value = "OFF" if name == "TurnOff" else "ON"
apcr.add_context_property(
namespace="Alexa.ToggleController", name="toggleState", value=state_value,
)
return send_response(apcr.get())
# apcr = AlexaResponse(correlation_token=correlation_token)
# state_value = "OFF" if name == "TurnOff" else "ON"
# apcr.add_context_property(
# namespace="Alexa.RangeController", name="toggleState", value=state_value,
# )
# return send_response(apcr.get())


def send_response(response):
Expand All @@ -144,13 +138,18 @@ def send_response(response):
return response


def call_api(endpoint):
def call_api(endpoint, method="GET", data={}):
auth_token = jwt.encode({"identity": skill_id}, token_secret, algorithm="HS256")
hed = {"Authorization": b"Bearer " + auth_token}
url = "{api_endpoint}/{endpoint}".format(
api_endpoint=api_endpoint, endpoint=endpoint
)
print("lambda_handler CALL API -----")
print(url)
requests.get(url, headers=hed)
print("URL: {url}".format(url=url))
if data:
print("DATA: {data}".format(data=data))
if method == "GET":
return requests.get(url, headers=hed)
else:
return requests.post(url, headers=hed, data=data)

Empty file added routes/__init__.py
Empty file.
Loading

0 comments on commit ef048ce

Please sign in to comment.