Nanit Baby Monitor Integration

Totally agree, Adam. Your message is oddly-timed as I’m currently spooling up a VM as a new Docker host for this very purpose!

Going forward, I’m going to look at turning this into a Supervisor Add In. My understanding is limited here, but I think these are essentially just containerised services with some Supervisor-friendly stuff on top.

Thank you so much. I really appreciate it. I’m just getting started with of this, and the primary way I learn is by watching how you guys fix things.

I tried (and failed) a workaround by setting up two extra Nanit accounts with permissions only to see one camera each, and run two separate Nanit containers, but for some reason I couldn’t figure out how to get the live stream to the second camera. The camera I named “live” would always work in VLC and the second one I’d name “live2” would never. User error obviously, and I’m sure something I don’t yet understand.

And I appreciate your comments re: docker.

I can definitely respect this. Appreciate taking the time making the response a “softer” landing considering so many different ways it could have been written. Totally understand the “strategy” and future and it makes sense. A point of view from some of us that have went “all in” years ago in Hass, we have weathered some “tough” strategy changes, nobody to blame, it’s how this beautiful solution has naturally evolved for the better. What started off as a ‘copy this image’ or running a few commands to run Hass, has changed to ‘what in the world is python and why do i need to upgrade it’, ‘moving to hass.io from virtual environment’, to now using docker. Yes, you are absolutely correct, barrier to entry is a bit rough and a learning curve to some of us that learning yaml was a big undertaking and adapting to releases/breaking changes over the years, docker will yet need to be one of those hurdles we need to overcome.

The challenge here is, some of our instances have become increasingly complex and possibly not compatible with docker without further investment/customization. Regardless, this too we’ll overcome and we’ll need folks like you to push us along. Thanks again for putting this together and one of these long weekends where the kids behave, i’ll take the plunge and get my arms around docker. Enjoy the holidays and stay away from the keyboard :slight_smile:

Thank you for your kind response. I am glad to hear also your perspective. I do have to admit that I might have been bit blind to those struggles in my message. Honestly, I was bit worried not to start any flames, but you have proven to me once again that this community can be kind and respecting.

A lot of people here are driven only by their enthusiasm without it being similar to their daily profession. Always evolving technologies can be difficult to grasp when you are dealing with them only from time to time. I don’t want to go too off-topic here, just wanted to share few thoughts that might help to maybe give somebody the final nudge to try something new/different :slight_smile:

1 Like

Hello Johnny,

I have created quick fix for multiple cameras. It is currently in the dev branch for testing. You can try it out by using registry.gitlab.com/adam.stanek/nanit:dev image and setting NANIT_LOCAL_STREAM_PUSH_TARGET="rtmp://myip:1935/live/{babyUid}".

The reason why the live2 endpoint wouldn’t work for you even with 2 containers is, that if you are using the tiangolo/nginx-rtmp server in the default configuration it is only registered to URL prefix /live. But you can use whatever suffix you would like (/live/whatever). More info https://hub.docker.com/r/tiangolo/nginx-rtmp/.

Let me know if it works for you. I will probably release it as a next version later this week, once the other changes (sensors read out) are proven to be stable enough.

Hi Adam,

Sorry, having a little trouble with latest dev branch. Am I supposed to set 2 of these in the environment, one for each camera ID? NANIT_LOCAL_STREAM_PUSH_TARGET=“rtmp://myip:1935/live/{babyUid}”

Tried a few different ways…VLC doesn’t recognize any of the rtmp URL’s I’ve pasted.

Also, any thoughts on how to get the sensors into HB?

Thanks again for all your help!

Sorry, it was slightly confusing. You should leave the {babyUid} part as it is. It is going to be replaced by UID of each of yours babies. Then check the log of the application it should give you hint what URLs should you use in your VLC (with the UID part replaced).

Only one variable definition is enough, it would be overwritten otherwise.

For the sensors, I implemented them using MQTT. I have not yet written any proper docs for it, but if you are impatient you can inspire yourself with home assistant snippet https://gitlab.com/adam.stanek/nanit/-/blob/dev/docs/home-assistant.md. Also the environment variables are commented in https://gitlab.com/adam.stanek/nanit/-/blob/dev/.env.sample

It works! Thank you so much.

Gotcha, thanks for clarifying. Still having trouble getting the stream to load in VLC. FWIW, I’m running the container on my Pi. So I’m restreaming to 127.0.0.1. In VLC I’ve swapped it with the local IP for my Pi (yes this IP is reserved on my router).

You shouldn’t use 127.0.0.1. Use your local IP. It is not the application which is connecting to the RTMP server but the cam itself, so it has to be reachable from it.

Just coming back to say:

  1. This is STILL awesome!
    (I have an automation to put the camera on all the fireHD wall tablets when naptime is on, so I can just glance at the tablets without opening the app!)

  2. Did you mention dev branch has sensor info? If so do you have any more info about that?

