Haaska test error

Hi all,

I’m trying to set up Haaska and ran into a problem. I don’t know if this is a configuration problem or a code problem.

I set everything up based on the instructions laid out on github GitHub - auchter/haaska: Home Assistant Alexa Skill Adapter.

My AWS logs shows a JSONDecodeError after trying to discover devices in the Alexa app.

Expecting value: line 4 column 17 (char 105): JSONDecodeError
Traceback (most recent call last):
File “/var/task/haaska.py”, line 655, in event_handler
config = Configuration(‘config.json’)
File “/var/task/haaska.py”, line 617, in init
self._json = json.load(f)
File “/var/lang/lib/python3.6/json/init.py”, line 299, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File “/var/lang/lib/python3.6/json/init.py”, line 354, in loads
return _default_decoder.decode(s)
File “/var/lang/lib/python3.6/json/decoder.py”, line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File “/var/lang/lib/python3.6/json/decoder.py”, line 357, in raw_decode
raise JSONDecodeError(“Expecting value”, s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 4 column 17 (char 105)

Trying to run “make test” ends up with the same error.

pi@raspberrypi:~/haaska $ make test
{
“errorMessage”: “Expecting value: line 4 column 17 (char 105)”,
“errorType”: “JSONDecodeError”,
“stackTrace”: [
[
“/var/task/haaska.py”,
655,
“event_handler”,
“config = Configuration(‘config.json’)”
],
[
“/var/task/haaska.py”,
617,
init”,
“self._json = json.load(f)”
],
[
“/var/lang/lib/python3.6/json/init.py”,
299,
“load”,
“parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)”
],
[
“/var/lang/lib/python3.6/json/init.py”,
354,
“loads”,
“return _default_decoder.decode(s)”
],
[
“/var/lang/lib/python3.6/json/decoder.py”,
339,
“decode”,
“obj, end = self.raw_decode(s, idx=_w(s, 0).end())”
],
[
“/var/lang/lib/python3.6/json/decoder.py”,
357,
“raw_decode”,
“raise JSONDecodeError("Expecting value", s, err.value) from None”
]
]
}
null
Makefile:38: recipe for target ‘test’ failed
make: *** [test] Error 1

Any ideas?

its been a year since i deployed this and then removed it after. But to me it looks like you aren’t supplying the test with the correct information. Its getting “None” when it should be getting some sort of JSON.

Also, IIRC you need to have all the code in the right spots with that. You need Lambda and the developer side communicating with each other. It’s alot of configuring.

Have you tried using Bruh automations hasska setup? The video is out of date by about 2 years but the information is still relevant. I believe the UI has changed for amazon developers and lambda. so you might fumble through that process.

Other than that, your error doesn’t have much to go off of.

Now that i think about it…

I’m still using haaska for my tv volume control and crap.

IIRC you also need to have home assistant responding to your tests. Otherwise the test will not work.

This is an example of my automations with alexa:

Intents:

{
  "intents": [
    {
      "intent": "LocateIntent",
      "slots": [ { "name": "User", "type": "Users" } ]
    },
    {
      "intent": "WhereAreWeIntent",
      "slots": []
    },
    {
      "intent": "RunScriptIntent",
      "slots": [ { "name" : "Script", "type" : "Scripts" } ]
    },
    {
      "intent": "ActivateSceneIntent",
      "slots": [ { "name" : "Scene", "type" : "Scenes" } ]
    },
    {
      "intent": "QuestionPersonIntent",
      "slots": [ { "name" : "Person", "type" : "Persons" } ]
    },
    {
      "intent": "SetVolumeIntent",
      "slots": [  { "name" : "Level", "type" : "Levels" } ]
    },
    {
      "intent": "VolumeUpIntent",
      "slots": []
    },
    {
      "intent": "VolumeDownIntent",
      "slots": []
    },
    {
      "intent": "VolumeMuteIntent",
      "slots": [ {"name": "DoWhat", "type": "DoWhats"}]
    },
    {
      "intent": "ChangeInputIntent",
      "slots": [ { "name" : "Input", "type": "Inputs" } ]
    }
  ] 
}

