How to use siteID in action code snippets?

I want to add home assistant actions to my intents. Following the guide, right now I have:

"""
location = data.get('roomName')
obj = data.get('lightType')

if location is not None:
  logger.info('turnOnLight at ' + location)
  entity_id = 'group.light_{}'.format(location)
  service_data = {'entity_id': entity_id }
  hass.services.call('group', 'turn_on', service_data, False)
elif obj is not None:
  logger.info('turnOnLight object ' + obj)
  entity_id = 'light.{}'.format(obj)
  service_data = {'entity_id': entity_id }
  hass.services.call('light', 'turn_on', service_data, False)
else:
  logger.info('turnOnLight at siteID')"""

The intent can either be for a dedicated object (“desktop lamp”), for a location (“living room”) or without context. For the last case, I want to control the light at the current location, which is the snips siteID in case someone uses base + satellites.
How can I access the siteID in the above code?

E.g. something like this:

...
else:
  logger.info('turnOnLight at ' + siteID)

  siteID = data.get('siteID')
  entity_id = 'light.{}'.format(siteID)
  service_data = {'entity_id': entity_id }
  hass.services.call('light', 'turn_on', service_data, False)

Oh and 2 more questions about this, since I dont fully understand it:

  1. How is snips knowing how to talk to home assistant? Is it via MQTT, and I just need the mqtt: component in HA, or is it via REST interface (how to I specify the home assistant server and port?)

  2. What effect is the " Home Assistant component" having which I can pick in the console for the home assistat action? I am writing the service call in the python snippet anyway, so what is it good for?

1 Like

I’m just getting started with Snips, so I can’t offer any suggestions, but I am also interested in knowing how to accomplish this.

If I figure it out over the next few days I’ll be sure to let you know!

FYI: I’ve decided to switch to app actions via git, as this will provide the most flexibility anyway. There is a pretty easy and straight forward template for this, and the hermes python reference is also pretty simple and easy.

Another benefit is that you can easily run the python script manually in the console, without the need to publish/update your assistant installation, as it is really just listening on the MQTT topics.

Regarding my first additional question:
As I had the home assistant actions still in place when installing my assistant (sam install assistant), I was asked during installation whether or not home assistant is already installed on that host. If you would say no, it would install home assistant for you, if you confirm that it is installed, it will complain about a missing installation if it isnt actually installed. This leads me to believe that the home assistant REST api is used by snips HA actions. However, I could not find a place to set a different home assistant host, and since my instance is running on another host, it would not work anyway.

However, the home assistant REST api is really easy to use with the python request module, so I decided to go that route in combination with the git app actions.

Another possibility, of course, to integrate snips + HA would be to use the snips component and the intent_script component..
I haven’t tried this, but to me it looks a bit cumbersome to use, and using git app actions would bundle the functionality directly with the assistant, so that no more setup on HA side would be necessary, which looks pretty clean and easy to me.

Hope this helps :slight_smile:

I am using the snips component in HA and a intent script.
This is how it looks like:

play:
  action:
    service: media_player.media_play
    data_template:
      entity_id: >
        media_player.{{ (deviceLocation if deviceLocation else site_id) | lower }}

deviceLocation is the intent slot that is used if it is available, otherwise site_id.
play is the intent name.

Yeah thats another way. However I wanted to implement it on snips side :slight_smile:

This is what I’ve ended up with:

And its working well so far.

To try to address some of the questions…

  1. When using the HA snippets as in the original post, HA and snips communicate via MQTT. Specifically, snips will interpret your voice commands, and post the intent to MQTT, and you have to configure HA to watch for those intents. See https://www.home-assistant.io/components/snips/ and look at “Triggering Actions” for more info, then go read https://www.home-assistant.io/components/python_script/ and https://www.home-assistant.io/components/intent_script/. Finally, read the snips page again, and this time it’s OK to look at the examples, since now they might make sense. :slight_smile:
  1. Choosing “Home Assistant component” does two things, AFAICT.
    1. It initializes the snippet in the console with a comment to help you in writing the snippet.
    2. It sets some internal values in the assistant so that sam will know it’s intended for use with Home Assistant, and in theory, it could then copy the files your config/python_script directory.

