UNPKG

pimatic-tts

Version:

Pimatic plugin providing Text-to-Speech capability

106 lines (79 loc) 3.35 kB
module.exports = (env) -> _ = env.require 'lodash' Promise = env.require 'bluebird' M = env.matcher commons = require('pimatic-plugin-commons')(env) class TTSActionProvider extends env.actions.ActionProvider constructor: (@framework, @config) -> parseAction: (input, context) => ttsInput = { text: input: null static: false parsed: null volume: null repeat: null interval: null device: null resource: null } SpeechDevices = _(@framework.deviceManager.devices).values().filter( (device) => device.hasAction("toSpeech") ).value() setDevice = (m, d) => ttsInput.device = d setText = (m, input) => ttsInput.text.input = input ttsInput.text.static = !@framework.variableManager.extractVariables(input).length > 0 setVolume = (m, v) => m.match([" with volume "]).matchNumber( (m, v) => ttsInput.volume = v ) setRepetition = (m, r) => m.match([" repeating "]).matchNumber( (m, r) => ttsInput.repeat = r ).match([" times"]) _setInterval = (m, w) => m.match([" every "]).matchNumber( (m, w) => ttsInput.interval = w ).match([" s", " seconds"]) m = M(input, context) .match(["speak ", "Speak ", "say ", "Say "]) .matchStringWithVars(setText) .match(" using ") .matchDevice(SpeechDevices, setDevice) .optional(setVolume) .optional(setRepetition) .optional(_setInterval) if m.hadMatch() match = m.getFullMatch() return { token: match nextInput: input.substring(match.length) actionHandler: new TTSActionHandler(@framework, @config, ttsInput) } else return null class TTSActionHandler extends env.actions.ActionHandler constructor: (@framework, @config, @ttsActionData) -> @base = commons.base @, 'Pimatic-TTS-TTSActionProvider' super() setup: () -> @dependOnDevice(@ttsActionData.device) super() executeAction: (simulate) => return new Promise( (resolve, reject) => return @framework.variableManager.evaluateStringExpression(@ttsActionData.text.input).then( (text) => @ttsActionData.text.parsed = text env.logger.debug __("TTSActionHandler - Device: '%s', Text: '%s'", @ttsActionData.device.id, @ttsActionData.text.parsed) if simulate return __("would convert Text to Speech: \"%s\"", @ttsActionData.text.parsed) else return @ttsActionData.device.toSpeech(@ttsActionData).then( (result) => env.logger.debug result resolve result ).catch( (error) => @base.rejectWithErrorString Promise.reject, error ) ).catch( (error) => @base.rejectWithErrorString Promise.reject, error ) ).catch( (error) => @base.rejectWithErrorString Promise.reject, error ) destroy: () -> super() return TTSActionProvider