Error and microphone problems

{
    "dialogue": {
        "satellite_site_ids": "home assistant, pi zero 2w",
        "system": "rhasspy"
    },
    "handle": {
        "satellite_site_ids": "home assistant, pi zero 2w",
        "system": "hass"
    },
    "home_assistant": {
        "access_token": "redacted",
        "url": "http://192.168.178.red:8123"
    },
    "intent": {
        "satellite_site_ids": "home assistant, pi zero 2w",
        "system": "fsticuffs"
    },
    "microphone": {
        "pyaudio": {
            "device": "default device"
        },
        "system": "arecord"
    },
    "mqtt": {
        "enabled": "",
        "host": "192.168.178.red",
        "password": "redacted",
        "site_id": "home assistant",
        "username": "redacted"
    },
    "sounds": {
        "system": "aplay"
    },
    "speech_to_text": {
        "kaldi": {
            "language_model_type": "arpa",
            "mix_weight": "0"
        },
        "satellite_site_ids": "home assistant, pi zero 2w",
        "system": "pocketsphinx"
    },
    "text_to_speech": {
        "larynx": {
            "default_voice": "nathalie",
            "vocoder": "vctk_small",
            "volume": "0.7"
        },
        "satellite_site_ids": "home assistant, pi zero 2w",
        "system": "larynx"
    },
    "wake": {
        "porcupine": {
            "keyword_path": "grasshopper_raspberry-pi.ppn",
            "sensitivity": "0.4"
        },
        "satellite_site_ids": "home assistant, pi zero 2w",
        "system": "porcupine"
    }
}

This is the base station. Strangely the HassGetTime does work now but the HassGetDate doesn’t

{
    "handle": {
        "satellite_site_ids": "home assistant, pi zero 2w",
        "system": "hass"
    },
    "home_assistant": {
        "access_token": "redacted",
        "url": "http://192.168.178.red:8123"
    },
    "intent": {
        "system": "hermes"
    },
    "microphone": {
        "arecord": {
            "device": "default:CARD=S330",
            "siteId": "home assistant, pi zero 2w"
        },
        "system": "arecord"
    },
    "mqtt": {
        "enabled": "true",
        "host": "192.168.178.red",
        "password": "redacted",
        "site_id": "pi zero 2w",
        "username": "redacted"
    },
    "sounds": {
        "aplay": {
            "device": "default:CARD=S330",
            "volume": "0.4"
        },
        "system": "aplay"
    },
    "speech_to_text": {
        "system": "hermes"
    },
    "text_to_speech": {
        "larynx": {
            "default_voice": "nathalie",
            "vocoder": "vctk_small"
        },
        "satellite_site_ids": "home assistant, pi zero 2w",
        "system": "hermes"
    },
    "wake": {
        "porcupine": {
            "keyword_path": "alexa_raspberry-pi.ppn"
        },
        "satellite_site_ids": "home assistant, pi zero 2w",
        "system": "porcupine"
    }
}

This satellite configuration gives me double the sentence when I ask for the time for example. At least I can conclude that it does work. Both the base and the satellite do work just not all the time. Thanks to your help and guide I am much further then I ever was.

Since you are setup for the same mqtt broker a couple of suggestions:

  1. On your satellites you shouldn’t have any satelite_site_ids specified;
  2. You should consider disabling Dialog and Intent handling on your satellite
  3. home assistant, doesn’t need to be specified in your satelite_site_ids on your base

Thanks for your suggestion. I had those settings but it didn’t work. I have changed it back now but still the same. The base station does recognize my wakeword en the intent but there is no action afterwards. Like giving me the time. The sattelite doesn’t do anything when there is no intent handler selected. Dialogue management was already disabled on the satellite. I have removed most of the satellite id’s on the satellite. Only the siteid in settings on the top is left.

You have 3 options for handling intents:

Intent Handling with HA and Events
Intent Handling with HA and Intents
Intent Handling with HA and Node Red

