Automagic & Home Assistant (plus NFC automation example)

This tutorial shows how to use Automagic android app to interact with Home assistant. Automagic is a really powerfull and innovative android automation app. Automagic and Home Assistant toghether lets to do a lot of interesting things.

Prerequisites:
in order to interact to home assistant by http commands a long life certificate needs to be created in HA:

  1. Go to your HA page>Profile>Long lived access token>Create token.
  2. Take note of created token.

1. Store your access data in Automagic

We have to create 2 variables to store IP address and token of our Home assistant in Automagic. These data will be then available within Automagic when needed.

  1. Automagic>left panel>Global Variables>add (+)
  2. Add global_ha_addr variable with your HA ip:port address
  3. Add global_ha_k variable with “Authorization:Bearer YOUR_TOKEN”

2. Import example flows

I created 2 flows: one to send commands to HA and one to retrieve informations from HA. These flows can be used as a base for you own projects.

Http Call service Flow
Get status Flow

WHen you open these links in a device with Automagic installed, you can choose to directly open them in the App.

PART 1: CALLING HA SERVICES FROM AUTOMAGIC

This is the related flow:

in the second block we have to enter HA sevice to call and related entity id:

That’s all. We can test the flow entering your service/entity data and using “Execute” on the top right menu. If it is working you can clone the flow and use it with differents triggers etc.

PART 2: RETRIEVING DATA FROM HA

This is the related flow:

In the second block we have to enter the entity wich we want to retrieve the status, the attibute three (if the attribute that we are searching is not nested we have to use only “attr” leaving attr1 empty) and the unit of the data:

In this flow the retrieved data is shown as a notification on the status bar. That’s all. We can test the flow entering your entity and other data and using “Execute” on the top right menu. If it is working you can clone the flow and use it with differents triggers etc.

PART 3: NFC TAG TO START HOME ASSISTANT SERVICE

The Http Call service Flow contains an NFC trigger. This usage is very useful because using a cheap self adesive tag you can send commands (safely) to HA only approaching your phone to the tag. You need writable tags to do so.

Starting from the example flow:

Tap on the trigger block (the first one), write down a code of your choise and tap on the WRITE button:

Then approach a writable NFC tag; it will be written with the code you choosen:

Now every time you approach the phone to the tag, the flow can start your Home assitant service (for example to open a door or similar).

Links:

Automagic app

NFC Tags

4 Likes

Giovanni, just a followup to a few things I found with your example xml flows. I started completely from scratch and imported the NFC flow and changed just one thing - replacing light.rgw_1 with light.entry_lamp via the flowchart editor. Ran execute and got this error…

13.02.2020 15:04:46.495 Could not evaluate '"entity_id": "light.rgbw_1"'.
ch.gridvision.ppam.androidautomagic.simplelang.a.d: Could not evaluate expression '"entity_id": "light.rgbw_1"' due to errors: [';' expected[11], expression expected[11], ';' expected[11]]

This was because in the flow, the XML: <formFieldList>{“entity_id”: “light.rgbw_1”}</formFieldList> did not get updated and no obvious way to change it via the flow editor. So I manually corrected it in the XML, re-imported it, and that fixed that issue.

Per the AutoMagic log (below), everything seems to be working and no errors that I can see. Unfortunately, HA still shows Login attempt or request with invalid authentication. I have double checked that the LLToken is valid and entered correctly as a variable. Sorry to say, this looks like a dead end result for me. If the log would have only showed the exact cURL http POST in full exactly as transmitted, that may have helped spot the problem.

13.02.2020 15:21:59.315 Import statistic ImportInfo{importedTriggerNames=[NFC Tag: 245678533589324], importedConditionNames=[], importedActionNames=[HTTP Request: POST {global_ha_addr}/api/services/{Service1} text/plain {JsonData} store in response, Script: Service1= replace( {Service}, "." , "/" ); data = newMapFromValues ("entity_id", {Entity_id}); JsonData = toJSON (data);, Script: Service= "light.toggle"; Entity_id= "light.entry_lamp";], importedFlowNames=[Test http POST service], importedWidgetNames=[], duplicateTriggerNames=[], duplicateConditionNames=[], duplicateActionNames=[], duplicateFlowNames=[], duplicateWidgetNames=[]}

