Smart Home device implementing Alexa.Speaker Interface not responding to volume change request - alexa-skills-kit

My Alexa Smart Home Skill for Entertainment Devices implements a few capabilities of API version 3, including the Alexa.Speaker Interface.
As far as I understand from the documentation, it should respond to voice commands such as “Alexa, set the volume of device to 5”, however Alexa always responds with "Sorry, I can't control the volume on your device".
The discovery response of the device looks like this
{
endpointId: 'music1',
friendlyName: 'pillow',
description: 'Music on Kodi',
manufacturerName: 'Cubox-i',
displayCategories: [],
capabilities: [
{
type: 'AlexaInterface',
interface: 'Alexa.PowerController',
version: '1.0',
properties: {
supported: [
{
name: 'powerState',
},
],
},
},
{
type: 'AlexaInterface',
interface: 'Alexa.PlaybackController',
version: '1.0',
properties: {},
},
{
type: 'AlexaInterface',
interface: 'Alexa.Speaker',
version: '1.0',
properties: {
supported: [
{
name: 'volume',
},
{
name: 'muted',
},
],
},
},
],
}
The discovery seems to work fine, as the PowerController interface is being responded to fine (e.g. "Alexa, turn on pillow").
I can see discovery, PowerController and PlaybackController requests and responses in the AWS Lambda logs.
Any voice commands to Speaker (whether trying to set the volume to 20, increasing it by 5, or asking to mute or unmute pillow) do not produce any requests to my Lambda and result in the response mentioned above – or in the case of muting in "Pillow doesn't support that".

Instead of
properties: {
supported: [
{
name: 'volume',
},
{
name: 'muted',
},
],
},
this JSON ,use this:
'properties.supported':[{
name: 'volume',
},
{
name: 'muted',
}]
This is a bug they are trying to solve,but till then,this will work,please let me know if this particular solution works for you.

To addition to 'properties.supported' the version should be 1 (not 3). The Speaker interface discovery response should look like:
{
"type": "AlexaInterface",
"interface": "Alexa.Speaker",
"version": "1.0",
"properties.supported":[
{
"name": "muted",
},
{
"name": "volume"
}]
}

Related

Firestore: REST API call to runQueries

URL:https://firestore.googleapis.com/v1/{parent=projects//databases//documents}:runQuery
Request body:
{ structuredQuery:
{ from: [
{ collectionId: 'questions'
}
],
orderBy: [
{ field:
{ fieldPath: 'created'
}, direction: 'DESCENDING' }
], select: { fields:
[
{ fieldPath: 'id' },
{ fieldPath: 'details' },
{ fieldPath: 'question' },
{ fieldPath: 'votes' }
]
},
where: {
compositeFilter: {
filters: [
{ fieldFilter: {
field: {
fieldPath: 'author'
},
op: 'EQUAL',
value: {
stringValue: "henry"
}
}
}
], op: 'AND'
}
},
limit: 4
}
}
What error do I get?
[{
"readTime": "2022-12-26T12:46:55.107240Z"
}]
the response isn't returning the expected results
What am I trying to do?
Fetch the given field from the collection: "questions" where the "author" matches "henry"
The documentation is available and it looks pretty straighforward.
Making REST calls
All REST API endpoints exist under the base URL https://firestore.googleapis.com/v1/.
To create a path to a document with the ID LA in the collection
cities under the project YOUR_PROJECT_ID you would use the
following structure.
/projects/YOUR_PROJECT_ID/databases/(default)/documents/cities/LA
To interact with this path, combine it with the base API URL.
https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/cities/LA
The best way to begin experimenting with the REST API is to use
the API Explorer, which automatically generates Google Identity OAuth
2.0 tokens and allows you to examine the API.

The woocommerce cart always comes up empty in my gatsby graphql