This only needs to be configured on your base, I personally went with the Node Red option (and so I didn’t configure Events or Intents at all, so I left the intents disabled). It allows me to put together more complex flows; like creating a timer for each satellite; get the remaining time; Play a timer done wav (at the request of my wife).

Would you mind sharing a node red example? I want to get started with node red red anyway.

Sure, I will preface this with I just started using Rhasspy this week; so I’m a bit of a newb (first drafts only). It’s very possible there are better ways of doing this.

[{"id":"fd62aedfec593c5f","type":"tab","label":"rhasspy","disabled":false,"info":"","env":[]},{"id":"03908a97249587b1","type":"mqtt in","z":"fd62aedfec593c5f","name":"","topic":"hermes/intent/#","qos":"2","datatype":"json","broker":"7ff47827abc0a6bf","nl":false,"rap":true,"rh":0,"inputs":0,"x":120,"y":260,"wires":[["97518b80b2b5205f"]]},{"id":"41be4306208c3598","type":"debug","z":"fd62aedfec593c5f","name":"mqtt intent","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":750,"y":560,"wires":[]},{"id":"32381bef6bf9e36f","type":"mqtt out","z":"fd62aedfec593c5f","name":"endSession","topic":"hermes/dialogueManager/endSession","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"7ff47827abc0a6bf","x":530,"y":80,"wires":[]},{"id":"3d422fdbfb4f9c5b","type":"template","z":"fd62aedfec593c5f","name":"text","field":"payload","fieldType":"msg","format":"json","syntax":"mustache","template":"{\"sessionId\" : \"{{sessionId}}\",\"text\": \"{{text}}\"}","output":"str","x":370,"y":80,"wires":[["32381bef6bf9e36f","344871c8282d7af9"]]},{"id":"97518b80b2b5205f","type":"change","z":"fd62aedfec593c5f","name":"","rules":[{"t":"set","p":"sessionId","pt":"msg","to":"payload.sessionId","tot":"msg"},{"t":"set","p":"siteId","pt":"msg","to":"payload.siteId","tot":"msg"},{"t":"set","p":"wakewordId","pt":"msg","to":"payload.wakewordId","tot":"msg"},{"t":"move","p":"payload","pt":"msg","to":"mqtt","tot":"msg"},{"t":"set","p":"timestamp","pt":"msg","to":"","tot":"date"}],"action":"","property":"","from":"","to":"","reg":false,"x":255,"y":260,"wires":[["344871c8282d7af9","5b93b028a2f103d7"]],"l":false},{"id":"5b93b028a2f103d7","type":"switch","z":"fd62aedfec593c5f","name":"intent","property":"mqtt.intent.intentName","propertyType":"msg","rules":[{"t":"eq","v":"GetTemperature","vt":"str"},{"t":"eq","v":"GetTime","vt":"str"},{"t":"eq","v":"TimerCancel","vt":"str"},{"t":"eq","v":"TimerSet","vt":"str"},{"t":"else"}],"checkall":"false","repair":false,"outputs":5,"x":210,"y":360,"wires":[["442daf9ba29bf19c"],["b9903708e35b2ccb"],["4ea99c44ea740857"],["aeba827af2018634"],["c1871180eecf2602"]]},{"id":"c1871180eecf2602","type":"template","z":"fd62aedfec593c5f","name":"missing","field":"text","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"uh oh, missing intent","output":"str","x":420,"y":560,"wires":[["593820bd421182d3"]]},{"id":"da39b6cbfd7ceb19","type":"link in","z":"fd62aedfec593c5f","name":"mqtt end","links":["d0dd8874b3654c72","8183de9a0324a6b6","575c8b42c3ea0a17","593820bd421182d3","d4822e524d8f184a","a801366582219385"],"x":275,"y":80,"wires":[["3d422fdbfb4f9c5b"]]},{"id":"d0dd8874b3654c72","type":"link out","z":"fd62aedfec593c5f","name":"intent out","mode":"link","links":["da39b6cbfd7ceb19"],"x":705,"y":260,"wires":[]},{"id":"442daf9ba29bf19c","type":"api-current-state","z":"fd62aedfec593c5f","name":"outside","server":"3894cb67.ddb574","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.front_door_sensor_temperature","state_type":"num","blockInputOverrides":false,"outputProperties":[{"property":"temp","propertyType":"msg","value":"","valueType":"entityState"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":420,"y":260,"wires":[["1fd4163f52fa50cf"]]},{"id":"a27b26222b2e5856","type":"template","z":"fd62aedfec593c5f","name":"temp","field":"text","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"Its currently {{temp}} degrees right now.","output":"str","x":610,"y":260,"wires":[["d0dd8874b3654c72"]]},{"id":"344871c8282d7af9","type":"debug","z":"fd62aedfec593c5f","name":"mqtt debug","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":530,"y":140,"wires":[]},{"id":"1fd4163f52fa50cf","type":"change","z":"fd62aedfec593c5f","name":"","rules":[{"t":"set","p":"temp","pt":"msg","to":"$ceil(temp)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":515,"y":260,"wires":[["a27b26222b2e5856"]],"l":false},{"id":"b9903708e35b2ccb","type":"moment","z":"fd62aedfec593c5f","name":"","topic":"","input":"timestamp","inputType":"msg","inTz":"America/Los_Angeles","adjAmount":0,"adjType":"days","adjDir":"add","format":"object","locale":"en","output":"time","outputType":"msg","outTz":"America/Los_Angeles","x":375,"y":320,"wires":[["aeee554e4aabbcd6"]],"inputLabels":["timestamp"],"outputLabels":["human timestamp"],"l":false},{"id":"c036f7c093bfdd83","type":"inject","z":"fd62aedfec593c5f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":60,"wires":[["818586d29736587b"]]},{"id":"818586d29736587b","type":"http request","z":"fd62aedfec593c5f","name":"train","method":"POST","ret":"txt","paytoqs":"ignore","url":"http://ha.lan:12101/api/train","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"credentials":{},"x":130,"y":140,"wires":[["344871c8282d7af9"]]},{"id":"aeee554e4aabbcd6","type":"function","z":"fd62aedfec593c5f","name":"time","func":"var text = \"Its \"\nvar midday = \", ey m\"\n\nif (msg.time.hours > 12) {\n    text += msg.time.hours - 12\n    midday = \", p m\"\n} else if (!msg.time.hours) {\n    text += \"12\"\n    midday = \", ey m\"\n} else {\n    text += msg.time.hours\n}\n\nif (msg.time.minutes < 10) {\n    text += \" o\"\n} \ntext += \" \" + msg.time.minutes\ntext += midday\n\nmsg.text = text\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":470,"y":320,"wires":[["8183de9a0324a6b6"]]},{"id":"8ed5c1484a22c191","type":"trigger","z":"fd62aedfec593c5f","name":"","op1":"","op2":"","op1type":"pay","op2type":"payl","duration":"1","extend":false,"overrideDelay":true,"units":"s","reset":"","bytopic":"topic","topic":"siteId","outputs":2,"x":545,"y":400,"wires":[["193829021761e5ae"],["bc7c56109464ed77"]],"l":false},{"id":"aeba827af2018634","type":"change","z":"fd62aedfec593c5f","name":"","rules":[{"t":"set","p":"s","pt":"msg","to":"$number($.mqtt.slots[slotName=\"s\"].value.value)","tot":"jsonata"},{"t":"set","p":"m","pt":"msg","to":"$number($.mqtt.slots[slotName=\"m\"].value.value)","tot":"jsonata"},{"t":"set","p":"h","pt":"msg","to":"$number($.mqtt.slots[slotName=\"h\"].value.value)","tot":"jsonata"},{"t":"set","p":"deadline","pt":"msg","to":"$flowContext(msg.siteId).timer","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":375,"y":440,"wires":[["560de57eafba3662"]],"l":false},{"id":"99c94c2d276b07bc","type":"mqtt out","z":"fd62aedfec593c5f","name":"send tts","topic":"hermes/tts/say","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"7ff47827abc0a6bf","x":960,"y":420,"wires":[]},{"id":"b4c1b74c7ef9570d","type":"template","z":"fd62aedfec593c5f","name":"text","field":"payload","fieldType":"msg","format":"json","syntax":"mustache","template":"{\"siteId\" : \"{{siteId}}\",\"text\": \"{{text}}\"}","output":"str","x":790,"y":420,"wires":[["99c94c2d276b07bc"]]},{"id":"8183de9a0324a6b6","type":"link out","z":"fd62aedfec593c5f","name":"intent out","mode":"link","links":["da39b6cbfd7ceb19"],"x":565,"y":320,"wires":[]},{"id":"575c8b42c3ea0a17","type":"link out","z":"fd62aedfec593c5f","name":"intent out","mode":"link","links":["da39b6cbfd7ceb19"],"x":765,"y":380,"wires":[]},{"id":"593820bd421182d3","type":"link out","z":"fd62aedfec593c5f","name":"intent out","mode":"link","links":["da39b6cbfd7ceb19"],"x":535,"y":560,"wires":[]},{"id":"fdeecd38a93d80e9","type":"function","z":"fd62aedfec593c5f","name":"calculate delay","func":"var id = msg.siteId + \".timer\"\nvar delay_ms = 0\nif (msg.h) {\n    delay_ms += msg.h * 600000\n}\nif (msg.m) {\n    delay_ms += msg.m * 60000\n}\nif (msg.s) {\n    delay_ms += msg.s * 1000\n}\nmsg.delay = delay_ms\nif (!msg.delay) {\n    msg.delay = 15000\n    msg.s = 15\n}\nvar deadline = msg.timestamp + delay_ms\n//node.warn(\"countdown: \" + (deadline - msg.timestamp)/1000);\nflow.set(id, deadline)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":485,"y":400,"wires":[["8ed5c1484a22c191"]],"l":false},{"id":"193829021761e5ae","type":"function","z":"fd62aedfec593c5f","name":"timer start","func":"var text = \"Okay, your timer is set for \"\nif (msg.h) {\n    text += msg.h + \" hours \"\n}\nif (msg.m) {\n    text += msg.m + \" minutes \"\n}\nif (msg.s) {\n    text += msg.s + \" seconds\"\n}\nmsg.text = text\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":650,"y":380,"wires":[["575c8b42c3ea0a17"]]},{"id":"60275641025b5638","type":"http request","z":"fd62aedfec593c5f","name":"play wav","method":"POST","ret":"txt","paytoqs":"ignore","url":"http://ha.lan:12101/api/play-wav?siteId=test","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[{"keyType":"other","keyValue":"Content-Type","valueType":"other","valueValue":"audio/wav"}],"x":460,"y":640,"wires":[["d0595951b26f27aa"]]},{"id":"ca0fae51715215e9","type":"file in","z":"fd62aedfec593c5f","name":"read file","filename":"/media/wav/timer_done.wav","filenameType":"str","format":"","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":300,"y":640,"wires":[["60275641025b5638"]]},{"id":"bfa651f70e1b5d3c","type":"inject","z":"fd62aedfec593c5f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":640,"wires":[["ca0fae51715215e9"]]},{"id":"d0595951b26f27aa","type":"debug","z":"fd62aedfec593c5f","name":"debug 5","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":620,"y":640,"wires":[]},{"id":"4ea99c44ea740857","type":"function","z":"fd62aedfec593c5f","name":"cancel timer","func":"var id = msg.siteId + \".timer\"\nvar timer = flow.get(id)\nif (timer) {\n    msg.text = \"Timer has been canceled\"\n} else {\n    msg.text = \"no, timer found\"\n}\nmsg.reset = true\nflow.set(id, null)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":375,"y":360,"wires":[["8ed5c1484a22c191","d4822e524d8f184a"]],"l":false},{"id":"d4822e524d8f184a","type":"link out","z":"fd62aedfec593c5f","name":"intent out","mode":"link","links":["da39b6cbfd7ceb19"],"x":485,"y":360,"wires":[]},{"id":"bc7c56109464ed77","type":"function","z":"fd62aedfec593c5f","name":"timer stop","func":"var id = msg.siteId + \".timer\"\nflow.set(id, null)\nmsg.text = \"Timer is done\"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":420,"wires":[["b4c1b74c7ef9570d"]]},{"id":"560de57eafba3662","type":"switch","z":"fd62aedfec593c5f","name":"","property":"deadline","propertyType":"msg","rules":[{"t":"null"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":425,"y":440,"wires":[["fdeecd38a93d80e9"],["7143a0328900e0df"]],"l":false},{"id":"7143a0328900e0df","type":"function","z":"fd62aedfec593c5f","name":"timer","func":"var remaining = Math.trunc((msg.deadline - msg.timestamp)/1000)\n// node.warn(\"remaining: \" + remaining)\nvar text = \"Time remaining is \"\nvar hours= 0\nvar mins = 0\nvar seconds = 0\nif (remaining > 3600) {\n    hours = Math.trunc(remaining/3600)\n    remaining = (remaining % 3600) \n}\nif (remaining > 60) {\n    mins = Math.trunc(remaining / 60)\n    remaining = (remaining % 60)\n}\nvar seconds = Math.trunc(remaining)\nif (hours) {\n    text += hours + \" hours \"\n}\nif (mins) {\n    text += mins + \" minutes \"\n}\nif (seconds) {\n    text += seconds + \" seconds \"\n} else {\n    text = \"Timer is running\"\n}\nmsg.text = text\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":480,"wires":[["a801366582219385","41be4306208c3598"]]},{"id":"a801366582219385","type":"link out","z":"fd62aedfec593c5f","name":"intent out","mode":"link","links":["da39b6cbfd7ceb19"],"x":675,"y":480,"wires":[]},{"id":"7ff47827abc0a6bf","type":"mqtt-broker","name":"","broker":"ha.lan","port":"1883","clientid":"nodered","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"3894cb67.ddb574","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]
[GetTime]
what time [is it]
what [is|the] time
tell [me|the] time

[GetTemperature]
what [is|the] (weather | temperature | temp)
how (hot | cold) [is it]

[TimerSet]
seconds = (0..1000){s} [sec | secs | second | seconds]
minutes = (0..1000){m} [min | mins | minute | minutes]
hours = (0..1000){h} [hour | hours]
set [a] timer for <seconds>
set [a] timer for <minutes>
set [a] timer for <hours>
set [a] timer for <minutes> [and] <seconds>
set [a] timer for <hours> [and] <minutes>
timer

[TimerCancel]
cancel timer
stop timer

Also be aware there is currently a bug in rhasspy that I will push a fix for shortly here so the play wav from a base to a satellite is broken (ie my Timer done wav)

Popi, it looks as though your Base machine is currently set to Internal MQTT. They should both be set to External with the save values 9especially the same Port number).

After I got my base+satellite configuration working, I went back and was surprised how few settings were actually required :wink:

One thing I would recommend that you add on your satellite is to enable "UDP Audio " by entering the same port number (I use 12203) in the Audio Recording and Wake Word sections. This provides a direct link from the microphone to the module which is listening just for the Wake Word (otherwise it gets sent across the network and back). Once Wake word is detected it is appropriate to send the (short) audio recording of the command to the general purpose speech_to_text module on the base machine.

OMG … i come back to finish this message and you’re already onto node-RED !!!

I think I did something similar … play an announcement over multiple satellites if the freezer (located in garage downstairs) was consuming power for too long (lid not shut ?), or was off for too long (power off ?).
My result (which I’m still using) is here. Note that I prefix the message by playing a chime.wav