Emacs autocomplete for home assistant entities

I quickly put together a simple means of auto-completing hass entities in GNU Emacs buffers. The code is up on github at:

Feel free to report issues, especially with fixes :-).

Hot stuff. I’m going to try this out when I get back home. In the readme, could you provide just a bit more detail on the setup using both api_states.txt and the live server version? I think I understand from reading the code, but being explicit is always helpful.

Sure, I added a bit more details. It’s not yet meant for folks uncomfortable with at least reading Emacs Lisp since I’ve not tried to test it against a new install, etc., so YMMV.

I am probably missing something basic. I have cloned your repo and added the directory onto load-path, and I added my bearer token and my hass_prefix url is https://192.168.1.xxx:8123 in the file in that directory. Then I do M-x hass-setup-completion. It prompts something like a folder, but if I just hit enter I get a JSON readable error: 59.

Can you M-x set-variable debug-on-error to t and send a full backtrace?

Debugger entered--Lisp error: (json-readtable-error 104)
  signal(json-readtable-error (104))
  json-read()
  json-read-file("/mnt/usbdrive/homeassistant/haconfig/conf$
  (setq hass-api-states-json (json-read-file from-file))
  (if from-file (setq hass-api-states-json (json-read-file $
  hass-setup-completion("/mnt/usbdrive/homeassistant/haconf$
  funcall-interactively(hass-setup-completion "/mnt/usbdriv$
  call-interactively(hass-setup-completion record nil)
  command-execute(hass-setup-completion record)
  execute-extended-command(nil "hass-setup-completion" "has$
  funcall-interactively(execute-extended-command nil "hass-$
  call-interactively(execute-extended-command nil nil)
  command-execute(execute-extended-command)

It seems like I’m giving it the file name, but I’m not sure how to get the optional argument to evaluate as false in the if statement when I use M-x hass-setup-complete. It prompts me for a file name. I have tried a blank entry here too without luck.

Thanks – please try the latest – you may have to re-clone the repository as I rebuilt it to make sure it properly reflected my working clone. I separated out a new interactive function for if you want to set up off of a file on disk, that way the function you’re calling (hass-setup-completion) will use the HTTP API by default interactively.

Thanks, I will try later! My ideal workflow would be to use the HTTP API by default, but fall back to the api_states.txt file if it cannot connect. When it connects, it saves an api_states.txt file. This way it will continue to work even when the HA server is down according to the last fetched state. You wouldn’t have to manually update the local file. If I can get your version to work, I will fiddle with it to see if I can get this workflow.

So I checked and I can use curl to get the valid /api/states result with the values in my secrets file. I get a new error now using your package. I would also request that you don’t force push onto your public repo, it was a mess to clean up, but it is your repo. I ended up having to copy my token to a separate folder and reclone.

Here is the debug log after I get [error] request-default-error-callback: https://127.0.0.1:8123/api/states parse-error

Debugger entered--Lisp error: (void-variable hass-api-states-json)
  (mapcar (function (lambda (a) (cdr (assoc 'entity_id a)))) hass-api-states-json)
  (setq hass-entities (mapcar (function (lambda (a) (cdr (assoc 'entity_id a)))) hass-api-states-json))
  hass-setup-completion()
  funcall-interactively(hass-setup-completion)
  call-interactively(hass-setup-completion record nil)
  command-execute(hass-setup-completion record)
  execute-extended-command(nil "hass-setup-completion" "hass")
  funcall-interactively(execute-extended-command nil "hass-setup-completion" "hass")
  call-interactively(execute-extended-command)

(Aside: Yes, I mentioned you’d likely have to re-clone – sorry about that as the version on github wasn’t the right one due to a mix-up in my setup of git on the two separate computers I was using to develop and test. That was a one time screw-up and git pull will suffice in general, of course.)

Looks like the request success case happens async, so a second call to the function should succeed. Regardless, I fixed that issue in the latest. Thanks for testing!

Ah I think I understand what happened. I bull headedly tried to use git pull --allow-unrelated-histories and it got really messy. I should have just heeded your warning.

This update went much smoother. Now I think it seems to connect, but I get the message got 0 entities. And autocomplete doesn’t work, I assume because there are no entities.

Does hass-api-states-json look right? Show it with C-h v hass-api-states-json

Does trying a second time have a different result?

Thank you for being patient in this process, I know a little Lisp to be useful, but not enough to debug something like this. I’m learning a whole lot on this process however.

It’s value is nil even after running hass-setup-completion twice.

I suspect request is failing in making the request, then. I’ll add some proper error handling tonight or tomorrow so that it’s more apparent what failure scenario you’ve encountered.

I just pushed an update that does some better error handling and sets an 8 second timeout on the request so you can get more feedback about what might be going wrong. Let me know if you can figure it out now.

I get an immediate error. The debug-on-error no longer starts presumably because the error is
now caught.

Got error: (error . "exited abnormally with code\
 35
")

From https://curl.haxx.se/libcurl/c/libcurl-errors.html, error code 35 looks like it’s related to SSL – see below. Are you using SSL for your prefix? Do you have SSL set up properly including a legit certificate, etc.? Can you try it with an http: instead of https: for the prefix? Does your curl binary have SSL support enabled? You can modify the code to inspect the error buffer if you want, but I believe this is a problem with your configuration.

CURLE_SSL_CONNECT_ERROR (35)

A problem occurred somewhere in the SSL/TLS handshake. You really want the
error buffer and read the message there as it pinpoints the problem slightly more.
Could be certificates (file formats, paths, permissions), passwords, and others.

1 Like

That was it. I thought it was something basic and I couldn’t figure out what error code 35 was. I changed to http: instead of https: and it works great! Thank you for all of your help!

Glad to hear it!