Its my first question, hope I am doing it right. I am trying to make a gatsby frontend for my woocommerce and its all fine. Up untill now all my queries has worked just fine, but when I make a query to get the cart information, it always comes up empty on my localhost://8000/___graphql but in the wp graphiql i can see it just fine.
here is my gatsby-config I guess this is where the problem would be.
siteMetadata: {
title: "shopone",
},
plugins: [
{
resolve: `gatsby-source-wordpress`,
options: {
url:
process.env.WPGRAPHQL_URL ||
`https://wpurl/graphql`,
},
},
{
resolve: "gatsby-source-graphql",
options: {
typeName: "WPGraphQL",
fieldName: "wpcontent",
url: "https://wpurl/graphql",
},
},
{
resolve: 'gatsby-wpgraphql-inline-images',
options: {
wordPressUrl: 'https://my/wpurl/',
uploadsUrl: 'https://my/url/wp-content/uploads/',
processPostTypes: ['Page', 'Post', 'CustomPost'],
graphqlTypeName: 'WPGraphQL',
httpHeaders: {
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
}
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: (__dirname, `src`),
},
},
`gatsby-plugin-sass`,
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`
],
};
This is because your localhost:8000/___graphql is generated on the build-time, at this point, the cart will be always empty since the user has not been allowed to fill it yet.
Your WP GraphiQL API is an asynchronous API that gets the data in real-time, on-demand as the user fills the cart so it will always contain the as soon as the requests are done. To "connect" both, you will need to perform some fetch/post request to your API.
You can read for further information in Build Time and Client Runtime Data Fetching.

Alfresco Aikau - creating list for view

I have been working through the Aikau tutorials on Github but can't work out how to create a list that I can pass on to a view. The requirement is to select all workflow tasks for all users and display the results.
I have added the following widgets which displays the details of one users(hard coded), but I need to cycle through all the users and display all workflows.
model.jsonModel = {
services: [
"alfresco/services/CrudService"
],
widgets:[
{
name: "alfresco/lists/AlfSortablePaginatedList",
config: {
loadDataPublishTopic: "ALF_CRUD_GET_ALL",
loadDataPublishPayload: {
url: "api/task-instances?authority=abeecher"
},
itemsProperty: "data",
widgets: [
{
name: "alfresco/lists/views/AlfListView",
config: {
additionalCssClasses: "bordered",
widgetsForHeader: [
{
name: "alfresco/lists/views/layouts/HeaderCell",
config: {
label: "Workflow ID",
sortable: true,
sortValue: "id"
}
},
{
name: "alfresco/lists/views/layouts/HeaderCell",
config: {
label: "Description"
}
},
{
name: "alfresco/lists/views/layouts/HeaderCell",
config: {
label: "Status"
}
},
{
name: "alfresco/lists/views/layouts/HeaderCell",
config: {
label: "Due Date",
sortable: true,
sortValue: "properties.bpm_dueDate"
}
},
{
name: "alfresco/lists/views/layouts/HeaderCell",
config: {
label: "Created By"
}
},
{
name: "alfresco/lists/views/layouts/HeaderCell",
config: {
label: "Assigned To",
sortable: true,
sortValue: "owner.firstName"
}
},
{
name: "alfresco/lists/views/layouts/HeaderCell",
config: {
label: "Tag1"
}
},
{
name: "alfresco/lists/views/layouts/HeaderCell",
config: {
label: "Tag2"
}
},
{
name: "alfresco/lists/views/layouts/HeaderCell",
config: {
label: "Tag3"
}
}
],
widgets: [
{
name: "alfresco/lists/views/layouts/Row",
config: {
widgets: [
{
name: "alfresco/lists/views/layouts/Cell",
config: {
additionalCssClasses: "mediumpad",
widgets: [
{
name: "alfresco/renderers/Property",
config: {
propertyToRender: "id",
}
}
]
}
},
{
name: "alfresco/lists/views/layouts/Cell",
config: {
widgets: [
{
name: "alfresco/renderers/Property",
config: {
propertyToRender: "workflowInstance.message",
}
}
]
}
},
{
name: "alfresco/lists/views/layouts/Cell",
config: {
widgets: [
{
name: "alfresco/renderers/Property",
config: {
propertyToRender: "state",
}
}
]
}
},
{
name: "alfresco/lists/views/layouts/Cell",
config: {
widgets: [
{
name: "alfresco/renderers/Property",
config: {
propertyToRender: "properties.bpm_dueDate",
}
}
]
}
},
{
name: "alfresco/lists/views/layouts/Cell",
config: {
widgets: [
{
name: "alfresco/renderers/Property",
config: {
propertyToRender: "workflowInstance.initiator.firstName" ,
}
}
]
}
},
{
name: "alfresco/lists/views/layouts/Cell",
config: {
widgets: [
{
name: "alfresco/renderers/Property",
config: {
propertyToRender: "owner.firstName",
}
}
]
}
},
]
}
}
]
}
}
]
}
}
]
};
The final solution will require the ability to sort the columns and be able to click on a task to see the underlying workflow. What would be the best way to create the initial list based on these requirements?
If I was to write a widget that did the building of the list, how do I couple the widget to the form? Is this a pub/sub solution since the user is not clicking on anything - just loading the page?
I assume that I would need to write custom a webscript if I use the "url" keyword under the loadDataPublishPayload option? If I did write a webscript, what would be the final statement to return the json data to the form?
I just need some guidance on the best way forward.
At the time of writing, using the latest released version of Aikau (1.0.83) it is not possible to do this using out-of-the-box widgets and services.
The main problem is that there is no full mapping between Aikau and the Share XML based forms runtime. This blog post explains the issue at hand. It is however something that we're working on.
Once the "alfresco/services/FormsRuntimeService" is complete this will be an easier exercise to complete. There would be no need to write additional widgets for the lists because the existing list widgets handle all the requirements for sorting/pagination (if the underlying REST API supports sorting and pagination!).
I guess your best way forward is very dependent upon how quickly require this solution. We're making progress with the FormsRuntimeService, but I can't say when it will be fully ready.
The existing pages in Share that show tasks and workflow that do use the Share Forms Runtime rely on APIs that return HTML that is hard-coded to work with the Share YUI2 based widgets - it might be possible to achieve what you want to using the older Surf Component / YUI2 widget approach. That might be one other area to explore.
The main thing to do is to establish whether or not there are existing REST APIs that will meet you core requirements

Azure Resource Manager - Multiple VM NAT Rules

I am trying to create an ARM template that will provision multiple webservers with directly accessible ports. For instance I want a VM to have either port 9001 or 9002 open based on what the index of the VM is.
I am struggling to get the frontendPort parameter to accept a function. Here is the documentation that I have used.
Here is what the relevant portion of my template looks like:
"inboundNatRules": [
{
"copy": {
"name": "natCopy",
"count": "[parameters('numberOfVms')]"
},
"name": "[concat('directHttps-', copyIndex())]",
"properties": {
"frontendIPConfiguration": {
"id": "[concat(variables('lbID'),'/frontendIPConfigurations/LoadBalancerFrontEnd')]"
},
"frontendPort": "[add(9001, copyIndex())]",
"backendPort": 9001,
"enableFloatingIP": false,
"idleTimeoutInMinutes": 4,
"protocol": "Tcp",
"backendIPConfiguration": {
"id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('vmNicName'), copyIndex()), 'ipconfig')]"
}
}
}
]
I was hoping that the this particular port would result in either "9001", or "9002".
"frontendPort": "[add(9001, copyIndex())]"
Instead, I see an error in Visual Studio's Intellisense, and when I try to deploy the solution.
Create template deployment 'deploymenttemplate-0107-1555'.
New-AzureRmResourceGroupDeployment : Resource Microsoft.Network/loadBalancers 'webserverLb'
failed with message 'Unable to process template language expressions for resource
'/subscriptions/some random guid/resourceGroups/webservers/providers/Microsoft.Network/loadBalancers/webserverLb'
at line '102' and column '10'. 'The template function 'copyIndex' is not expected at this location.
The function can only be used in a resource with copy specified.
Long story short, I'm simply trying to have the same number of NAT rules as I have VM's in the template, and dynamically assign the external port number.
Please let me know if I can provide any more information. Thank you.
Try:
[Concat(900,CopyIndex(1))]
which will offset the index (0 based) and give you the number you want.
This is the syntax that works for copying the NAT rules (I am adding an RDP rule on the standard back-end port):
"copy": [
{
"name": "inboundNatRules",
"count": "[parameters('numberOfWebInstances')]",
"input": {
"name": "[concat(parameters('lbNatRulePrefix'), copyindex('inboundNatRules'))]",
"properties": {
"frontendIPConfiguration": {
"id": "[variables('lbFrontEndIpId')]"
},
"frontendPort": "[add(50001, copyIndex('inboundNatRules'))]",
"backendPort": 3389,
"enableFloatingIP": false,
"idleTimeoutInMinutes": 4,
"protocol": "tcp"
}
}
}
],
And then to apply the rules to the NIC, you actually need to add some code on the NIC itself. The following is for both LB rules and NAT rules:
"loadBalancerBackendAddressPools": [
{
"id": "[concat(variables('lbID'), '/backendAddressPools/', parameters('lbPoolName'))]"
}
],
"loadBalancerInboundNatRules": [
{
"id": "[concat(variables('lbID'),'/inboundNatRules/' , parameters('lbNatRulePrefix'), copyindex())]"
}
]
#Your script is wrong it should you are writing copyindex() but you need to pass the name of rule it should work.
"inboundNatRules": [
{
"copy": {
"name": "natCopy",
"count": "[parameters('numberOfVms')]"
},
"name": "[concat('directHttps-', copyIndex(natCopy,1))]",
"properties": {
"frontendIPConfiguration": {
"id": "[concat(variables('lbID'),'/frontendIPConfigurations/LoadBalancerFrontEnd')]"
},
"frontendPort": "[add(9001, copyIndex(natCopy,1))]",
"backendPort": 9001,
"enableFloatingIP": false,
"idleTimeoutInMinutes": 4,
"protocol": "Tcp",
"backendIPConfiguration": {
"id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('vmNicName'), copyIndex(natCopy,1)), 'ipconfig')]"
}
}
}
$LoadBalancer = Get-AzureRmLoadBalancer -ResourceGroupName $ResourceGroupName -Name $LoadBalancerName
$publicIP1 = Get-AzureRmPublicIpAddress -name $pipName -resourcegroupname $ResourceGroupName
$frontendIP1 = Get-AzureRmLoadBalancerFrontendIpConfig -LoadBalancer $LoadBalancer -Name $FrontendIpConfigName
$LoadBalancer | Add-AzureRmLoadBalancerInboundNatRuleConfig -Name "nat_rule_tcp_IP1_49157" -FrontendIpConfiguration $frontendIP1 -IdleTimeoutInMinutes 4 -Protocol TCP -FrontendPort 49157 -BackendPort 49157 | Set-AzureRmLoadBalancer

OrientDB ETL edge lookup from query - how to access $input?

I'm trying my darnedest to do an ETL import from a large dataset that I've been keeping in MongoDB. I've successfully imported the vertices, and I feel like I'm one little syntax misunderstanding away from importing the edges too.
I am pretty sure that the error is in this transformer:
{"edge":{"class":"Friend", "joinFieldName":"id",
"lookup": "select from Character WHERE $input.id IN character_friends",
"unresolvedLinkAction":"CREATE"}},
So what I'm trying to do is to make an edge from a document with id = FOO to all other documents that contain FOO in their character_friends array.
If I execute
select from Character WHERE FOO IN character_friends
in the browser, I get a ton of documents, so my guess is that my problem is with $input.id either not returning the id I'm expecting, or maybe not being recognized as a variable at all.
Documents look like this:
{
id: FOO,
character_friends: [BAR, BAZ, QUX]
(and a bunch of other junk)
}
Seems you're inserting a property "id", but it's reserved in Blueprints standard. You can rename it (with "field" transformers) or set this in Orient Loader:
standardElementConstraints: false,
Then I've created the file /temp/datasets/charles.json with this content:
[
{
name: "Joe",
id: 1,
friends: [2,4,5],
enemies: [6]
},
{
name: "Suzie",
id: 2,
friends: [1,4,6],
enemies: [5,2]
}
]
And this pipeline:
{
config: {
log: "debug",
parallel: false
},
source : {
file: { path: "/temp/datasets/charles.json", lock : true }
},
extractor : {
json: {}
},
transformers : [
{ merge: { joinFieldName:"id", lookup:"Account.id" } },
{ vertex: { class: "Account"} },
{ edge: {
"class": "Friend",
"joinFieldName": "friends",
"lookup": "Account.id",
"unresolvedLinkAction": "CREATE"
} },
{ edge: {
"class": "Enemy",
"joinFieldName": "enemies",
"lookup": "Account.id",
"unresolvedLinkAction": "CREATE"
} }
],
loader : {
orientdb: {
dbURL: "plocal:/temp/databases/charles",
dbUser: "admin",
dbPassword: "admin",
dbAutoDropIfExists: true,
dbAutoCreate: true,
standardElementConstraints: false,
tx: false,
wal: false,
batchCommit: 1000,
dbType: "graph",
classes: [{name: 'Account', extends:"V"}, {name: 'Friend', extends:"E"}, {name: 'Enemy', extends:"E"}],
indexes: [{class:"Account", fields:["id:integer"], type:"UNIQUE_HASH_INDEX" }]
}
}
}
Assure to use last version of ETL jar (replace it in $ORIENTDB/lib) with default version. Last version is downloadable from:
https://oss.sonatype.org/content/repositories/snapshots/com/orientechnologies/orientdb-etl/2.0.2-SNAPSHOT/orientdb-etl-2.0.2-20150208.225903-1.jar
Or get OrientDB ETL 2.0.2 of major.

Resources