Python script not working

I have downloaded the system and everything and I have two problems mainly to see if you can lend me a hand.

First of all I would like to say that I’m triying to use my own python script after de system recognise of the different commands. I have changed the profile as appears in the official documentation but nothing happens when I say one command. What could be happening? How can I see where is the problem?

On the other hand, someone knows why Porcupine don’t works now?

Which version of Rhasspy? There was a bug in the Porcupine code of the Rhasspy 2.5 prerelease.

My rhasspy version is 2.4.18.

I haven’t tested this version for a while, so I can’t help you with that.

As for the Python script: are you using MQTT/Hermes in your script or do you run it as a local intent handler script? You are sure that Rhasspy detects the intents your script has to react to?

About Porcupine now I´m using Snowboy, so is no important problem.

My idea is that after having a command recognized by Rhasspy a python program is run that works based on the input json to be able to make certain requests later with POST.

What I have done has been to configure the profile as indicated in Documentation but nothing happens when it detects the different commands (which detects them correctly already displayed in the LOG tab)

What does your Python program look like? Is it executable? (Make it executable with chmod +x nameofscript.py)

If I execute the command as you indicate, I don’t see any errors or anything strange.

I enclose the code below, it is a very simple code since it is an initial test:

#!/usr/bin/env python

import sys
import json
import random
import datetime

import io
import requests
import socket
from adapt.intent import IntentBuilder


def speech(text):
    global o
    o["speech"] = {"text": text}


# get json from stdin and load into python dict
o = json.loads(sys.stdin.read())

intent = o["intent"]["name"]
msg = o["text"]

if intent == "GetTime":
    now = datetime.datetime.now()
    speech("It's %s %d %s." % (now.strftime('%H'), now.minute, now.strftime('%p')))

elif intent == "Hello":
    replies = ['Hi!', 'Hello!', 'Hey there!', 'Greetings.']
    speech(random.choice(replies))

elif intent == "PercentageControl":
    percentage_control(self,msg)
    replies = ['Okey', 'Done!', 'Adjusted as your like']
    speech(random.choice(replies))

elif intent == "ChangeState":
    things_onoff(self,msg)
    replies = ['Okey', 'Done!', 'Adjusted as your like']
    speech(random.choice(replies))

# convert dict to json and print to stdout
print(json.dumps(o))



    def send_post_openhab(self,item, signal): 
        URL= 'http://10.5.55.3:8080/rest/items/'+item
        headers = {
            'Content-Type': 'text/plain',
            'Accept': 'application/json',
        }

        data = signal
        url_archivo_salida = 'response.xml'

        try:
            resp = requests.post( URL, headers = headers, data = data )

        except Exception as e:
            print( 'The exception >> ' + type(e).__name__ )
            raise e

        else:
            #requests.codes.ok = 200 => OK
            if( resp.status_code == requests.codes.ok ):
                with open( url_archivo_salida, 'w' ) as f:
                    f.write( resp.text )
                    f.close()
            else:
                out = 'resp.status_code >> ' + str(resp.status_code) + ' != ' + str(requests.codes.ok) 

    def percentage_control(self,msg):

        utterance = msg.data["utterance"]
        number = str(extract_number(utterance))

        if "lights" in msg.data.get('utterance') or "light" in msg.data.get('utterance'):
            if "kitchen" in msg.data.get('utterance'):           
                if "to" in msg.data.get('utterance'):
                    self.send_post_openhab("Kitchen_Dimmer", number)          
            if "living room" in msg.data.get('utterance'):           
                if "to" in msg.data.get('utterance'):
                    self.send_post_openhab("LR_Dimmer", number) 

        if "blinds" in msg.data.get('utterance'):
            if "kitchen" in msg.data.get('utterance'):
                if "up" in msg.data.get('utterance') or "raise" in msg.data.get('utterance') :
                    self.send_post_openhab("Blind1", "0")
                    self.send_post_openhab("Blind2", "0")
                if "down" in msg.data.get('utterance') or "lower" in msg.data.get('utterance'):
                    self.send_post_openhab("Blind1", "100")
                    self.send_post_openhab("Blind2", "100")            
                elif "to" in msg.data.get('utterance'):
                    self.send_post_openhab("Blind1", number)
                    self.send_post_openhab("Blind2", number)                                  
                    self.send_post_openhab("Blind3", number)                               


    def things_onoff(self,msg):
        print (msg.data.get('utterance'))

        if "lights" in msg.data.get('utterance') or "light" in msg.data.get('utterance'):
            if "kitchen" in msg.data.get('utterance'):
                if "table" in msg.data.get('utterance'):
                    if "on" in msg.data.get('utterance'):          
                        self.send_post_openhab("Kitchen1", "ON")
                    if "off" in msg.data.get('utterance'):
                        self.send_post_openhab("Kitchen1", "OFF")          
                elif "work" in msg.data.get('utterance'):
                    if "on" in msg.data.get('utterance'):          
                        self.send_post_openhab("Kitchen2", "ON")
                    if "off" in msg.data.get('utterance'):
                        self.send_post_openhab("Kitchen2", "OFF")          
                else:
                    if "on" in msg.data.get('utterance'):          
                        self.send_post_openhab("Kitchen_Dimmer", "100")
                    if "off" in msg.data.get('utterance'):
                        self.send_post_openhab("Kitchen_Dimmer", "0")                                     

                

    def stop(self):
        pass

