bbrookfield / alexa-radiothermostat

8 stars 6 forks source link

Add hold temp on and off? #3

Open kevinsickles opened 8 years ago

kevinsickles commented 8 years ago

This is a request and not an issue, and completely understand if the answer is no. but would love to add the ability to set a hold temperature and turn hold off. I will take a shot but confidence is very low

the curl is: Hold on (for airconditioning)
curl -d '{"tmode":2,"t_cool":82,"hold":1}' http://192.168.15.75/tstat

Hold Off curl -d '{"tmode":2,"hold":0}' http://192.168.15.75/tstat

tball78 commented 7 years ago

Hope this helps others with the radiothermostat.

I edited the index.js in the alexa-radiothermostat module to add some additional logic to turn hold on/off and to turn fan on/off. Also, I added logic to increase/decrease temp by specified number of degrees. I revised logic of existing code to check if thermostat was in heat or cool mode so that the code could modify t_heat or t_cool to set temperature or increase/decrease temperature.

I have also revised responses from Alexa to report actual house temp, report which mode thermostat is set to (such as heat or cool or off), and the target temperature when querying Alexa for current temperature.

See attached file. Should be saved as index.js in alexa-radiothermostat module folder.

Here is updated Intents Schema for the Alexa Skill Service to use the new code:

{ "intents": [ { "intent": "getTemp", "slots": [{ "name": "getTemperature", "type": "AMAZON.LITERAL" }] }, { "intent": "setHeat", "slots": [{ "name": "setHeating", "type": "AMAZON.NUMBER" }] }, { "intent": "setCool", "slots": [{ "name": "setCooling", "type": "AMAZON.NUMBER" }] }, { "intent": "setOff" }, { "intent": "setFanOn" }, { "intent": "setFanAuto" }, { "intent": "setHoldOn" }, { "intent": "setHoldOff" }, { "intent": "incTemp", "slots": [{ "name": "increaseTemp", "type": "AMAZON.NUMBER" }] }, { "intent": "decTemp", "slots": [{ "name": "decreaseTemp", "type": "AMAZON.NUMBER" }] } ] }

Here are sample utterances for the updated skill to utilize new fan, hold, increase/decrease temp functionality:

setOff turn off thermostat setOff turn off the thermostat setOff set thermostat to off setFanOn turn on fan setFanOn turn on furnace fan setFanAuto turn off fan setFanAuto turn off furnace fan setFanOn set fan to on setFanOn set furnace fan to on setFanAuto set fan to off setFanAuto set furnace fan to off setFanAuto set fan to auto setFanAuto set furnace fan to auto setHoldOn turn on hold setHoldOn set hold to on setHoldOff turn off hold setHoldOff set hold to off setHeat set heat to {setHeating} setCool adjust cool to {setCooling} setHeat adjust heat to {setHeating} setCool set cool to {setCooling} setCool adjust air conditioning to {setCooling} setCool set air to {setCooling} setCool adjust air to {setCooling} setHeat adjust the heat to {setHeating} setCool adjust the air conditioning to {setCooling} setCool set ac to {setCooling} setCool set air conditioning to {setCooling} getTemp what is the temperature getTemp what is the temperature getTemp what is temperature getTemp what is house temperature getTemp what's the house temperature getTemp what's the temperature getTemp say the temperature getTemp tell me the temperature getTemp tell me temperature

save_as_index_js.txt

tball78 commented 7 years ago

GoodComputerGuy,

I setup the SSL endpoint required for the skill on a raspberry pi versus Lambda or Heroku. To do so, I used Let's encrypt to generate certs/keys and I modded the app.js (for the node-alexa-server) that runs the node server to force nodejs to setup an SSL server versus http and add path to SSL certs and key. I also modded the code near the end of app.js to just use port 9000 for the secureServer versus passing port number via command line.

I've attached my app.js for node-alexa-server if you want to take peek. Feel free to compare this to the original app.js to see where I made changes.

I've yet to try with Lamdba since I got it working via SSL endpoint.

Hope this helps.

Regards,

Terry

On Thu, Dec 8, 2016 at 3:41 PM, GoodComputerGuy notifications@github.com wrote:

This is great - I'll update my install with the added functionality as soon as I get it working. I have the skill set up ok but am having trouble with the js scripts. I've tried both locally in Node.js and up on Lambda but I have not been successful yet. Is there anyone around who has this all working and can help me out? I'm close, but no cigar quite yet.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bbrookfield/alexa-radiothermostat/issues/3#issuecomment-265849496, or mute the thread https://github.com/notifications/unsubscribe-auth/ASZSo3utmN2rMTjzRkgkjZp48y6Sg6ZCks5rGGuMgaJpZM4JzNif .