13.02.2020 15:22:10.557 [Test http POST service] Starting to execute flow 'Test http POST service' with Context{global{global_ha_k=ey...,global_ha_addr=https://myhass.duckdns.org:8123},local{flow_name=Test http POST service,trigger=Manual,triggertime=1581628930556}}

13.02.2020 15:22:10.559 [Test http POST service] Start executing action 'Script: Service= "light.toggle"; Entity_id= "light.entry_lamp";'

13.02.2020 15:22:10.581 [Test http POST service] End executing action 'Script: Service= "light.toggle"; Entity_id= "light.entry_lamp";'

13.02.2020 15:22:10.590 [Test http POST service] Flow continues executing with the next step.

13.02.2020 15:22:10.590 [Test http POST service] Start executing action 'Script: Service1= replace( {Service}, "." , "/" ); data = newMapFromValues ("entity_id", {Entity_id}); JsonData = toJSON (data);'

13.02.2020 15:22:10.606 [Test http POST service] End executing action 'Script: Service1= replace( {Service}, "." , "/" ); data = newMapFromValues ("entity_id", {Entity_id}); JsonData = toJSON (data);'

13.02.2020 15:22:10.624 [Test http POST service] Flow continues executing with the next step.

13.02.2020 15:22:10.624 [Test http POST service] Start executing action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1} text/plain {JsonData} store in response'

13.02.2020 15:22:10.626 [Test http POST service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1} text/plain {JsonData} store in response' url = https://myhass.duckdns.org:8123/api/services/light/toggle

13.02.2020 15:22:10.628 [Test http POST service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1} text/plain {JsonData} store in response' contentType = text/plain

13.02.2020 15:22:10.628 [Test http POST service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1} text/plain {JsonData} store in response' generalTextData = {"entity_id": "light.entry_lamp"}

13.02.2020 15:22:10.629 [Test http POST service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1} text/plain {JsonData} store in response' variable = response

13.02.2020 15:22:10.629 [Test http POST service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1} text/plain {JsonData} store in response' customHTTPHeaders = ey...

13.02.2020 15:22:10.948 [Test http POST service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1} text/plain {JsonData} store in response' URL data fetched successfully.

13.02.2020 15:22:10.949 [Test http POST service] End executing action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1} text/plain {JsonData} store in response'

13.02.2020 15:22:10.970 [Test http POST service] Flow ended.

I have this entry in my configuration.yaml. It is related to api too. You can check if you have that too. I’m speaking about default config row

02b071ff4d7ac977c54340276453e1f8ac3f2f2f_2_690x219

Did you use ; at the end of tge row?

Did you enter authorization variable correctly?

d2e8491002af3ee948e99608696f6de7bd420457_2_690x344

Thanks Giovanni for the troubleshooting suggestions. Yes, my configuration yaml is similar, but without javascript_version which is deprecated now.

Yes, semicolons are properly appended to each row. (There are NO errors in the syntax and command processing according to the AutoMagic logs now).

Yes, the global variables are entered correctly. This has been triple checked. I have mentioned earlier that I even verified the REST API was communicating properly from Windows using a direct cURL command…
curl -X POST -H "Authorization: Bearer XxXxX....." -H "Content-Type: text/plain" -d "{\"entity_id\": \"light.entry_lamp\"}" https://myhass.duckdns.org:8123/api/services/light/toggle

So it is really odd why the authentication isn’t working from AutoMagic on my personal Android 9 phone. The logs don’t give any clue at all what the problem is.

Can you post your flow screenshots from your phone? Maybe some little error in your Automagic flow…

I captured the flow screen shots but decided that to prove beyond any doubt that I may have introduced any typo’s, I imported your Http Call service flow and made NO changes to it. I then created an HA entity of light.rgbw_1 to match the entity in this flow. I also found a setting to enable additional debug information in the log, and for the first time, I can see it reporting a “network 401” error, meaning “unauthorized”.

