Project : Off-grid? Stand-alone NTP server with GPS

The reasons for this project:

  1. there are off-grid scenarios where you want HE but have no Internet service.

  2. the HE hub does not include a battery-backed RTC (real time clock) and if NTP servers aren't immediately available over the Internet at the time you boot or reset the hub, the system can end up not knowing the correct time of day - result, your time-based modes, automations and rules don't run properly.

  3. A strong marketing message and raison-detre of Hubitat is local execution, ie not relying on cloud services like other home automation platforms. However, dependency on internet NTP servers to set the time is one area where it is currently not purely local as billed.

Time is available from GPS satellites. A USB GPS receiver costs about $14. We can use this to set the time of a NTP server running on a raspberry pi or home router. Then we just need to have HE get its time from our now-synced ntp server.

My first attempt with this has been successful so far.

Im using a Mikrotik hAP lite router RB951, but you can use any Mikrotik router that has a USB port. The RB951 is around $41. I connected the VK-162 GPS device ($14) to the USB port of the router. I installed the extra GPS and NTP packages and rebooted.

I logged in with Mikrotik's winbox admin tool. I enabled the GPS and set the port to USB0, and bang - instantly, the Mikrotik set its system clock to the correct time. GPS hadn't even had time to sync up or get lock, and the puck is just sitting on my desk indoors, not near a window, no clear line of sight to the sky at all. I guess one of the first messages it gets from the birds is the time.

All good so far. Next I enabled the NTP server, I unchecked the options for broadcast, multicast and manycast as I didnt want possibly wrong time being sprayed all over my LAN. I put a static IP on it from my LAN, and went ahead and tested the server using the ntpdate -q command on a linux terminal. The ntp server correctly responds with the correct time, and it shows its at stratum 4, which should be plenty good enough for any client to set their time to.

The next step, which I have not yet fully tested with HE due to not having a dev HE hub to play with, is to set the Mikrotik router up as the dhcp, dns and ntp server for the HE. We can intercept the DNS requests coming from HE and respond to them with our own IP address.

So now HE is using us as its DNS server, and we just answer any request for with our own IP address.

So if you are planning to deploy HE at a off-grid location with no internet, you would still need to initially connect it to the internet in order to do the initial registration and on-boarding. You could build your Mikrotik router with the following config, and then take it to the site, connect HE to Mikrotik port 1 and it should just work.

/ip address add address= interface=ether1
/ip pool add name=dhcp_pool0 ranges=
/ip dhcp-server add address-pool=dhcp_pool0 disabled=no interface=ether1 name=dhcp1
/ip dhcp-server network add address= gateway=
/ip firewall nat add action=redirect chain=dstnat dst-port=53 protocol=udp
/ip dns set allow-remote-requests=yes
/ip dns static add address=
/system gps set enabled=yes port=usb1 set-system-time=yes
/system ntp server set enabled=yes manycast=no

This could all be done on a Raspberry Pi too with dnsmasq, chrony, gpsd etc, but, as they say, thats an exercise left up to the reader.

The Hubitat team could enable support for time syncing from USB GPS dongles (connected via a USB hub) in an update, and this would remove one more dependency on Internet/cloud.


Is there any process to intercept the ntp request from HE or enabling the ntp server on the mikrotik will make HE to get the time from the local server?

Its done by faking the DNS responses, when HE tries to look up, the mikrotik answers with its own IP address.

1 Like

Maybe this could be a feature request for Hubitat... add a setting to specify what the NTP server should be in the first place. That way you will not need to fake it going forward.

1 Like

Ideally, yep. Its been requested I think, doesnt mean it will happen. in the meantime, there is this.

There's nothing really wrong giving back a :"fake" reply It's a pool of public servers anyways, and you never know which one you're going to get. So you know if that's all the hackishness required that's doing pretty well.

And presumably if it didn't have ntp is would just be a free running clock and you could use your browser to set if I put a Product Manager hat on, that's a pretty good solution for a small edge case. :slight_smile:

1 Like

You can do pretty much everything really easily with a pfSense appliance. Could run on a Pi as well I believe. Just my two cents. Added benefits are HAProxy for SSL termination (with automated letsencrypt support), business grade firewall, VLANS, and built in DNS/NTP/etc. Plus it's really easy to use/set up.

I was curious, I don't do the fake ntp reply DNS thing, but I do set the NTP DHCP option on my DHCP server. I'm not sure if this is respected by the HE Hub, but after looking through my firewall logs, I don't see any NTP requests to external servers.

My DHCP server put's out the time server info and the Hubitat doesn't use it. Neither does a few other devices like Ooma, Vizio TV's. etc.

I put a log rule to count NTP packets from the HE about a week ago, it has logged precisely zero packets. So I think we can assume HE is not running ntpd. Probably it runs something like ntpdate only once at boot time and then is free running thereafter. I would expect to see some drift over time if that was the case, and indeed my HE time is about 8 seconds off ntp time right now, my hub has been up 15 days.

So to the HE devs, it sure seems like running the ntp daemon would be a good idea to a) keep it synced, and b) to let it sync by itself if ntp isn't immediately available at boot time.

1 Like

+1 to the feature requests to both:

  • Allow us to specify a NTP server, I run one locally on a rPi that with a LONG battery backup
  • Actually run ntpd or regular ntp updates to ensure the local clock doesn't drift too much

Thanks for your work on this Jon.

There doesn't appear to be a way to set the time in the browser. And this "locally running" Hubitat needs internet, but only uses it once when it boots? Why not just let user set it than? Sheesh.

I'm starting to wonder what I got myself into.

You can set it in the browser, its under Settings Hub Details.


I haven't verified this locally yet but you could potentially have your server that runs ntpd for your local network cron this curl command (with your hub's IP):

curl '' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' --data "`date +"%d %b %Y %l:%M:%S"`"

The Update Time from Browser Time button just does a POST to that /location/updateTime URL with a string formatted like '19 Sep 2019 10:11:22'


time change failed

Looks like it doesn't like the left-padded hour, but it does work with a 0 padded hour.

I just verified this works locally for me (change hubitat to your hub's IP/hostname)

curl 'http://hubitat/location/updateTime' --data "$(date +"%d %b %Y %H:%M:%S")"

I guess the next step is to package this into a shell script, handle the responses, and alert you if there is an error. The two responses I see look like:

{"status":"time changed successfully","currentTime":"2019-09-21 9:30:01 AM PDT"}
{"status":"time changed failed","currentTime":"2019-09-21 9:31:06 AM PDT"}

Both are returned with a HTTP 200 status code.

Just a little teaser: in 2.1.5 there will be a method available to drivers and apps to set the hub time. It will accept a Date object.


Yay! well I'm not going to bother with any more effort then.

Any chance we could just configure a ntp server target and have the hub just run ntpd?

If not sounds like 2.1.5 will let us create a ntp proxy app.

It's one of the many items on the list of improvements. We actually used to run ntpd but shut it off and now use a call to a server to sync time due to some ISPs blocking ntp (I'm looking in your direction at&t!)

1 Like

But that's a cloud dependency......

Download the Hubitat app