// Requires for this skill var express = require('express'); routes = require('routes') var forceSSL = require('express-force-ssl'); var bodyParser = require('body-parser'); var path = require('path'); var fs = require('fs'); var async = require('async'); var http = require('http'); var https = require('https'); var privateKey = fs.readFileSync('/home/pi/apps/node-alexa-server-master/private-key.pem', 'utf8'); var certificate = fs.readFileSync('/home/pi/apps/node-alexa-server-master/certificate.pem', 'utf8'); var credentials = { key: privateKey, cert: certificate }; var app = express(); var secureServer = https.createServer(credentials, app); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json());

/*

function init(cb) { var modulePath = path.resolve(path.join(__dirname, './app_modules')); fs.readdir(modulePath, function(err, services) { var moduleArray = []; services.forEach(function(module) { moduleArray.push(require('./app_modules/' + module)); }); async.series(moduleArray, function(err, results) { if (err) { console.error(err); } else { cb(); } }); }); }

init(function() { // Manually hook the handler function into express app.post('/:service', function(req, res) { //console.log(req.body); // console.log(req.params); global[req.params.service].request(req.body) .then(function(response) { console.log(response); res.json(response); }); }); //var httpsServer = https.createServer(credentials, app); secureServer.listen(9000); });

tball78 commented 7 years ago

One other thing... I had to add https://sslendpoint.yourdomain.com/thermostat in the configuration for the skill. Adding the URL only for my endpoint did not work. It had to have the /thermostat after it.

Regards,

Terry

On Thu, Dec 8, 2016 at 3:41 PM, GoodComputerGuy notifications@github.com wrote:

This is great - I'll update my install with the added functionality as soon as I get it working. I have the skill set up ok but am having trouble with the js scripts. I've tried both locally in Node.js and up on Lambda but I have not been successful yet. Is there anyone around who has this all working and can help me out? I'm close, but no cigar quite yet.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bbrookfield/alexa-radiothermostat/issues/3#issuecomment-265849496, or mute the thread https://github.com/notifications/unsubscribe-auth/ASZSo3utmN2rMTjzRkgkjZp48y6Sg6ZCks5rGGuMgaJpZM4JzNif .

GoodComputerGuy commented 7 years ago

Thanks, tball. That might be exactly what I'm looking for. I've been playing around with a lot of different home automation stuff and this will help a lot. Right now I have a bunch of different ways to interact with my 2 thermostats - this script, openHAB, a new SmartThings hub I'm trying (2 different ways via SmartThings too.) So far this script is the best but I have had intermittent luck with Heroku, can't get the "handler" field right in Lambda, and failed to get the Alexa skill to connect to my node.js script, although I got close. I have an SSL certificate already so implementing your script above should work for me pretty easily. And then I don't have to leave my thermostats exposed to the Internet either. At some point I'd also like to figure out how to run Node.js behind Apache or nginx, too.

tball78 commented 7 years ago

That is what I just did. The script I just sent you sent you was my prior revision of the script (needing SSL) that I had before implementing nginx. I now use the base app.js published on node-alexa-server github project (with exception of forcing the port 9000) and implemented the SSL in nginx. I agree with your logic that is a better way to go. By doing that, I was able to allow HomeAssistant and Alexa skill to both enjoy SSL encryption.

This is a pretty good link for nginx implementation:

http://www.htpcguides.com/secure-nginx-reverse-proxy-with-lets-encrypt-on-ubuntu-16-04-lts/

Had to utilize the stretch repos for raspberry pi jessie distribution to get nginx new enough to use this procedure, but it worked well after it was upgraded. Make sure to turn of the basic authentication that nginx implements using this howto for the /thermostat location or your Alexa skill will fail SSL handshake.

Good luck.

Regards,

Terry

On Mon, Dec 12, 2016 at 6:32 PM, GoodComputerGuy notifications@github.com wrote:

Thanks, tball. That might be exactly what I'm looking for. I've been playing around with a lot of different home automation stuff and this will help a lot. Right now I have a bunch of different ways to interact with my 2 thermostats - this script, openHAB, a new SmartThings hub I'm trying (2 different ways via SmartThings too.) So far this script is the best but I have had intermittent luck with Heroku, can't get the "handler" field right in Lambda, and failed to get the Alexa skill to connect to my node.js script, although I got close. I have an SSL certificate already so implementing your script above should work for me pretty easily. And then I don't have to leave my thermostats exposed to the Internet either. At some point I'd also like to figure out how to run Node.js behind Apache or nginx, too.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bbrookfield/alexa-radiothermostat/issues/3#issuecomment-266587947, or mute the thread https://github.com/notifications/unsubscribe-auth/ASZSo0uMwly8BTM4NY2z8ZvV4BtnzQlXks5rHdmigaJpZM4JzNif .

GoodComputerGuy commented 7 years ago

Getting closer but not quite there yet. I figured out how to npm routes and express-force-ssl although that "routes" line in your script looks odd to me. That's not formatted like the other vars? I understand networking (it's how I make my living) and do some development but this stuff here is all new to me and I am not sure how to troubleshoot this script.

I'm able to get the same response from https://my_server.com:9000/thermostat as I get from Heroku (which is to say, not much - "Cannot GET /thermostat" but Alexa works with the version at Heroku.) Actually I think the same thing happened with my implementation of node.js running SSL, which I had done slightly differently than you. But when it didn't work I figured I screwed something up.

But when I test the Alexa skill I still get "The remote endpoint could not be called, or the response it returned was invalid." There doesn't seem to be anything to troubleshoot here.

So... any more hints?

tball78 commented 7 years ago

Hmmm... yeah... looks like that var for route is dorked up... I'm sure you've likely corrected it by now.

Here was site I utilized when adapting the node-alexa-server for SSL.... I am fairly new to nodejs/express myself...

http://www.gettingcirrius.com/2012/06/securing-nodejs-and-express-with-ssl.html

I would expect a couldn't GET if you just try to browse to it... I get the same but Alexa can still communicate with it on port 9000.

I'll keep thinking here to see if I have any other ideas... one other thing I remembered doing was installing:

npm install -g npm-check-updates

and from the node-alexa-server folder, I ran npm-check-updates -u (or ncu -u using shortcut) which verified and or updated anything that needed it.

And since you are network pro, assuming all is well with port forwarding on your router where you are forwarding port 9000 outside to 443 inside to your host running nodejs.

Regards,

Terry

.

On Mon, Dec 12, 2016 at 8:40 PM, GoodComputerGuy notifications@github.com wrote:

Getting closer but not quite there yet. I figured out how to npm routes and express-force-ssl although that "routes" line in your script looks odd to me. That's not formatted like the other vars? I understand networking (it's how I make my living) and do some development but this stuff here is all new to me and I am not sure how to troubleshoot this script.

I'm able to get the same response from https://my_server.com/thermostat as I get from Heroku (which is to say, not much - "Cannot GET /thermostat" but Alexa works with the version at Heroku.) Actually I think the same thing happened with my implementation of node.js running SSL, which I had done slightly differently than you. But when it didn't work I figured I screwed something up.

But when I test the Alexa skill I still get "The remote endpoint could not be called, or the response it returned was invalid." There doesn't seem to be anything to troubleshoot here.

So... any more hints?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bbrookfield/alexa-radiothermostat/issues/3#issuecomment-266609936, or mute the thread https://github.com/notifications/unsubscribe-auth/ASZSo0cUGJuNsNjR2A-YTGVPz63_lKL8ks5rHfeCgaJpZM4JzNif .

GoodComputerGuy commented 7 years ago

I'll check that site out tomorrow but I'm pretty sure this is up and running properly on SSL. Also, as far as the networking goes, port 9000 is just being forwarded to the machine running node.js which is listening on port 9000 anyway, not 443. Verified because I can hit it at https://10.1.1.8:9000 (although of course there is an SSL error if I do that.)

Argh - this should work! Or kick back an error message that I could troubleshoot instead of just leaving me high and dry.

tball78 commented 7 years ago

Ugh... I didn't say what I meant to say in last email... I reversed it... Amazon Alexa Skill Service wants to talk https/SSL on 443 coming into your router so you need to have ssl/443 on outside of router forwarded to port 9000 on inside to the nodejs server (running ssl on 9000). That is how I had the port forwarding when I was using this script. Now with nginx config, I have 443 outside being forwarded to 443 inside to nginx host.

Hope this helps...

On Mon, Dec 12, 2016 at 9:48 PM, GoodComputerGuy notifications@github.com wrote:

I'll check that site out tomorrow but I'm pretty sure this is up and running properly on SSL. Also, as far as the networking goes, port 9000 is just being forwarded to the machine running node.js which is listening on port 9000 anyway, not 443. Verified because I can hit it at https://10.1.1.8:9000 (although of course there is an SSL error if I do that.)

Argh - this should work! Or kick back an error message that I could troubleshoot instead of just leaving me high and dry.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bbrookfield/alexa-radiothermostat/issues/3#issuecomment-266620713, or mute the thread https://github.com/notifications/unsubscribe-auth/ASZSo_02P-U3nxHsNR5zcaqtfWRgg0Kdks5rHgeMgaJpZM4JzNif .

GoodComputerGuy commented 7 years ago

Oooooohhhhhh.... That crossed my mind but I used http://my_server.com:9000/thermostat in the Alexa skill and it didn't barf at me so I thought it was OK. That could be the whole problem. Would have been REALLY nice to get an error message about that though. Unfortunately I have other things running on 443 on that IP address but I may be able to run this somewhere else. I'll check on this tomorrow.

tball78 commented 7 years ago

Yeah... i only have http://my_server.com/thermostat in Alexa skill. Well... another use case for nginx where you could have nginx terminate ssl/443 and forward to different locations (aka sites) that then do not have to be https and can then be http. That is how I am servicing radiothermostat skill and Home Assistant via nginx. If you temporarily forward 443 to 9000, and change skill endpoint by removing the :9000, it would likely work.

Terry

On Mon, Dec 12, 2016 at 10:13 PM, GoodComputerGuy notifications@github.com wrote:

Oooooohhhhhh.... That crossed my mind but I used http://my_server.com:9000/thermostat in the Alexa skill and it didn't barf at me so I thought it was OK. That could be the whole problem. Would have been REALLY nice to get an error message about that though. Unfortunately I have other things running on 443 on that IP address but I may be able to run this somewhere else. I'll check on this tomorrow.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bbrookfield/alexa-radiothermostat/issues/3#issuecomment-266624936, or mute the thread https://github.com/notifications/unsubscribe-auth/ASZSo1Eq4Hvf6qNzM5l1nObxUMI2bvgvks5rHg1ugaJpZM4JzNif .

GoodComputerGuy commented 7 years ago

OK, quick test showed that was it! At least I'm connecting now and am getting an SSL error message in the Alexa skill that I can troubleshoot (strange though - that SSL certificate shows fine in the browser and is in use on my production server.)

But... if I have to run only on 443 I don't think that's going to work for me. I have a couple thermostats that need to be accessed separately as well as my company server running my help desk and other critical stuff on 443 on a completely different machine. I don't know anything about nginx but I'm thinking I might be better off going back to trying to get this to work on Lambda again.

tball78 commented 7 years ago

Yep... that is the bummer... As far as I know since they are routing to an https address can only have one 443 coming into the router. I suppose you can research to see if they will allow other ports. I'm running mine at home so no big deal to run small nginx instance to route the web sites to different folders on the host. Good luck and good chatting with you.

Regards,

Terry

GoodComputerGuy commented 7 years ago

I'll have to look into this some more. It's all running on various machines on my home based consulting business. Might be able to figure something out to separate the traffic. Thanks for cluing me into that key point that I have to run this on 443. Good stuff...

tball78 commented 7 years ago

One more thought... the /thermostat in the config line of skill corresponds to the "Invocation Name" that I configured in the skill so I could say "Echo...ask thermostat...what is the temperature?" Yours may be different and if so, you would use https://my-server.com/myinvocationname. That may explain your SSL error you got after port forwarding 443 to 9000.

On Mon, Dec 12, 2016 at 10:41 PM, GoodComputerGuy notifications@github.com wrote:

I'll have to look into this some more. It's all running on various machines on my home based consulting business. Might be able to figure something out to separate the traffic. Thanks for cluing me into that key point that I have to run this on 443. Good stuff...

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bbrookfield/alexa-radiothermostat/issues/3#issuecomment-266632380, or mute the thread https://github.com/notifications/unsubscribe-auth/ASZSozk6GjyG9ZZKhMQdwYCmglW2yXUJks5rHhP5gaJpZM4JzNif .

GoodComputerGuy commented 7 years ago

I wouldn't think that part would cause an SSL error but I could be wrong. Thanks again for your help!

tball78 commented 7 years ago

No worries. Glad to help. Take care.

GoodComputerGuy commented 7 years ago

Another followup to this topic if anyone comes looking: I got it all working locally with the original script modified as tball78 mentioned (listen locally on 9000) and his excellent additions. The easiest way to make this work securely is to use Caddy reverse proxy, which uses Let's Encrypt and can be set up in all of about 30 seconds. I'm glad I found that before I tried to get it working with nginx!