Updated on 9/21.
A downloadable multi app version of this task has been uploaded to Taskernet.com. Search for “WireGuard Auto Connect.”
If you rely on WireGuard for occasional remote access, don’t want to run the app all the time when you aren’t at home, and don’t access HA remotely often enough to make HA Cloud worthwhile, this task will make it much more convenient to access your Home Assistant server when you’re away. This is a Task, rather than a Profile because Tasker has difficulty reliably detecting via profile when an app is running, probably due to Android limitations.
This task has two modes:
Local mode: If your phone is connected to your home network Home Assistant Companion starts normally and the task exits.
Remote mode: If your phone is not connected to your home network, this task activates a WireGuard tunnel, verifies the HA server is accessible and then starts HA Companion. When HA Companion is no longer in the foreground the WG tunnel is shut down and the task exits to the home screen.
What’s needed:
- An Android phone. (Tested on an unrooted Oneplus 9Pro running Android 13.)
- Your phone’s static IP address on your home network, or if you prefer to leave Location enabled on your phone, your WiFi SSID.
- Tasker
- A working Wireguard server on your home network. (I’m using PI VPN running on the same server as Home Assistant.)
- The Wireguard app on your phone with a working tunnel configured that allows access to your HA server.
- Your HA server configured to respond to pings.
Setup:
- Copy the code below to a text file and name it “Home_Assistant.tsk.xml”.
- Import the Home_Assistant.tsk.xml file into Tasker by long clicking on the Tasks tab at the top.
- Configure the variables in the variable entry section.
- If desired, change the Icon by tapping the dots at the bottom center of the screen.
- Turn on “Allow remote control apps” in Wireguard Settings / Advanced.
- In Tasker Permissions enable “Control Wireguard Tunnels.”
- In the main Tasker screen tap the 3 dot menu. Select “More” and “Android Settings”, then turn on “App Usage Stats” for Tasker.
- Create a widget for the task on your launcher. You should no longer need a separate HA Companion app icon.
Note: After connecting through WireGuard and leaving HA Companion, this script is not able to reestablish the WG tunnel if you switch back to the HA Companion app. HA Companion must be restarted from the widget to reestablish the tunnel.
<TaskerData sr="" dvi="1" tv="6.2.12-rc">
<Task sr="task72">
<cdate>1690430702327</cdate>
<edate>1693765479317</edate>
<id>72</id>
<nme>Home Assistant</nme>
<pri>100</pri>
<showinnot>false</showinnot>
<Kid sr="Kid">
<launchID>65</launchID>
<pkg>com.bluescloud.www.ha</pkg>
<vTarg>29</vTarg>
<vnme>1.0</vnme>
<vnum>2</vnum>
</Kid>
<Action sr="act0" ve="7">
<code>300</code>
<label>Variable entry</label>
</Action>
<Action sr="act1" ve="7">
<code>300</code>
<label>Home Assistant IP</label>
</Action>
<Action sr="act10" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%PingTries</Str>
<Str sr="arg1" ve="3">3</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act11" ve="7">
<code>300</code>
<label>End of variable entry</label>
</Action>
<Action sr="act12" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%Retrycount</Str>
<Str sr="arg1" ve="3">%PingTries</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="1"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act13" ve="7">
<code>37</code>
<ConditionList sr="if">
<bool0>Or</bool0>
<Condition sr="c0" ve="3">
<lhs>%WIFII</lhs>
<op>4</op>
<rhs>%IP1orSSID1</rhs>
</Condition>
<Condition sr="c1" ve="3">
<lhs>%WIFII</lhs>
<op>4</op>
<rhs>%IP2orSSID2</rhs>
</Condition>
</ConditionList>
</Action>
<Action sr="act14" ve="7">
<code>20</code>
<App sr="arg0">
<appClass>io.homeassistant.companion.android.launch.LaunchActivity</appClass>
<appPkg>io.homeassistant.companion.android</appPkg>
<label>Home Assistant</label>
</App>
<Str sr="arg1" ve="3"/>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
</Action>
<Action sr="act15" ve="7">
<code>135</code>
<Int sr="arg0" val="1"/>
<Int sr="arg1" val="1"/>
<Str sr="arg2" ve="3">End</Str>
</Action>
<Action sr="act16" ve="7">
<code>38</code>
</Action>
<Action sr="act17" ve="7">
<code>20</code>
<App sr="arg0">
<appClass>com.wireguard.android.activity.MainActivity</appClass>
<appPkg>com.wireguard.android</appPkg>
<label>WireGuard</label>
</App>
<Str sr="arg1" ve="3"/>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
</Action>
<Action sr="act18" ve="7">
<code>365</code>
<Bundle sr="arg0">
<Vals sr="val">
<net.dinglisch.android.tasker.RELEVANT_VARIABLES><StringArray sr=""/></net.dinglisch.android.tasker.RELEVANT_VARIABLES>
<net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>
</Vals>
</Bundle>
<Str sr="arg1" ve="3">WireGuardSetTunnel(true,%WGTunnel)</Str>
</Action>
<Action sr="act19" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%Loopcount</Str>
<Str sr="arg1" ve="3">0</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act2" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%HA_IP</Str>
<Str sr="arg1" ve="3">Your HS server's private IP</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act20" ve="7">
<code>30</code>
<Int sr="arg0" val="0"/>
<Int sr="arg1" val="1"/>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
</Action>
<Action sr="act21" ve="7">
<code>300</code>
<label>WaitingWG</label>
</Action>
<Action sr="act22" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%Loopcount</Str>
<Str sr="arg1" ve="3">%Loopcount+1</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="1"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act23" ve="7">
<code>37</code>
<ConditionList sr="if">
<Condition sr="c0" ve="3">
<lhs>%Loopcount</lhs>
<op>0</op>
<rhs>2</rhs>
</Condition>
</ConditionList>
</Action>
<Action sr="act24" ve="7">
<code>550</code>
<Str sr="arg0" ve="3"/>
<Str sr="arg1" ve="3">Waiting for Home Assistant</Str>
<Str sr="arg2" ve="3"/>
<Str sr="arg3" ve="3">Popup</Str>
<Int sr="arg4" val="2"/>
<Int sr="arg5" val="1"/>
</Action>
<Action sr="act25" ve="7">
<code>38</code>
</Action>
<Action sr="act26" ve="7">
<code>37</code>
<ConditionList sr="if">
<Condition sr="c0" ve="3">
<lhs>%Loopcount</lhs>
<op>0</op>
<rhs>%PingTries</rhs>
</Condition>
</ConditionList>
</Action>
<Action sr="act27" ve="7">
<code>550</code>
<Str sr="arg0" ve="3"/>
<Str sr="arg1" ve="3">No Home Assistant Response - Exiting</Str>
<Str sr="arg2" ve="3"/>
<Str sr="arg3" ve="3">Popup</Str>
<Int sr="arg4" val="5"/>
<Int sr="arg5" val="1"/>
</Action>
<Action sr="act28" ve="7">
<code>135</code>
<Int sr="arg0" val="1"/>
<Int sr="arg1" val="1"/>
<Str sr="arg2" ve="3">WGOff</Str>
</Action>
<Action sr="act29" ve="7">
<code>38</code>
</Action>
<Action sr="act3" ve="7">
<code>300</code>
<label>Network 1 SSID or Phone IP (Location must be on to use SSID)</label>
</Action>
<Action sr="act30" ve="7">
<code>320</code>
<se>false</se>
<Str sr="arg0" ve="3">%HA_IP</Str>
<Int sr="arg1" val="1"/>
<Str sr="arg2" ve="3"/>
<Str sr="arg3" ve="3">%Pingtime</Str>
<Str sr="arg4" ve="3"/>
</Action>
<Action sr="act31" ve="7">
<code>37</code>
<ConditionList sr="if">
<Condition sr="c0" ve="3">
<lhs>%err</lhs>
<op>0</op>
<rhs>1</rhs>
</Condition>
</ConditionList>
</Action>
<Action sr="act32" ve="7">
<code>135</code>
<Int sr="arg0" val="1"/>
<Int sr="arg1" val="1"/>
<Str sr="arg2" ve="3">WaitingWG</Str>
</Action>
<Action sr="act33" ve="7">
<code>38</code>
</Action>
<Action sr="act34" ve="7">
<code>300</code>
<label>StartHA</label>
</Action>
<Action sr="act35" ve="7">
<code>20</code>
<App sr="arg0">
<appClass>io.homeassistant.companion.android.launch.LaunchActivity</appClass>
<appPkg>io.homeassistant.companion.android</appPkg>
<label>Home Assistant</label>
</App>
<Str sr="arg1" ve="3"/>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
</Action>
<Action sr="act36" ve="7">
<code>300</code>
<label>WaitingHA</label>
</Action>
<Action sr="act37" ve="7">
<code>37</code>
<ConditionList sr="if">
<Condition sr="c0" ve="3">
<lhs>%LAPP</lhs>
<op>3</op>
<rhs>WireGuard</rhs>
</Condition>
</ConditionList>
</Action>
<Action sr="act38" ve="7">
<code>30</code>
<Int sr="arg0" val="500"/>
<Int sr="arg1" val="0"/>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
</Action>
<Action sr="act39" ve="7">
<code>135</code>
<Int sr="arg0" val="1"/>
<Int sr="arg1" val="19"/>
<Str sr="arg2" ve="3">WaitingHA</Str>
</Action>
<Action sr="act4" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%IP1orSSID1</Str>
<Str sr="arg1" ve="3">Your phone's private static IP or your WiFi SSID.</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act40" ve="7">
<code>38</code>
</Action>
<Action sr="act41" ve="7">
<code>300</code>
<label>HAActive</label>
</Action>
<Action sr="act42" ve="7">
<code>37</code>
<ConditionList sr="if">
<Condition sr="c0" ve="3">
<lhs>%LAPP</lhs>
<op>3</op>
<rhs>Home Assistant</rhs>
</Condition>
</ConditionList>
</Action>
<Action sr="act43" ve="7">
<code>30</code>
<Int sr="arg0" val="500"/>
<Int sr="arg1" val="0"/>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
</Action>
<Action sr="act44" ve="7">
<code>135</code>
<Int sr="arg0" val="1"/>
<Int sr="arg1" val="19"/>
<Str sr="arg2" ve="3">HAActive</Str>
</Action>
<Action sr="act45" ve="7">
<code>38</code>
</Action>
<Action sr="act46" ve="7">
<code>300</code>
<label>WGOff</label>
</Action>
<Action sr="act47" ve="7">
<code>365</code>
<Bundle sr="arg0">
<Vals sr="val">
<net.dinglisch.android.tasker.RELEVANT_VARIABLES><StringArray sr=""/></net.dinglisch.android.tasker.RELEVANT_VARIABLES>
<net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>
</Vals>
</Bundle>
<Str sr="arg1" ve="3">WireGuardSetTunnel(false,%WGTunnel)</Str>
</Action>
<Action sr="act48" ve="7">
<code>25</code>
<Int sr="arg0" val="0"/>
<Str sr="arg1" ve="3"/>
</Action>
<Action sr="act49" ve="7">
<code>300</code>
<label>End</label>
</Action>
<Action sr="act5" ve="7">
<code>300</code>
<label>Network 2 SSID or Phone IP (Location must be on to use SSID)</label>
</Action>
<Action sr="act6" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%IP2orSSID2</Str>
<Str sr="arg1" ve="3">Your phone's 2nd private static IP or your 2nd WiFi SSID. Leave unchanged if you only have a single network.
</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act7" ve="7">
<code>300</code>
<label>WireGuard Tunnel Name</label>
</Action>
<Action sr="act8" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%WGTunnel</Str>
<Str sr="arg1" ve="3">Your WG tunnel name</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int
sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act9" ve="7">
<code>300</code>
<label>Server Ping Tries (~4 seconds/ping before failing)</label>
</Action>
<Img sr="icn" ve="2">
<fle>/storage/emulated/0/QuickShare/ic_launcher_round.png</fle>
</Img>
</Task>
</TaskerData>
Below are the individual tasks entries contained in the XML if you prefer to recreate the task from the Tasker UI. This list was transcribed manually from my phone (there doesn’t seem to be a way to export it) so there may be minor typos.
1 Label Variable Entry Section
2 Label Home Assistant IP
3 Variable Set Name %HA_IP To <Your HA server’s private IP Address>
4 Label Network 1 SSID or phone IP (Location must be on to use SSID)
5 Variable Set Name %IP1orSSID1 To <Network 1 - Your phone’s private static IP or your WiFi SSID>
6 Label Network 2 SSID or phone IP (Location must be on to use SSID)
7 Variable Set Name %IP1orSSID2 To <Network 2 – Your phone’s private static IP or your WiFi SSID>
8 Label WireGuard Tunnel Name
9 Variable Set Name %WGTunnel to <Your WireGuard Tunnel Name>
10 Label Server Ping Tries (~4 seconds/ping before failing)
11 Variable Set Name %PingTries To 3
12 Label End of variable entry
13 Variable Set Name %Retrycount To %PingTries
14 If %WIFII ~R %IP1orSSID1 | %WIFII ~R %IP2orSSID2
15 Launch App Package/App Name Home Assistant
16 Goto Type ActionLabel Label End
17 End If
18 Launch App Package/App Name WireGuard
19 Tasker Function Function WireGuardSetTunnel (True,%WGTunnel)
20 Variable Set Name %Loopcount To 0
21 Wait 1 Second
22 Label WaitingWG
23 Variable Set Name %Loopcount To %Loopcount+1
24 If %Loopcount eq 2
25 Popup Text Waiting for Home Assistant
26 End If
27 If %Loopcount eq %PingTries
28 Popup Text No Home Assistant Response – Exiting
29 Goto Type Action Label Label WGOff
30 End If
31 Ping Host %HA_IP Number 1
32 If %err eq 1
33 Goto Type Action Label Label WaitingWG
34 End If
35 Label StartHA
36 Launch App Package/App Name Home Assistant
37 Label WaitingHA
38 If %LAPP !~ WireGuard
39 Wait 500 MS
40 Goto Type Action Label Label WaitingHA
41 End If
42 Label HAActive
43 If %LAPP !~ Home Assistant
44 Wait 500 MS
45 Goto Type Action Label Label HAActive
46 End If
47 Label WGOff
48 Tasker Function WireGuardSetTunnel (False,%WGTunnel)
49 Go Home Page 0
50 Label End
I have no way to test this on other versions of Android, but if you have a problem getting it to work let me know and I’ll try to help.