I’m taking a small break from working on my snips addon for hassio (not Home Assistant generically, but the docker container specifically), which helps to address some of these problems. The feature I’m working on right now is to get those HA snippets not only copied to the config/python_script directory (which it currently does), but also to update the HA config file so the user won’t need to do the complex stuff referenced above. It’ll just work. I expect to have that feature completed today or tomorrow, although it won’t restart HA to reload the updated configuration yet. I just don’t trust my code enough yet to give it that much power. Oh, and it already works well with actions that are available via git. :slight_smile: If you’d like to take a look at it, ask me, and I’ll point you to the pre-release version.

Thanks for the follow-up on the initial questions.

Regarding your answer 1), why is Snips forcing me to install home assistant on the same machine as the snips runtime, if communication is going via MQTT (-> decoupled) anyway? Does not make sense to me, and would also never work for me, since my HA installation is running on a different host.

Regarding your other answer, I think youre trying to make the snips skills directly interact with the HA process/configuration, even to the extend of updating HA configurations (correct me if I understood this wrong).
As for my personal use, I am striving to separate software components as much as possible and to use separate unix users for security reasons (also to follow best practices regarding unix services etc.) In my setup, HA and snips will even be on different machines.
Thus, I would never let snips (or another component) directly access my HA installation at least for security reasons.
I would always prefer clean and secure interfaces and separation/decoupling.

Snips is not forcing you to install home assistant on the same computer as the snips runtime. A lot of the documentation suggests doing it that way, but I don’t like that, either. It’s also one of the reasons I suggested reading only the Triggering Actions and Examples sections of the home assistant snips document. There’s too much “do it this way” in there, and it’s suggesting the wrong way, IMO. :slight_smile:

I like the idea of limiting the communication between snips and HA to the MQTT bus, because that means snips can only cause a very limited set of actions – actions that must be defined in HA. I also set up an MQTT bridge for this, and I don’t follow the common suggestions of bridging everything from hermes, I only bridge hermes/intent/# – HA can only see the intents this way. That is, communication between the two is even further separated. :slight_smile:

I don’t really like the idea of snips calling the HA API directly – that lets a snips app do anything it wants, and I have to create a token and somehow securely store it in snips. IMO, that’s too much like giving snips direct access to HA. What I mean is, if someone breaks the security of your system running snips, that someone can modify the snips assistant or install new software to invoke the HA API and do whatever they want. If everything is limited to the MQTT bus, one who breaks into the system running snips can send whatever intents to the MQTT bus, but that doesn’t mean HA will do anything with them. Additionally, because you’ve stored the token with snips, the one can view that token, and invoke the HA API from some other system (theoretically from remote, if the HA API is open to the outside world). I think it’s far more secure to route through MQTT. :slight_smile:

I think you misunderstand what my addon does, somewhat, and perhaps what hassio is for. Hassio is a group of docker containers for running and managing home assistant. An addon is an additional docker container that can provide new functionality, modify functionality, etc., of home assistant (although, technically, it could be an unrelated docker container). Each container shares a private network and can efficiently share files (e.g. HA’s config directory). The goal of hassio is to make configuring and managing HA easier.

My addon attempts to simplify the installation, management, and configuration of snips, and make it easy to configure integration with HA. The instance of snips in my addon should work with apps that use skills from git, apps that use python snippets, and apps that use home assistant snippets. My goal is to make it so one can create an assistant in the snips console, point the addon to it, and have everything work (it’s not there yet). There’s an official snips addon for hassio, too, but its far more limiting, working only with home assistant snippets).