:frowning: I don’t know why it’s still not working…the log shows that it’s pushing the streams of both cameras but VLC won’t open the network stream

I can’t really help you unless you provide me with some info.

I recently run into situation when local streaming silently stopped working. There is a limit of number of devices which cam supports. During the night there was Internet dropout by my provider and all the phones switched to local streaming. That kicked out the restreamer as it was above that limit.

I am thinking how to make it more robust because unless it is rock solid it won’t pass WAF.

I have improved processing of error responses from the cam in the latest version. Maybe it can give you a clue. Also you can try setting NANIT_LOG_LEVEL=debug for additional info.

1 Like

Hey Adam, please see below

$ docker run --rm -e NANIT_EMAIL="****" -e NANIT_PASSWORD="****" -e NANIT_REMOTE_STREAM_ENABLED=false -e NANIT_HTTP_ENABLED=false -e NANIT_LOCAL_STREAM_ENABLED=true -e NANIT_LOCAL_STREAM_PUSH_TARGET=rtmp://****:1935/live/{babyUid} -e NANIT_LOG_LEVEL=debug registry.gitlab.com/adam.stanek/nanit:dev
21 Dec 20 19:32 UTC INF Application started gitversion=157166b8
21 Dec 20 19:32 UTC INF No .env file found. Using only environment variables path=/app/.env
21 Dec 20 19:32 UTC INF Setting log level to debug
21 Dec 20 19:32 UTC INF Directory created ./video dir=/app/data/video
21 Dec 20 19:32 UTC INF Directory created ./log dir=/app/data/log
21 Dec 20 19:32 UTC INF Fetching babies list
21 Dec 20 19:32 UTC INF Authorizing using user credentials email=**** password=********************
21 Dec 20 19:32 UTC INF Authorized token=e3b1****************************************c568
21 Dec 20 19:32 UTC INF Connected to websocket url=wss://api.nanit.com/focus/cameras/****/user_connect
21 Dec 20 19:32 UTC DBG Sending message data="type:REQUEST request:{id:1 type:GET_SENSOR_DATA getSensorData:{all:true}}"
21 Dec 20 19:32 UTC INF Requesting local streaming target=rtmp://****:1935/live/****
21 Dec 20 19:32 UTC DBG Sending message data="type:REQUEST request:{id:2 type:PUT_STREAMING streaming:{id:MOBILE status:STARTED rtmpUrl:\"rtmp://****:1935/live/****\" attempts:3}}"
21 Dec 20 19:32 UTC INF Connected to websocket url=wss://api.nanit.com/focus/cameras/****/user_connect
21 Dec 20 19:32 UTC DBG Sending message data="type:REQUEST request:{id:1 type:GET_SENSOR_DATA getSensorData:{all:true}}"
21 Dec 20 19:32 UTC INF Requesting local streaming target=rtmp://****:1935/live/****
21 Dec 20 19:32 UTC DBG Sending message data="type:REQUEST request:{id:2 type:PUT_STREAMING streaming:{id:MOBILE status:STARTED rtmpUrl:\"rtmp://****:1935/live/****\" attempts:3}}"
21 Dec 20 19:32 UTC DBG Received message data="type:RESPONSE response:{requestId:1 requestType:GET_SENSOR_DATA statusCode:200 sensorData:{sensorType:TEMPERATURE isAlert:false timestamp:1363676 valueMilli:22631 value:23} sensorData:{sensorType:HUMIDITY isAlert:false timestamp:1363676 valueMilli:31378 value:31} sensorData:{sensorType:LIGHT isAlert:false timestamp:1363676 valueMilli:548000 value:548}}"
21 Dec 20 19:32 UTC DBG Received sensor data update humidity=31.378 temperature=22.631
21 Dec 20 19:32 UTC DBG Received message data="type:RESPONSE response:{requestId:1 requestType:GET_SENSOR_DATA statusCode:200 sensorData:{sensorType:TEMPERATURE isAlert:false timestamp:571974 valueMilli:23535 value:24} sensorData:{sensorType:HUMIDITY isAlert:false timestamp:571974 valueMilli:28582 value:29} sensorData:{sensorType:LIGHT isAlert:false timestamp:571974 valueMilli:50000 value:50}}"
21 Dec 20 19:32 UTC DBG Received sensor data update humidity=28.582 temperature=23.535
21 Dec 20 19:32 UTC DBG Received message data="type:RESPONSE response:{requestId:2 requestType:PUT_STREAMING statusCode:200 7:\"\\x08\\x02\\x10\\x00\\x1a'rtmps://****PUBLIC_IP****:47142/nanit/p2p\"}"
21 Dec 20 19:32 UTC DBG Received message data="type:RESPONSE response:{requestId:2 requestType:PUT_STREAMING statusCode:200 7:\"\\x08\\x02\\x10\\x00\\x1a'rtmps://****PUBLIC_IP****:59456/nanit/p2p\"}"
21 Dec 20 19:32 UTC DBG Received message data="type:REQUEST request:{id:467 type:PUT_SENSOR_DATA sensorData:{sensorType:TEMPERATURE isAlert:false timestamp:571998 valueMilli:23525 value:24}}"
21 Dec 20 19:32 UTC DBG Received sensor data update temperature=23.525
21 Dec 20 19:32 UTC DBG Received message data="type:REQUEST request:{id:468 type:PUT_SENSOR_DATA sensorData:{sensorType:HUMIDITY isAlert:false timestamp:571998 valueMilli:28582 value:29}}"
21 Dec 20 19:32 UTC DBG Received sensor data update humidity=28.582
^C21 Dec 20 19:33 UTC DBG Received message data="type:REQUEST request:{id:523 type:PUT_SENSOR_DATA sensorData:{sensorType:TEMPERATURE isAlert:false timestamp:1363707 valueMilli:22591 value:23}}"
21 Dec 20 19:33 UTC DBG Received sensor data update temperature=22.591
21 Dec 20 19:33 UTC DBG Received message data="type:REQUEST request:{id:524 type:PUT_SENSOR_DATA sensorData:{sensorType:HUMIDITY isAlert:false timestamp:1363707 valueMilli:31378 value:31}}"
21 Dec 20 19:33 UTC DBG Received sensor data update humidity=31.378
21 Dec 20 19:33 UTC WRN Received interrupt signal, terminating
21 Dec 20 19:33 UTC INF Closing baby babyuid=****
21 Dec 20 19:33 UTC DBG Closing websocket on interrupt
21 Dec 20 19:33 UTC WRN Disconnected from server
21 Dec 20 19:33 UTC INF Closing baby babyuid=****
21 Dec 20 19:33 UTC DBG Closing websocket on interrupt
21 Dec 20 19:33 UTC ERR Disconnected from server error="read tcp 172.17.0.2:42336->3.225.131.121:443: use of closed network connection"