utterances:

LocateIntent Where is {User}
LocateIntent Where's {User}
LocateIntent Where {User} is
LocateIntent Where did {User} go

WhereAreWeIntent where we are

RunScriptIntent run {Script}
RunScriptIntent enter {Script}
RunScriptIntent start {Script}
RunScriptIntent engage {Script}

ActivateSceneIntent activate {Scene}

QuestionPersonIntent tell me about {Person}
QuestionPersonIntent tell me what you think about {Person}
QuestionPersonIntent what do you think of {Person}
QuestionPersonIntent describe {Person}
QuestionPersonIntent about {Person}
QuestionPersonIntent who is {Person}

SetVolumeIntent set the tv volume to {Level}
SetVolumeIntent set volume of the tv to {Level}
SetVolumeIntent set the volume to {Level}
SetVolumeIntent set volume to {Level}
SetVolumeIntent set volume {Level}
SetVolumeIntent set the volume level to {Level}
SetVolumeIntent set the volume to {Level} decibels
SetVolumeIntent volume {Level}

VolumeUpIntent turn up the tv volume
VolumeUpIntent turn the tv volume up
VolumeUpIntent turn up the volume
VolumeUpIntent turn the volume up
VolumeUpIntent volume up

VolumeDownIntent turn down the tv volume
VolumeDownIntent turn the tv volume down
VolumeDownIntent turn down the volume
VolumeDownIntent turn the volume down
VolumeDownIntent volume down

VolumeMuteIntent {DoWhat} volume
VolumeMuteIntent volume {DoWhat}
VolumeMuteIntent {DoWhat} TV
VolumeMuteIntent TV {DoWhat}

ChangeInputIntent switch to {Input}

I don’t have examples of slots… they are just lists of available sayings that to into your utterances. Example: Person slot would be a list of people by name that you expect to say.

Alexa home assistant yaml:

  WhereAreWeIntent:
    speech:
      type: plain
      text: >
       {{ REDACTED }}
  
  LocateIntent:
    speech:
      type: plain
      text: >
        {{ REDACTED }}
          
  RunScriptIntent:
    action:
      service: script.turn_on
      data_template:
        entity_id: script.{{ Script | replace(" ", "_") }}
    speech:
      type: plain
      text: OK
      
  ActivateSceneIntent:
    action:
      service: scene.turn_on
      data_template:
        entity_id: scene.{{ Scene | replace(" ", "_") }}
    speech:
      type: plain
      text: OK

  QuestionPersonIntent:
    speech:
      type: plain
      text: >
        {{ REDACTED }}
        
  SetVolumeIntent:
    action:
      service: media_player.volume_set
      data_template:
        entity_id: media_player.yamaha_receiver
        volume_level: >-
          {%- if Level|int in range(10,81) -%}
            {%- set n = Level|float -%}
            {{ (1.0-( n / 100.0 )) | round(2) }}
          {%- endif -%}
    speech:
      type: plain
      text: OK
    
  VolumeUpIntent:
    action:
      service: media_player.volume_set
      data_template:
        entity_id: media_player.yamaha_receiver
        volume_level: >
          {% if is_state('media_player.yamaha_receiver', 'on')  %}
            {% set n = states.media_player.yamaha_receiver.attributes.volume_level | float %}
            {% if n <= 0.85 %}
              {{ n + 0.05 | round(2) }}
            {% endif %}
          {% endif %}
    speech:
      type: plain
      text: OK
      
  VolumeDownIntent:
    action:
      service: media_player.volume_set
      data_template:
        entity_id: media_player.yamaha_receiver
        volume_level: >
          {% if is_state('media_player.yamaha_receiver', 'on')  %}
            {% set n = states.media_player.yamaha_receiver.attributes.volume_level | float %}
            {% if n >= 0.25 %}
              {{ n - 0.05 | round(2) }}
            {% endif %}
          {% endif %}
    speech:
      type: plain
      text: OK
      
  VolumeMuteIntent:
    action:
      service: media_player.volume_mute
      data_template:
        entity_id: media_player.yamaha_receiver
        is_volume_muted: >
          {% if is_state('media_player.yamaha_receiver', 'on')  %}
            {% if DoWhat.lower() in ['mute'] %}
              true
            {% elif DoWhat.lower() in ['unmute'] %}
              false
            {% else %}
              false
            {% endif %}
          {% else %}
            false
          {% endif %}
    speech:
      type: plain
      text: OK
      
  ChangeInputIntent:
    action:
      service: media_player.select_source
      data_template:
        entity_id: media_player.yamaha_receiver
        source: >
          {% if is_state('media_player.yamaha_receiver', 'on')  %}
            {% if Input.lower() in ['xbox','xbox one'] %}
              Xbox One
            {% elif Input.lower() in ['playstation','ps4'] %}
              Playstation 4
            {% elif Input.lower() in ['wii', 'wii u', 'we', 'we u', 'we you'] %}
              Wii U
            {% elif Input.lower() in ['computer','pc'] %}
              PC
            {% elif Input.lower() in ['apple tv','switch'] %}
              Apple Tv
            {% elif Input.lower() in ['phone','aux'] %}
              Phone
            {% elif Input.lower() in ['blue tooth', 'echo'] %}
              Echo
            {% else %}
              Xbox One
            {% endif %}
          {% else %}
            Xbox One
          {% endif %}
    speech:
      type: plain
      text: OK

