node-red-contrib-alexa-smart-home
Version:
Integrate Alexa and Google Assistant / Google Home in your Node-RED flows.
418 lines (393 loc) • 15.3 kB
HTML
<!--
Copyright 2016 IBM Corp.
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.
-->
<script type="text/x-red" data-template-name="alexa-smart-home-v3-conf">
<div class="form-row">
<label for="node-config-input-username" style="width:130px"><i class="icon-tag"></i> Username</label>
<input type="text" id="node-config-input-username">
</div>
<div class="form-row">
<label for="node-config-input-password" style="width:130px"><i class="icon-tag"></i> Password</label>
<input type="password" id="node-config-input-password">
</div>
<div class="form-row">
<label for="node-config-input-mqttserver" style="width:130px"><i class="icon-tag"></i> MQTT Hostname</label>
<input type="text" id="node-config-input-mqttserver">
</div>
<div class="form-row">
<label for="node-config-input-webapiurl" style="width:130px"><i class="icon-tag"></i> Web API Hostname</label>
<input type="text" id="node-config-input-webapiurl">
</div>
<div class="form-row" title="Select the Node-RED context store to use with this Node.">
<label for="node-config-input-contextName" style="width:130px"><i class="icon-tag"></i> Context Store</label>
<select id="node-config-input-contextName"></select>
<div id="contextName-hint"></div>
<br />
<div class="form-tips">
This node requires a Node-RED memory-based <a href='https://nodered.org/docs/user-guide/context' target="_blank">context store</a>.
</div>
</div>
</script>
<script type="text/x-red" data-help-name="alexa-smart-home-v3-conf">
<p>If you don't have an account on the bridge create one
<a target="_blank" href="https://red.cb-net.co.uk">here</a>.</p>
</script>
<script type="text/javascript">
// ## Modified to include mqtt / webapi services ??
RED.nodes.registerType("alexa-smart-home-v3-conf", {
category: "config",
defaults: {
username: {},
mqttserver: { value: "mq-red.cb-net.co.uk" },
webapiurl: { value: "red.cb-net.co.uk" },
contextName: { value: "default" },
},
credentials: {
username: { type: "text" },
password: { type: "password" },
},
color: "#D3D3D3",
label: function () {
return this.username;
},
oneditsave: function () {
var node = this;
var user = $("#node-config-input-username").val();
var pass = $("#node-config-input-password").val();
var mqttserver = $("#node-config-input-mqttserver").val();
var webapiurl = $("#node-config-input-webapiurl").val();
// console.log('***** saving context store: ' + $('#node-config-input-contextName').val());
console.log("pass: ", pass);
if (pass != "_PWD_") {
var account = {
id: node.id,
user: user,
pass: pass,
mqtt: mqttserver,
webapi: webapiurl,
};
$.ajax({
data: JSON.stringify(account),
url: "alexa-smart-home-v3/new-account",
contentType: "application/json",
type: "POST",
processData: false,
});
}
},
oneditprepare: function () {
var node = this;
var contextName = node.contextName || undefined;
// console.log('***** settings: ' + JSON.stringify(RED.settings));
for (let store of RED.settings.context.stores) {
// console.log('***** adding store: ' + store);
$("<option/>", {
value: store,
text: store,
}).appendTo("#node-config-input-contextName");
}
if (contextName != "default" && contextName != undefined)
$("#node-config-input-contextName").val(node.contextName).change();
},
});
</script>
<script type="text/x-red" data-template-name="alexa-smart-home-v3">
<div class="form-row">
<label for="node-input-conf"><i class="icon-tag"></i> Account</label>
<input type="text" id="node-input-conf">
</div>
<div class="form-row">
<label for="node-input-device"><i class="icon-tag"></i> Device</label>
<select id="node-input-device">
</select>
<a id="node-input-device-refresh" class="red-ui-button"><i class="fa fa-refresh"></i></a>
</div>
<div class="form-row">
<label> </label>
<input type="checkbox" id="node-input-acknowledge" style="display: inline-block; width: auto; vertical-align: top;">
<label for="node-input-acknowledge" style="width: 70%"> Auto Acknowledge</span>
</div>
<div class="form-row">
<label for="node-input-topic"><i class="icon-tag"></i> Topic</label>
<input type="text" id="node-input-topic">
</div>
<input type="hidden" id="node-input-name">
</div>
</script>
<script type="text/x-red" data-help-name="alexa-smart-home-v3">
<p>This node provides a Device endpoint for the Alexa/ Google Assistant device bridge.
To use this node you will need to create an account and declare some devices
<a target="_blank" href="https://red.cb-net.co.uk">here</a>.
You will also need to link the skill with your Amazon Echo/ Google account</p>
<p>Instructions can be found
<a target="_blank" href="https://red.cb-net.co.uk/docs">here</a></p>
<p>The <i>Topic</i> field is optional and will be added to any messages sent from
the node.</p>
<p>Auto Acknowledge tells Alexa the command succeeded no matter what. If you un-tick
this option you will need to add a <i>Alexa Home Response</i> node to the flow, injecting
msg.acknowledge into your flow.</p>
</script>
<script type="text/javascript">
RED.nodes.registerType("alexa-smart-home-v3", {
category: "alexa",
defaults: {
conf: { value: "", type: "alexa-smart-home-v3-conf" },
device: { value: "" },
acknowledge: { value: true },
name: {},
topic: {},
},
outputs: 1,
inputs: 0,
color: "#D3D3D3",
icon: "alexa.png",
label: function () {
return this.name || "Alexa Smart Home v3";
},
oneditsave: function () {
var n = $("#node-input-device option:selected").text();
//console.log("selected name " + n);
this.name = n;
$("#node-input-name").val(n);
},
oneditprepare: function () {
var node = this;
//console.log("foo " + node.device);
if (typeof node.acknowledge === "undefined") {
$("#node-input-acknowledge").prop("checked", true);
}
$("#node-input-device").change(function () {
$("#node-input-name").val(
$("#node-input-device option:selected").text()
);
});
var getDevs = function (account) {
$.getJSON("alexa-smart-home-v3/devices/" + account, function (data) {
$("#node-input-device").find("option").remove().end();
for (d in data) {
console.log(
"device info:",
data[d].endpointId,
data[d].friendlyName
);
$("<option/>", {
value: parseInt(data[d].endpointId),
text: data[d].friendlyName,
}).appendTo("#node-input-device");
}
if (node.device) {
$("#node-input-device").val(node.device);
}
}).fail(function (jqXHR, textStatus, errorThrown) {
console.log("problem getting devices");
console.log(textStatus);
});
};
if (node.conf) {
var account = $("#node-input-conf").val();
console.log("account: ", account);
if (account != "_ADD_") {
getDevs(account);
}
}
$("#node-input-conf").change(function () {
var account = $("#node-input-conf").val();
console.log("account changed: ", account);
if (account != "_ADD_") {
getDevs(account);
} else {
console.log("new account");
$("#node-input-device").find("option").remove().end();
$("#node-input-device").val("");
}
});
$("#node-input-device-refresh").click(function () {
$("#node-input-device-refresh").addClass("disabled");
var account = $("#node-input-conf").val();
$.ajax({
url: "alexa-smart-home-v3/refresh/" + account,
type: "POST",
}).done(function (data) {
setTimeout(function () {
getDevs(account);
$("#node-input-device-refresh").removeClass("disabled");
}, 3000);
});
});
},
});
</script>
<!-- ############################################################################################## -->
<script type="text/x-red" data-template-name="alexa-smart-home-v3-state">
<div class="form-row">
<label for="node-input-conf"><i class="icon-tag"></i> Account</label>
<input type="text" id="node-input-conf">
</div>
<div class="form-row">
<label for="node-input-device"><i class="icon-tag"></i> Device</label>
<select id="node-input-device">
</select>
<a id="node-input-device-refresh" class="red-ui-button"><i class="fa fa-refresh"></i></a>
</div>
<input type="hidden" id="node-input-name">
</div>
</script>
<script type="text/x-red" data-help-name="alexa-smart-home-v3-state">
<p>This node provides state reporting to the Web App.</p>
<p>Place this node after Alexa Smart Home v3, MQTT out or similar nodes.</p>
<p>Expects specific inbound message format, namely msg.payload.state and msg.acknowledge elements:</p>
<pre>
msg {
acknowledge: true,
payload {
state {
"brightness": 0-100,
"colorBrightness": 0-1,
"colorHue": 0-360,
"colorSaturation": 0-1,
"colorTemperature": 0-10000,
"contact" : "DETECTED" || "NOT_DETECTED",
"input": string,
"lock": "LOCKED" || "UNLOCKED",
"mode" : string,
"motion" : "DETECTED" || "NOT_DETECTED",
"mute" : "ON" || "OFF",
"percentage": number,
"percentageDelta": number,
"playback": playback,
"power": "ON" || "OFF",
"rangeValue" : number,
"rangeValueDelta" : number,
"temperature": number,
"thermostatMode": "HEAT" || "COOL",
"thermostatSetPoint" : number,
"targetSetpointDelta": number,
"volume": number,
"volumeDelta": number
}
}
}
</pre>
<p>Failure to include msg.acknowledge (set to true, not "true") will result in the state update being discarded.</p>
</script>
<script type="text/javascript">
RED.nodes.registerType("alexa-smart-home-v3-state", {
category: "alexa",
defaults: {
conf: { value: "", type: "alexa-smart-home-v3-conf" },
device: { value: "" },
name: {},
topic: {},
},
outputs: 0,
inputs: 1,
color: "#D3D3D3",
icon: "alexa.png",
label: function () {
return this.name || "Alexa Smart Home v3 State";
},
oneditsave: function () {
var n = $("#node-input-device option:selected").text();
//console.log("selected name " + n);
this.name = n;
$("#node-input-name").val(n);
},
oneditprepare: function () {
var node = this;
$("#node-input-device").change(function () {
$("#node-input-name").val(
$("#node-input-device option:selected").text()
);
});
var getDevs = function (account) {
$.getJSON("alexa-smart-home-v3/devices/" + account, function (data) {
$("#node-input-device").find("option").remove().end();
for (d in data) {
console.log(
"device info:",
data[d].endpointId,
data[d].friendlyName
);
$("<option/>", {
value: parseInt(data[d].endpointId),
text: data[d].friendlyName,
}).appendTo("#node-input-device");
}
if (node.device) {
$("#node-input-device").val(node.device);
}
}).fail(function (jqXHR, textStatus, errorThrown) {
console.log("problem getting devices");
console.log(textStatus);
});
};
if (node.conf) {
var account = $("#node-input-conf").val();
console.log("account: ", account);
if (account != "_ADD_") {
getDevs(account);
}
}
$("#node-input-conf").change(function () {
var account = $("#node-input-conf").val();
console.log("account changed: ", account);
if (account != "_ADD_") {
getDevs(account);
} else {
console.log("new account");
$("#node-input-device").find("option").remove().end();
$("#node-input-device").val("");
}
});
$("#node-input-device-refresh").click(function () {
$("#node-input-device-refresh").addClass("disabled");
var account = $("#node-input-conf").val();
$.ajax({
url: "alexa-smart-home-v3/refresh/" + account,
type: "POST",
}).done(function (data) {
setTimeout(function () {
getDevs(account);
$("#node-input-device-refresh").removeClass("disabled");
}, 3000);
});
});
},
});
</script>
<!-- ############################################################################################## -->
<script
type="text/x-red"
data-template-name="alexa-smart-home-v3-resp"
></script>
<script type="text/x-red" data-help-name="alexa-smart-home-v3-resp">
<p>This node sends a response to Alexa to acknowledge if the command
succeeded or not. To use this node you will need to un check the
<i>Auto Acknowledge</i> check box in the Alexa Home node that starts
the flow. Responses must be sent with in 2 seconds of
receiving the request otherwise a timeout message will be returned
to the Alexa service.</p>
<p>The message must come from the Alexa Home input node and expects msg.acknowledge to be either true or false.</p>
</script>
<script type="text/javascript">
RED.nodes.registerType("alexa-smart-home-v3-resp", {
category: "alexa",
defaults: {},
inputs: 1,
outputs: 0,
color: "#D3D3D3",
icon: "alexa.png",
label: function () {
return this.name || "Alexa Smart Home v3 Response";
},
});
</script>