I would suggest to start with something much more simple, such as this one. If this works, you know the error is in your script and not in Rhasspy’s intent handling.

The first step to solve this issue is figuring out exactly what is going wrong. Define a json inside your script that has the same format as the one you expect to be handled and run your script manually from the console. Also check if the answer looks like it should. If your script manually the next step is figuring out if it is called from rhasspy at all. To do that you could write into log file from your python script and then check if there is an entry.

Nor does anything happen if I put that code as indicated in the path of the profile.json. It is as if the corresponding program will not be executed because nothing happens.

In addition I get the following problem: “HomeAssistantIntentHandler Can’t contact server” I understand that it appears to me by the configuration of the command as such, although I do not want to use Haas

The initial problem I think is that the Python program does not run as such after detecting a command since nothing happens or testing with the example they have told me. I don’t know what I can do to make it really run or what I’m doing wrong

On the other hand, I’m sorry for not knowing how it is, but can you be more explanatory to me as it would be to check if my code works as such? How could I execute the code by seeing how it takes the json data in the program from the previous message?

Basically your script is a python script and you can run it with the normal console instead of with rhasspy. If it is not called by rhasspy then it needs to get the json data from somewhere so you need to put that into your skript and then run it. If your skript outputs a valid json (and it should if it works) then we know that there is no error in the skript itself preventing it from running and that the skript can run. That rules out a few possibilities of why it doesn’t work

So basically figure out how to define a json in python, put it in your o variable instead of reading stdin

It is a good idea to check where the error is, I just did it and the program runs without any problem so that the problem I understand is how to configure rhasspy to run the program when a command is detected. I have made the configuration of the profile as indicated so that I do not know where the error may be.

Now the next step is to add a log entry or something to your skript. That way something in your file system changes when the program is run. Test the logging with a manual start and if your log works try it with rhasspy and you will know if your skript is called from rhasspy. If it is then rhasspy either doesn’t give you data the way you expect it or you don’t give data back the way rhasspy expects it. If it doesn’t run then you know rhasspy has some problem executing the script.

I have added to the program that a txt file is created every time the code is executed, if I execute it manually if it is created. So the script is not running. What I have done has been to add to the profile.json the lines indicated in the documentation. Perhaps it is not the correct way to do it, or do I have to do something else or different for the program to run after detecting a command?

Only thing I can think of is to check the path. The documentation gives you a few variables to specify the path to your script, did you use them? If not, try using one to create the path because that might be throwing it off. If you are using docker the path that you use on the console will not be the same as the one rhasspy needs because docker is something like a different system when run.

That if I didn’t know, if I am using a docker and I have set the normal path that appears when pwd when the file appears. How should I do being a docker?

  • $RHASSPY_BASE_DIR - path to the directory where Rhasspy is running from
  • $RHASSPY_PROFILE - name of the current profile (e.g., “en”)
  • $RHASSPY_PROFILE_DIR - directory of the current profile (where profile.json is)

That is in the documentation. So you pick one of those you want to use, I personally would go with the $RHASSPY_BASE_DIR. Then you make sure that your script is somewhere in that base dir. I would make a folder there called scripts or so and then put the script there. Then the path for your script would be $RHASSPY_BASE_DIR/scripts/my_script.py.

Then your rhasspy will resolve $RHASSPY_BASE_DIR to the directory where it is running from and then find the file.

It still does not work, I believe that the fault is in the profile.json or that I am leaving something to do. The profile.json that I am using is the following:

> {
    "handle": {
        "command": {
            "program": "$RHASSPY_BASE_DIR/scripts/ex1.py"
        },
        "forward_to_hass": true
    },
    "microphone": {
        "pyaudio": {
            "device": "5"
        }
    },
    "wake": {
        "system": "snowboy"
    }
}

I am not able to detect the failure.

I do not have a running rhasspy to test stuff on so I am just going by the documentation. The “handle” part there has two lines more than yours and at least one of them looks like it is needed for it to work.

"handle": {
  "system": "command",
  "command": {
  "program": "$RHASSPY_BASE_DIR/scripts/ex1.py",
  "arguments": []
  },
  "forward_to_hass": true
}

Try this, if it doesn’t work doublecheck that your script folder is really in the folder that rhasspy calls home.