Nanit Baby Monitor Integration

I’m running Hassio from the official image on a Raspberry Pi and Node-Red for my automations.

So this is what you can do if you have a similar setup:

  1. Enable ffmpeg in HA like this: https://www.home-assistant.io/integrations/ffmpeg/#configuration
  2. Add this to the config
camera:
  - platform: ffmpeg
    input: !include nanitinput.yaml
    name: Nanit
  1. Import this into Node-Red. This flow will retrieve baby_uid and accesstoken automatically every 2 hours and build the corresponding feed URL which will be written into a file called nanitinput.yaml, which is what the config file reads.
[{"id":"95617a57.280438","type":"inject","z":"c35e4544.aab968","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"7200","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":720,"wires":[[]]},{"id":"a83d0bad.d2ae48","type":"http request","z":"c35e4544.aab968","name":"POST","method":"POST","ret":"txt","paytoqs":"ignore","url":"https://api.nanit.com/login","tls":"","persist":false,"proxy":"","authType":"","x":410,"y":720,"wires":[["a61e3ce5.84f8e"]]},{"id":"7cb6d684.58bd18","type":"function","z":"c35e4544.aab968","name":"","func":"msg.payload = { \n  \"email\" :\"XXXXX\",\n  \"password\" :\"XXXXX\"\n}\nmsg.headers = {};\nmsg.headers['x-tc-transform'] = 'tti-app';\nmsg.headers['Content-Type'] = 'application/json';\nmsg.headers['x-tc-transformVersion'] = '0.2';\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":280,"y":720,"wires":[["a83d0bad.d2ae48"]]},{"id":"a61e3ce5.84f8e","type":"json","z":"c35e4544.aab968","name":"","property":"payload","action":"","pretty":false,"x":530,"y":720,"wires":[["c887b424.95deb8"]]},{"id":"c887b424.95deb8","type":"change","z":"c35e4544.aab968","name":"Filter token","rules":[{"t":"set","p":"nanittoken","pt":"flow","to":"payload.access_token","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":720,"wires":[["fcb222c3.0bf"]]},{"id":"557ade78.7148b","type":"file","z":"c35e4544.aab968","name":"Write to nanitinput.yaml","filename":"/config/nanitinput.yaml","appendNewline":true,"createDir":false,"overwriteFile":"true","encoding":"none","x":1690,"y":720,"wires":[[]]},{"id":"57b64395.3f180c","type":"function","z":"c35e4544.aab968","name":"Construct Feed URL","func":"msg.payload = \"-i rtmps://media-secured.nanit.com/nanit/\"+ flow.get(\"nanitbabyuid\") +\".\" + flow.get(\"nanittoken\")\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1460,"y":720,"wires":[["557ade78.7148b"]]},{"id":"66828159.0a098","type":"http request","z":"c35e4544.aab968","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://api.nanit.com/babies","tls":"","persist":false,"proxy":"","authType":"","x":970,"y":720,"wires":[["c3b81b67.b9b618"]]},{"id":"fcb222c3.0bf","type":"function","z":"c35e4544.aab968","name":"","func":"msg.headers = {};\nmsg.headers['x-tc-transform'] = 'tti-app';\nmsg.headers['Content-Type'] = 'application/json';\nmsg.headers['x-tc-transformVersion'] = '0.2';\nmsg.headers['Authorization'] = 'Token ' + flow.get(\"nanittoken\");\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":820,"y":720,"wires":[["66828159.0a098"]]},{"id":"c3b81b67.b9b618","type":"json","z":"c35e4544.aab968","name":"","property":"payload","action":"","pretty":false,"x":1110,"y":720,"wires":[["f23be6d0.b6a698"]]},{"id":"f23be6d0.b6a698","type":"change","z":"c35e4544.aab968","name":"Filter babyuid","rules":[{"t":"set","p":"nanitbabyuid","pt":"flow","to":"payload.babies.uid","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1260,"y":720,"wires":[["57b64395.3f180c"]]}]
  1. Make sure to replace both XXXXX with your username and password in the first function node

Since I haven’t been using this for too long, I’m not sure if refreshing the token every 2 hours is too little or too much. But this can be changed later at the bottom of the inject node.

EDIT: Not working as expected. Requires a restart of Hassio in order to detect changes to the token.

Hello guys, I am just getting back to you with some status update (nothing interesting pushed to repo just yet).

I managed to make the websocket connection work. Was able to get majority of interesting stuff described. But it turned out to be bit disappointing. Yes, it is possible to read the temperature and send some commands (night light, play tunes, …), but I was hoping to get access to the motion and sound sensors as well. That does not seem to be possible to my current understanding, but I will keep digging.

I would really like to somehow leverage the motion / sound alerts for automation.

As far the live stream goes, I have discovered some interesting hints about the local streaming. If it would be possible we might be able to communicate with the cam without streaming it to the Internet first.

2 Likes

Local streaming would be great to have! Being able to turn on whitenoise remotely would also be amazing so I can automate it for when the lights turn off.

I am experiencing, however, almost 30 seconds lag in the feed. Anyone else having this issue?

Hi @velky.bloud, amazing work (and amazing work everyone!). I’m curious, are you able to pull any sense of status (e.g. baby asleep, awake) and time in status? I’d see that as immensely useful for automation, as a way to ensure things don’t wake the baby (e.g. lower TV volume if baby is asleep), give you a version of presence detection, and a way to automate reminders (e.g. play a reminder on Sonos to wake the baby after 2 hours).

Again, amazing work and looking forward to trying it all out!

not quite 30 seconds, but a noticeable delay for sure. If local is a possibility that will mitigate this (fingers crossed)

Sadly no status events like that are coming over websockets. There might be possibility to somehow gather that info from events, but it is not exactly ideal.

If you don’t mind me asking, how were you able to determine the endpoint for the stream?

I got the stream URL from running the APK in Andriod Studio simulator. It crashes after a while due some incompatibilities, but it still manages to do some initial communication. The URL is taken out of the logs of running application.

The MITM approach would be challenging for RTMPS.

Yeah, that’s what I’ve found. Are you able to use the same method to check the local stream by forcing your nanit off the internet at your router/gateway?

Actually no. To my current knowledge, there is no local stream. The communication is outbound. The client starts up its own RTMP server and sends URL to the cam. The cam then starts streaming to that URL. I was able to make this work against nginx-rtmp in some PoC fashion. But the results are not that much better than through the remote streaming :frowning: There is still about 2s delay for some reason. Maybe I just need to tweak the server settings a bit.

I wonder what the maximum number of devices it can support in local mode is.

Not sure about the streams, but I have discovered there is a hard limit of 2 websocket connections on the local device. So I assume there will be some limit for concurrent streams too.

Hello everybody,

I just released major update of the Nanit restreamer. It now supports local streaming :tada:

Please have a look and let me know what you think.

The next step is to support read out of the sensors data. Majority of the work is already done. The cam is periodically communicating any temperature and humidity updates to the app. All that is needed is to expose that data over HTTP / MQTT so that it can be consumed on the Home Assistant front.

I am looking for contributors at this point. My week of paternity leave is getting to the end so I would like to pass the project to the community. If you can help with the implementation or even write a nice guide how to integrate everything with Home Assistant it would be helpful.

Hope it finds you well.

A.

7 Likes

I will try and help out where I can.

I bought a Miku baby monitor. Does anyone know if Miku can be integrated into HA?

Following this thread because I’m interested in Nanit + Homebridge. @velky.bloud thanks for all your effort! Any news on the hb front?

It should work with the HB as well. Both HA and HB support FFMPEG based camera streams. You can just feed it with RTMP served by your local server (you can run it like described at https://gitlab.com/adam.stanek/nanit#b-restream-to-local-rtmp-server).

I got this error: **FTL** Server responded with unexpected status code code=401
log shows this error: FTL Missing environment variable NANIT_EMAIL

any ideas? I typed everything in correctly

from looking at the set up you can either use the .env file, or when you use the docker run command be sure to use -e [email protected] etc

sorry for the ignorance, first time using docker. how can I set the .env file? Also, the docker run command did include the email line (obviously modified to match my email).

could it be an issue with 2 step verification?