Hi, just noting that in the past 48 hours running your dev registry I only seem to have one camera at a time working.

I restart the container and it generally fixes the problem for a minute and then one of the cameras won’t stream over VLC or through Homebridge (which I know is not the point of this thread just noting it seems to be a not streaming problem not a platform problem). Which camera it is seems to be random and nothing in the log seems to be off.

Anyways, it’s not a big deal because I can create two accounts with just one camera access and it seems to fix the issue. Just wanted to note it in case it’s something on the Nanit side. If I notice it starts to be one camera consistently even with my workaround I will update, as then it would obviously be an issue w my camera.

Thanks again.

Yeah I’m trying to figure out how to get this to work on HOOBS…

Thanks again @velky.bloud! I can watch the baby monitor on my Apple Watch wherever I’m at!

2 Likes

The log looks good to me, but it is bit trickier problem to debug. It is important to keep in mind that the video stream is NOT actually going through the app. It is streamed directly from the cam to the RTMP server. The communication flow is illustrated here: https://gitlab.com/adam.stanek/nanit/-/blob/dev/docs/nanit-local-streaming.svg

Because of that if anything happens with the stream itself we cannot really know on the app’s end. You would have to debug that in cam and nginx logs. But before you dive into that please double check that the RTMP server is reachable from the cam. You cannot use your localhost IP for NANIT_LOCAL_STREAM_PUSH_TARGET. Also always make sure that the RTMP server is up and running before you attempt to start the app. Cam might want to start streaming at the time when the server is simply just getting started and refusing all connections.

From the top of my head I cannot think of anything which would cause that. I have no way of testing that myself, but we can try to work something out if it turns out to be an issue for you. Just start a ticket on the gitlab repo, so that we don’t spam this thread.

Hello guys, after longer pause I am getting back with some updates.

In order to make this useful, I really want to make sure that the streaming is solid, so that I can rely on it for baby monitoring. Sadly this is rather difficult given the way how cam operates. (Just a reminder, it pushes the video stream directly to the RTMP server without it going through the app. Illustrated here: https://gitlab.com/adam.stanek/nanit/-/blob/dev/docs/nanit-local-streaming.svg)

It is more or less reliable based on stability of your environment (your local network, internet connection, etc.) but obviously there can be dropouts.

I was thinking how to make this better. There are basically 2 options, either I would have to integrate the RTMP server into the app so that I can react to any stream dropouts, or leave it as a separate server and listen to it. Given the complexity of the first option I have decided to try the second approach first and see if will solve the issue. I have implemented simple watchdog which subscribes to the stream and listens to it. If there is any dropout it tries to reinitiate it.

It is currently implemented in the dev branch for you to try it out.

If you are interested in sensors, you can try them out on the dev branch too. You can find some basic info here: https://gitlab.com/adam.stanek/nanit/-/blob/dev/docs/sensors.md. I will leave out to the community to write some more comprehensive guide how to glue all the pieces together.

After you guys let me know it works well for you, I will release it as another stable version.

2 Likes