alexatts – Diff between revs 2 and 4

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
Rev 2 Rev 4
Line 1... Line 1...
1 #!/usr/bin/env nodejs 1 #!/usr/bin/env nodejs
2 /////////////////////////////////////////////////////////////////////////// 2 ///////////////////////////////////////////////////////////////////////////
3 // Copyright (C) Wizardry and Steamworks 2018 - License: GNU GPLv3 // 3 // Copyright (C) Wizardry and Steamworks 2020 - License: GNU GPLv3 //
4 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // 4 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
5 // rights of fair usage, the disclaimer and warranty conditions. // 5 // rights of fair usage, the disclaimer and warranty conditions. //
6 /////////////////////////////////////////////////////////////////////////// 6 ///////////////////////////////////////////////////////////////////////////
7 7  
-   8 // Audioinjector cards: sysdefault:CARD=audioinjectorpi
-   9  
8 const Gpio = require('onoff').Gpio 10 const Gpio = require('onoff').Gpio
9 const mqtt = require('mqtt') 11 const mqtt = require('mqtt')
10 const YAML = require('yamljs'); 12 const YAML = require('yamljs')
11 const winston = require('winston') 13 const winston = require('winston')
12 const picoSpeaker = require('pico-speaker') 14 const picoSpeaker = require('pico-speaker')
-   15 const googleTTS = require('google-tts-api')
-   16 const player = require('play-sound')((opts = { player: 'mpg123' }))
-   17 const https = require('https')
-   18 const tmp = require('tmp')
-   19 const fs = require('fs')
-   20 const lambda = require('was.js').lambda
13 21  
14 // Load configuration file. 22 // Load configuration file.
15 const config = YAML.load('config.yml') 23 const config = YAML.load('config.yml')
Line 16... Line 24...
16   24  
17 // Define configuration for pico TTS. 25 // Define configuration for pico TTS.
18 var picoConfig = { 26 var picoConfig = {
19 AUDIO_DEVICE: config.card, 27 AUDIO_DEVICE: config.card,
20 LANGUAGE: config.language 28 LANGUAGE: config.language
Line 21... Line 29...
21 }; 29 }
22   30  
Line 23... Line 31...
23 // Initialize with config 31 // Initialize with config
24 picoSpeaker.init(picoConfig) 32 picoSpeaker.init(picoConfig)
25   33  
26 // Generate GPIO pins for configuration. 34 // Generate GPIO pins for configuration.
27 var ATTS = {}; -  
28 for(var i in config.GPIO) { 35 var ATTS = {}
29 if(!config.GPIO.hasOwnProperty(i)) 36 for (var i in config.GPIO) {
30 continue; -  
31 37 if (!config.GPIO.hasOwnProperty(i)) continue
32 if(config.GPIO[i] === -1) 38  
33 continue; 39 if (config.GPIO[i] === -1) continue
34 40  
35 ATTS[i] = new Gpio(config.GPIO[i], 'out') 41 ATTS[i] = new Gpio(config.GPIO[i], 'out')
36 } 42 }
37 43  
38 // Set up logger. 44 // Set up logger.
39 winston.add(winston.transports.File, {filename: config.log}) 45 winston.add(winston.transports.File, { filename: config.log })
-   46  
-   47 // Initiate connection to MQTT.
-   48 const client = mqtt.connect(config.mqtt.url)
-   49  
-   50 function mqttSubscribeCallback (err, granted) {
-   51 if (err) {
-   52 winston.info(`Unable to subscribe to MQTT topic ${config.mqtt.topic}`)
-   53 return
40 54 }
41 // Initiate connection to MQTT. 55 winston.info(`Subscribed to MQTT topic ${config.mqtt.topic}`)
42 const client = mqtt.connect(config.mqtt.url, {queueQoSZero: false}) 56 }
43 57  
44 client.on('connect', function () { 58 client.on('connect', () => {
45 winston.info('Connected to MQTT server') 59 winston.info(`Connected to MQTT server ${config.mqtt.url}`)
-   60 client.subscribe(config.mqtt.topic, {}, mqttSubscribeCallback)
-   61 })
-   62  
-   63 client.on('error', () => {
46 client.subscribe(config.mqtt.topic) 64 winston.error(`Unable to connect to MQTT server ${config.mqtt.url}`)
47 }) 65 })
48 -  
49 client.on('message', function (topic, message) { 66  
50 if(message.length === 0) 67 client.on('message', (topic, message) => {
51 return; 68 if (message.length === 0) return
52 -  
53 // Remove any retained message. -  
54 client.publish(topic, "", {retain: true}) -  
55 -  
56 message = message.toString() -  
57 winston.info('Received message: ' + message) -  
58   -  
59 ATTS["ptt"].write(1, (err) => { -  
60 if(err) { -  
Line -... Line 69...
-   69  
-   70 // Remove any retained message.
-   71 client.publish(topic, '', { retain: true })
-   72  
61 winston.err('Unable to press push-to-talk button: ' + err.message) 73 speakMessage = `${config.alexa}, Simon says, ${message.toString()}`
62 return; 74 winston.info(`Received MQTT message: ${message}`)
-   75  
-   76 if (config.tts.use === 'google' && speakMessage.length > 100) {
-   77 winston.error(
-   78 `Total spoken message would be too long: ${speakMessage.length} characters out of ${config.tts.google.maxLength}`
-   79 )
-   80 return
-   81 }
63 } 82  
-   83 winston.info(`Sending to Alexa: ${speakMessage}`)
-   84 ATTS['ptt'].write(1, err => {
Line -... Line 85...
-   85 if (err) {
-   86 winston.error(`Unable to press push-to-talk button: ${err}`)
-   87 return
-   88 }
-   89  
-   90 lambda.switch(
-   91 config.tts.use,
-   92 tts => {
-   93 winston.error(`Unknown TTS engine selected`)
-   94 },
-   95 tts => tts === 'google',
-   96 tts => {
-   97 googleTTS(speakMessage, 'en', config.tts.google.speed)
-   98 .then(url => {
-   99 winston.info(`Google TTS URL obtained: ${url}`)
-   100  
-   101 tmp.tmpName((err, path) => {
-   102 if (err) {
-   103 winston.error(`Unable to create temporary file: ${err}`)
-   104 return
-   105 }
-   106  
-   107 const file = fs
-   108 .createWriteStream(path)
-   109 .on('error', err => {
-   110 winston.error(
-   111 `Writing temporary file ${path} failed with error ${err}`
-   112 )
-   113 })
-   114 .on('finish', () => {
-   115 winston.info(`Google TTS file stored at ${path}`)
-   116 winston.info(`Speaking...`)
-   117 player.play(path, err => {
-   118 if (err) {
-   119 winston.error(`Unable to play the sound file: ${err}`)
-   120 }
-   121 ATTS['ptt'].write(0)
-   122 winston.info(`Done`)
-   123 })
-   124 })
-   125 .on('end', () => {
-   126 file.close()
-   127 })
-   128  
-   129 https.get(url, (res, err) => {
-   130 res.pipe(file)
-   131 })
-   132 })
-   133 })
-   134 .catch(err => {
-   135 winston.error(`Google TTS error: ${err}`)
-   136 })
-   137  
-   138 return true
-   139 },
64   140 tts => tts === 'picotts',
-   141 tts => {
-   142 picoSpeaker.speak(speakMessage).then(() => {
65 // Send the message. 143 winston.info('Message ' + speakMessage + ' sent to Alexa.')
-   144  
-   145 ATTS['ptt'].write(0)
66 picoSpeaker.speak(config.alexa + ", Simon says, " + message).then(function() { 146 })
67 winston.info('Message ' + message + ' sent to Alexa.') 147