Because my addon modifies the HA config, you might be thinking about my comments above the and the API. However, there are protections. When one breaks into the addon, one can still only send intents through MQTT. One cannot modify the HA configuration, because that’s limited a single script – one that only modifies the HA config to react to the intents which are defined in the snips assistant as being for HA. That script is protected from modification by apparmor. One who breaks into my addon still cannot use the HA API, either, since that access is forbidden by the configuration of the addon (which is not controlled at runtime, but at install time. Unfortunately, this means it wouldn’t work with your app. :(. You do need to trust the assistant you install, though, only to do the things you want it to do. :slight_smile: If you can’t trust the assistant you install, then I’m not sure anything could be secure enough. :smile:

Note that hassio, my addon, and any other addons I install can modify HA’s config. That’s rather the point of them – to configure and manage home assistant. Apps like snips (and snips assistants) should not be allowed to modify HA’s config. Right now my addon would allow snips to modify HA’s config, but that’s a bug in my addon. I know about it, and it’s something I’ll have fix before releasing the version that modifies the HA config.

2 Likes

Correction; I bridge hermes/intent/# from snips to HA’s MQTT, and hermes/dialogueManager/# from HA’s MQTT to snips – otherwise HA’s snips.say wouldn’t work. :slight_smile:

@franc
I have only tried this once, but when I had HA actions in the snips console in place, snips was asking me whether or not HA is already installed on that host during sam install assistant. If I would pretend “yes” (and thus lie, since its running on another machine) it would abort complaining that it cannot find the HA installation. If I would say no, sam would go on and install a fresh HA installation.
Maybe I did something wrong, however I did not put much time into this because I quickly switched to the github app template.

So yeah maybe I somehow got you wrong on the way, also I am not familiar with hassio, I am having a manual/standalone installation of HA ever since. Of course when the snips-component is bundled with hassio it kind of makes sense to use a tighter integration.

Other than that I think we agree on most parts. I like your ideas of clean separation via MQTT, which is something I am also doing for other parts (e.g. my remote control is hooked via MQTT).
And yes you’re right in that a direct connection to HA has more security implications than communication via MQTT. Yet the possible actions in the REST API are limited, and while there sure could/will be attack vectors, I think the impact is also limited. I am already using it anyway for e.g. node-red, and I think using MQTT you will quickly reach a point where things get really complicated in HA.

Regarding this topic (and I can only speak for myself, not @Kryt1kal or @Malyngo) I wanted to go that python -> HA REST API approach for two reasons:

  1. I am really no big fan of HAs YAML configuration, especially when it gets more complicated. Using code snippets in value templates and all that stuff (within a configuration language) just feels cumbersome and weird to me. Note that I am not saying its crap, or that I know of a much better solution, but I just dont like using it. I still do for some sensors and switches, and I know that its pretty versatile, but if I can get around it, I tend not to use it :slight_smile:
  2. I am a developer, and I like trying out new stuff, and just to program stuff :smiley:

Also, my app now really boils down to only configuring a bunch of groups in HA and everything will just work. No automations needed, no complex intent_script, no MQTT message parsing.

1 Like

@s710
I think you just proved me at least partly wrong. :smile: I haven’t used sam in quite a while, mostly because I found it used a lot of system resources for no apparent reason. If you install the assistant manually, and avoid sam, there’s no requirement to have snips and HA on the same computer. :slight_smile:

I don’t like HA’s YAML configuration, either. I, too, think it’s cumbersome. I can understand the examples I read, and well enough to go beyond them, but I shouldn’t have to think about it so much. :slight_smile: On the plus side, I think this is why the HA snippets in snips exist – using those, the configuration for the intent script is straight forward and small. You just need the name of the intent, the name of the script file, and to copy the file into the right place. That does make for a complicated snippet in some places, and I still don’t know how to get the site_id as you originally asked. :frowning: But I think you can access the actual intent message, so it should be possible; I just haven’t looked into it for a while.

Anyway, thanks for the info!