I’m also seeing a Java error “Could not evaluate expression ‘“entity_id”: “light.rgbw_1”’ due to errors” .

I will post the full debug log here with my token redacted (which I confirmed is entirely accurate).

Please see if you can find the error in your original flow XML and I will reimport a fixed version and make no changes. It will be interesting to see if that has any affect on the authentication process.

14.02.2020 13:08:00.339 [Test http service] Starting to execute flow 'Test http service' with Context{global{global_ha_k=ey...,global_ha_addr=https://myhass.duckdns.org:8123},local{flow_name=Test http service,trigger=Manual,triggertime=1581707280335}}
14.02.2020 13:08:00.340 [Test http service] Start executing action 'Script: Service= "light.toggle"; Entity_id= "light.rgbw_1";'

14.02.2020 13:08:00.355 [Test http service] End executing action 'Script: Service= "light.toggle"; Entity_id= "light.rgbw_1";'
14.02.2020 13:08:00.364 [Test http service] Flow continues executing with the next step.
14.02.2020 13:08:00.364 [Test http service] Start executing action 'Script: Service1= replace( {Service}, "." , "/" ); data = newMapFromValues ("entity_id", {Entity_id}); JsonData = toJSON (data);'
14.02.2020 13:08:00.365 Queue contains 1 workerInfos
14.02.2020 13:08:00.382 [Test http service] End executing action 'Script: Service1= replace( {Service}, "." , "/" ); data = newMapFromValues ("entity_id", {Entity_id}); JsonData = toJSON (data);'
14.02.2020 13:08:00.400 [Test http service] Flow continues executing with the next step.
14.02.2020 13:08:00.400 [Test http service] Start executing action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response'
14.02.2020 13:08:00.403 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' url = https://myhass.duckdns.org:8123/api/services/light/toggle 

14.02.2020 13:08:00.404 Could not evaluate '"entity_id": "light.rgbw_1"'.
ch.gridvision.ppam.androidautomagic.simplelang.a.d: Could not evaluate expression '"entity_id": "light.rgbw_1"' due to errors: [';' expected[11], expression expected[11], ';' expected[11]]
	at ch.gridvision.ppam.androidautomagic.simplelang.a.j.a(SourceFile:947)
	at ch.gridvision.ppam.androidautomagic.simplelang.a.j.a(SourceFile:910)
	at ch.gridvision.ppam.androidautomagic.util.cr.a(SourceFile:390)
	at ch.gridvision.ppam.androidautomagic.util.cr.a(SourceFile:320)
	at ch.gridvision.ppam.androidautomagic.util.cr.a(SourceFile:269)
	at ch.gridvision.ppam.androidautomagic.model.a.bi$1.a(SourceFile:354)
	at ch.gridvision.ppam.androidautomagic.model.a.bi$1.c(SourceFile:333)
	at ch.gridvision.ppam.androidautomagiclib.util.ci$1.run(SourceFile:40)
	at java.lang.Thread.run(Thread.java:764)

14.02.2020 13:08:00.405 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' contentType = text/plain
14.02.2020 13:08:00.405 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' generalTextData = {"entity_id": "light.rgbw_1"}
14.02.2020 13:08:00.405 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' variable = response
14.02.2020 13:08:00.405 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' customHTTPHeaders = ey...
14.02.2020 13:08:00.735 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' URL data fetched successfully.
14.02.2020 13:08:00.736 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' Header Content-Length=17
14.02.2020 13:08:00.736 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' Header Content-Type=text/plain; charset=utf-8
14.02.2020 13:08:00.736 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' Header Date=Fri, 14 Feb 2020 19:08:01 GMT
14.02.2020 13:08:00.736 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' Header Server=Python/3.7 aiohttp/3.6.1
14.02.2020 13:08:00.736 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' Header X-Android-Received-Millis=1581707280734

14.02.2020 13:08:00.737 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' Header X-Android-Response-Source=NETWORK 401

14.02.2020 13:08:00.737 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' Header X-Android-Selected-Protocol=http/1.1
14.02.2020 13:08:00.737 [Test http service] Action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response' Header X-Android-Sent-Millis=1581707280709
14.02.2020 13:08:00.737 [Test http service] End executing action 'HTTP Request: POST {global_ha_addr}/api/services/{Service1}  text/plain {JsonData} store in response'
14.02.2020 13:08:00.744 [Test http service] Flow ended.

I’m pretty sure you have a sintax error in your Automagic flow, especially in your second and/or third block. Please post screenshots from your phone.

Yes, I agree. But the Automagic flow is yours, directly from your dropbox link. I’ve made no changes to it at all.

I tested it from scratch another time in a new device (an android tablet) installing all stuff from zero (Automagic and flows dowloaded directly from OP link) just 1 hour ago. It worked for me. I don’t have the error “Could not evaluate…”.
That error means that there is something wrong in your flow (i can’t say why, especially if i can’t see the screenshots).

Were you viewing the default filtered log? That won’t show the error. An unfiltered log view will show Java errors (from the log option in the main slide-out menu). In any case, the OP flow worked for you so even if this error exists, it didn’t impact anything.

I downloaded the OP flow to my phone directly again, executed it with no changes, and got the exact same results as before.

Here are the flow screenshots you asked for…

EDIT: Could the problem be that I’m running the TRIAL version? I sure wanted to verify this worked before buying it. And - I still have to get it to work on an older phone.

  1. Do you stil have “Could not evaluate xxx…” error?
  2. Do you have an authentication error notification in HA when you try to send commands from Automagic?

For the second case i know the solution. Your flow seems to be ok.

Yes, I still have the evaluation error but it does not seem to be fatal. The remainder of the flow processes.

Yes, the authentication error in HA occurs exactly when the flow attempts to login. That’s good news you have a solution for this!

One thing to note about the evaluation error - if I do change the light.rgbw_1 entity name in the flow editor, the Java evaluation error is still referring to light.rgbw_1. This line in the flow appears to be hardcoded and not modifiable by the flow editor…
<formFieldList>{“entity_id”: “light.rgbw_1”}</formFieldList>

EDIT: This field is actually viewable if the Content Type is temporarily changed from “General Text” to “Form”. The interpreter is not liking the colon and is expecting a semicolon to separate fields. This line should be cleared out as it isn’t even being used I found out later.

Ok, i don’t know if you already tried but in case of ha login error you have to access to your ha from same device where you installed Automagic: you can do this using official ha app. From there create a new long lived access token and use it in Automagic variable. Wait some minute because it seems new token is not immediately working.

Sure, I have been connecting to my https HA (duckdns.org) site from the same Android 9 phone that AutoMagic is running on this whole time. I’ve recreated token codes and have tried again with them several times. I know the token is good since it has been tested and connected fine with cURL as I had mentioned before.

Is your home HA site accessed externally via https or is it http?

I use https (duckdns+letsencrypt setup). At this moment i have not other ideas…

Ok, thanks.

It would be interesting to know if others have had any issues connecting AutoMagic to HA or have had success and could post here.

Good news Giovanni - the http request flow is working for me now!

I had initially defined the global_ha_k to start with “Authorization: Bearer” followed by the LLToken, but in subsequent attempts using a new token, I had inadvertently pasted over it, so it was only the token in the custom http header.

I also found what was causing the Java evaluation error. In the last flow, the Content Type is set to General Text - text/plain which is fine. But if it is changed to “Form” it shows a formFieldList of “entity_id”: “light.rgbw_1” . This field list needs to be separated by semicolons. But it appears this isn’t even being used, so I just removed it, and it works fine. Your template should be updated to remove it as well.

EDIT: I think changing the template to automatically include “Authorization: Bearer” would be helpful for new users. Just copy/paste the LLToken into the global variable by itself and let the template properly preface the custom header.