I appreciate the response! It looks like the app and the lambda function are communicating, as this same error shows up in the lambda logs when I try to discover devices, but I can’t tell if it’s reaching Home Assistant. There’s no connection error though.

Yes I’ve watched Bruh’s video as well as followed these instructions: https://pastebin.com/aucq7sDY. There’s no mention of doing anything on the Home Assistant side with what you’re talking about. I think you’re confusing Haaska with a custom Alexa skill rather than a smart home Alexa skill.

As for the test, from my understanding I’m running the Alexa discovery test which is the most basic test. It should work out of the box.

@petro

I’m not sure if you misunderstand the difference between haaska and the alexa intents schema or I misunderstood your post above (and yes it was probably me).

In case it’s the former:

Haaska and Alexa Intents are not the same thing.

To use alexa intents you have to specifically spell out the actions HA is to take in response to the utterances that you also have to define. And you have to use an additional action phrase (i.e. “tell Automation to…”) to get alexa to perform the action.

Haaska exposes devices directly to alexa natively (or as best as I can understand the term) so it shows up as a device in the app. All you then have to do to operate it is say “alexa, turn on…”. no other action word required. I like it better and use it for everything I use alexa to control.

If it’s the latter…never mind…:wink:

@mnl1121

I set haaska up a few months back and wrote up a procedure on how I got it working since the BRUH’s video and the procedure on the Haaska github didn’t work for me.

Here is my procedure:

https://pastebin.com/Dzzr9K8X

I can’t guarantee it will work since things seem to change frequently on how you are suppose to do enable it. But it might be worth a shot

1 Like

Yeah, I set this up a year ago. Thought I used hasska to deliver my intents. Might be some other method. I don’t use hasska for turning on and off my devices. Switched that to emulated hue because its 2-4 seconds faster. I still thought that the hasska lambda function passed my intents over. Maybe I wrote something else…

Thanks for the instructions, I’m going to try it right now. I’m going to try fresh.

I got it working! Thank you @finity! So 3 things I needed to do for anyone else that encounters this error. To start I was using the wrong port, I wasn’t using port 443. I also forgot quotes around ca-certificates.crt from instructions below found from https://pastebin.com/aucq7sDY

Edit the file to include your IP address:port and api password (for secured setups use your dns domain and port 443)
Edit parameter to “expose_by_default”: false
Edit parameter to “ssl_verify”: “ca-certificates.crt”

Third was to change the payload version to V2. It’s disabled on Amazon, but only though HTML, if you inspect the element via Chrome/Firefox you can delete “disabled=“disabled””. This will allow you to to choose V2.

Note that fixing the first 2 things I mentioned here allowed to test the lambda function successfully and it discovered all my Home Assistant devices, however until I chose Payload v2, the Alexa app wasn’t able to discover my devices.