There are two kinds of apps that I build when I am working on my personal projects. They are either apps that are confined to my home network or ones that run on the web. Examples of apps that run on the web are my investment planning app or investment recommendation app. I can access them from anywhere. Examples of apps that only run in my home network include home automation, drip irrigation, solar power management, etc. These are apps that are running on android devices, linux PC or ESP8266 boards and are connected to my wifi. You cannot access them from outside the home network.


Generally this is not a problem, but every once in a while I wish I can access them outside of my network. For example, I might want to change my solar power management configuration if we are traveling. I would like it to disconnect from grid much earlier instead of at 5:30 am. That way battery will be drained even more. And since no one is at home, during the day, the solar panel can charge the battery to full pretty quickly. But if I am traveling I cannot access the app from outside. In my solar panel app, there is a setting which lets me tune some parameters as show below, which I’d like to change based on season and power usage during that season.


Configuring the solar planner


My solar planner algorithm uses those values to determine when to disconnect the grid and run off of battery. In the above example, I am letting the planner know that I will be using 5500 mA on average during the day. And I set the sunrise time to 10 am. This sunrise time is not related to real sunrise. It is approximately when the sunlight will be sufficiently high. I also configured the battery to not go below 80%. So based on those details, the planner chooses to disconnect the grid at 5 am.


If I change the battery level or sunrise time or average load, the planner may disconnect much earlier or later. So when we are traveling, I change the average load to around 3500 or less depending on how many appliances I switch off which is based on how long we will be away from home. For example for a 2 day or less trip I leave my home automation and media center PC running. Other times I turn all of them down and reduce power usage to 2500 mA.


Anyway, you get the point that I need to configure the planner. But if I forget to change the settings before I go on vacation, I have no way to access the device from outside my home network and that is a bummer because if the planner did not disconnect early enough, the battery will be fully charged too soon and the rest of solar energy is just lost. Likewise, I’d like access to my media center PC so I can download something from it while traveling. But it is not accessible outside my home network, obviously for security reasons. There are a few solutions to the problem and I explain some of them along with the pros and cons. You can use the techniques if you are ever in this situation.


One solution is to expose an IP to the external world using DMZ in your wifi router. DMZ in combination with a DDNS service will allow you to access your network from anywhere in the world. This is the easiest solution. Obviously this is also the least secure way to do things. The server running on the exposed IP better be hardened and well protected against network attacks. Otherwise you will completely compromise your whole home network.


Another solution is to build the apps in such a way that the app can read data from the cloud. So perhaps my solar panel project could use Firebase or some other cloud solution to read the configuration information from the cloud. Another app would write the configuration to the cloud. This could work, but the problem is that you need to build this kind of write to cloud and read from cloud apps. In addition, the cloud storage where they are reading and writing from should have access restrictions to protect bad actors and any random user on the internet from writing/reading data into/from the cloud. Just imagine any random person anywhere in the world being able to control your lights and fans of your home automation by writing data to the cloud storage.


To fix the issue, you need to restrict access to the data only to certain individuals like your family. They have to login to your app and only with those credentials and proper authorization will they be able to write and read data from the cloud storage. Adding this layer of authentication and authorization to every single app is a lot of effort. This is how I wrote some of my apps. Anyone who opens the app will be required to sign-in. The access is limited to only select accounts (my family for example) and the cloud backend rejects all others who try to access the data even with a login.


Another way to access your home network is via a VPN. The internet traffic is routed through their servers (after encrypting it) to your home network and vice-versa. So you can access your home network from anywhere in the world. But the problem is cost, latency and performance depending on their server traffic and location. Alternatively you could use VPN on the public internet like OpenVPN. But that solution does not work on carrier grade network which mobile phones use. So if you want to access a mobile phone that is in your home network from outside, it will not work. However there is a solution for that and one of them is by using ZeroTier. You can learn more about it from the following video.



I went with ZeroTier because it was easy to setup, it is open source and I was able to make it work on all the devices that I needed. First you need to create an account on their website. Then create a private network which all your home network devices can join. For example, my network looks like this


My Zero Tier network


Now to make the clients join the network so they can talk to each other over public network you will need to run a client on all the devices. So I installed one on my linux laptop. On NixOS it is as simple as adding this configuration


services.zerotierone = {
  enable = true;
  joinNetworks = [
    "<my-network-id>"
  ];
};


That simple configuration not only runs the ZeroTier service but also joins my network. On android devices I installed ZeroTier One. You will need to open the app and manually enter the network ID. Finally on my media center PC (running CoreElec), which is an ARM based CPU, I installed it via opkg install zerotier. Then I added the following two lines to the script that runs automatically every time the device boots up.


zerotier-one -d
zerotier-cli join <my-network-id>


That’s it. I assigned static IPs to all the devices so I can directly connect to them from anywhere on the internet. This is how I have been managing my home network devices. Hope it helps someone. Although I haven’t tried Zero Tier on ESP8266, there is one under development which you could give a try.