forked from nightscout/cgm-remote-monitor
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d767102
commit 202402f
Showing
10 changed files
with
292 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
Nightscout Google Home/DialogFlow Plugin | ||
======================================== | ||
|
||
## Overview | ||
|
||
To add Google Home support for your Nightscout site, here's what you need to do: | ||
|
||
1. Activate the `googlehome` plugin on your Nightscout site, so your site will respond correctly to Google's requests. | ||
2. Create a custom DialogFlow agent that points at your site and defines certain questions you want to be able to ask. (You'll copy and paste a basic template for this, to keep things simple.) | ||
3. Create desired integrations with DialogFlow | ||
|
||
|
||
## Activate the Nightscout Google Home Plugin | ||
|
||
1. Your Nightscout site needs to be new enough that it supports the `googlehome` plugin. . | ||
2. Add `googlehome` to the list of plugins in your `ENABLE` setting. ([Environment variables](https://github.com/nightscout/cgm-remote-monitor#environment) are set in the configuration section for your monitor. Typically Azure, Heroku, etc.) | ||
|
||
## Create Your DialogFlow Agent | ||
|
||
### Signin to DialogFlow | ||
|
||
- Sign in to DialogFlow with your Google account (https://console.dialogflow.com/api-client/#/login). If you don't already have one, signup with Google. | ||
|
||
### Create a new custom DialogFlow agent | ||
|
||
1. Select "Create new agent" in the main menu bar. | ||
2. Input a custom name for your agent and click "CREATE". | ||
3. Download the simple agent template : ( https://drive.google.com/drive/folders/18z2kQSEInvH4O_jfjB4Qh8z9508P9Oao?usp=sharing ) | ||
4. Select IMPORT FROM ZIP , in order to import the template. | ||
5. SAVE | ||
6. Go to "Fullfillment" menu and enter details about your webhook. | ||
7. SAVE | ||
8. Go to "Integration" menu and select your desired integration. | ||
9. Follow instructions for each desired integration. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
'use strict'; | ||
|
||
var _ = require('lodash'); | ||
var moment = require('moment'); | ||
|
||
function configure (app, wares, ctx, env) { | ||
var express = require('express'); | ||
var api = express.Router(); | ||
var entries = ctx.entries; | ||
var translate = ctx.language.translate; | ||
|
||
// invoke common middleware | ||
api.use(wares.sendJSONStatus); | ||
// text body types get handled as raw buffer stream | ||
api.use(wares.bodyParser.raw()); | ||
// json body types get handled as parsed json | ||
api.use(wares.bodyParser.json()); | ||
|
||
ctx.plugins.eachEnabledPlugin(function each(plugin) { | ||
if (plugin.googleHome) { | ||
if (plugin.googleHome.intentHandlers) { | ||
console.log('Plugin ' + plugin.name + ' is Google Home enabled'); | ||
_.each(plugin.googleHome.intentHandlers, function (handler) { | ||
if (handler) { | ||
ctx.googleHome.configureIntentHandler(handler.intent, handler.intentHandler, handler.routableSlot, handler.slots); | ||
} | ||
}); | ||
} | ||
} else { | ||
console.log('Plugin ' + plugin.name + ' is not Google Home enabled'); | ||
} | ||
}); | ||
|
||
ctx.googleHome.configureIntentHandler('CurrentMetric', function (result, next, sbx) { | ||
entries.list({count: 1}, function(err, records) { | ||
var response = ''; | ||
if (records && records.length > 0) { | ||
var direction = ''; | ||
if (records[0].direction === 'FortyFiveDown') { | ||
direction = ' and slightly dropping'; | ||
} else if (records[0].direction === 'FortyFiveUp') { | ||
direction = ' and slightly rising'; | ||
} else if (records[0].direction === 'Flat') { | ||
direction = ' and holding'; | ||
} else if (records[0].direction === 'SingleUp') { | ||
direction = ' and rising'; | ||
} else if (records[0].direction === 'SingleDown') { | ||
direction = ' and dropping'; | ||
} else if (records[0].direction === 'DoubleDown') { | ||
direction = ' and rapidly dropping'; | ||
} else if (records[0].direction === 'DoubleUp') { | ||
direction = ' and rapidly rising'; | ||
} | ||
response = buildPreamble(result.parameters); | ||
response += sbx.scaleMgdl(records[0].sgv) + direction + ' as of ' + moment(records[0].date).from(moment(sbx.time)); | ||
} else { | ||
response = buildPreamble(result.parameters) + 'unknown'; | ||
} | ||
next(response); | ||
}); | ||
}, 'metric', ['bg', 'blood glucose', 'blood sugar', 'number']); | ||
|
||
api.post('/googlehome', ctx.authorization.isPermitted('api:*:read'), function (req, res, next) { | ||
console.log('Incoming request from Google Home'); | ||
onIntent(req.body, function (response) { | ||
res.json(ctx.googleHome.buildResponse(response)); | ||
next(); | ||
}); | ||
}); | ||
|
||
function buildPreamble(parameters) { | ||
var preamble = ''; | ||
if (parameters && parameters.givenName) { | ||
preamble = parameters.givenName + '\'s current '; | ||
} else { | ||
preamble = 'Your current '; | ||
} | ||
if (parameters && parameters.readingType) { | ||
preamble += parameters.readingType + ' is '; | ||
} else { | ||
preamble += 'blood glucose is '; | ||
} | ||
return preamble; | ||
} | ||
|
||
function onIntent(body, next) { | ||
console.log('Received intent request'); | ||
console.log(JSON.stringify(body)); | ||
handleIntent(body, next); | ||
} | ||
|
||
// https://docs.api.ai/docs/webhook#section-format-of-request-to-the-service | ||
function handleIntent(body, next) { | ||
var displayName = body.queryResult.intent.displayName; | ||
var metric = body.queryResult.parameters ? body.queryResult.parameters.metric : null; | ||
var handler = ctx.googleHome.getIntentHandler(displayName, metric); | ||
if (handler) { | ||
var sbx = initializeSandbox(); | ||
handler(body.queryResult, next, sbx); | ||
} else { | ||
next('I\'m sorry I don\'t know what you\'re asking for'); | ||
} | ||
} | ||
|
||
function initializeSandbox() { | ||
var sbx = require('../../sandbox')(); | ||
sbx.serverInit(env, ctx); | ||
ctx.plugins.setProperties(sbx); | ||
return sbx; | ||
} | ||
|
||
return api; | ||
} | ||
|
||
module.exports = configure; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
|
||
function init(env, ctx) { | ||
|
||
console.log('Configuring Google Home...'); | ||
|
||
function googleHome() { | ||
return googleHome; | ||
} | ||
|
||
var intentHandlers = {}; | ||
|
||
googleHome.configureIntentHandler = function configureIntentHandler(intent, handler, routableSlot, slotValues) { | ||
if (!intentHandlers[intent]) { | ||
intentHandlers[intent] = {}; | ||
} | ||
if (routableSlot && slotValues) { | ||
for (var i = 0, len = slotValues.length; i < len; i++) { | ||
if (!intentHandlers[intent][routableSlot]) { | ||
intentHandlers[intent][routableSlot] = {}; | ||
} | ||
if (!intentHandlers[intent][routableSlot][slotValues[i]]) { | ||
intentHandlers[intent][routableSlot][slotValues[i]] = {}; | ||
} | ||
intentHandlers[intent][routableSlot][slotValues[i]].handler = handler; | ||
} | ||
} else { | ||
intentHandlers[intent].handler = handler; | ||
} | ||
}; | ||
|
||
googleHome.getIntentHandler = function getIntentHandler(intentName, metric) { | ||
if (intentName && intentHandlers[intentName]) { | ||
if (metric && intentHandlers[intentName]['metric'] && | ||
intentHandlers[intentName]['metric'][metric] && | ||
intentHandlers[intentName]['metric'][metric].handler) { | ||
return intentHandlers[intentName]['metric'][metric].handler; | ||
} else if (intentHandlers[intentName].handler) { | ||
return intentHandlers[intentName].handler; | ||
} else { | ||
return null; | ||
} | ||
} else { | ||
return null; | ||
} | ||
|
||
}; | ||
|
||
googleHome.buildResponse = function buildResponse(output) { | ||
return { | ||
fulfillmentText: output | ||
// , fulfillmentMessages: [output] | ||
, source: 'Nightscout' | ||
}; | ||
}; | ||
|
||
return googleHome; | ||
} | ||
|
||
module.exports = init; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
202402f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See nightscout#4035 for mdomox's original work.