Temperature Overlay in Dahua Cameras

DavidDavid

Getting comfortable
Jan 29, 2017
604
266
Ohio
Does anybody have a way to overlay the current temperature onto the camera image?

I have a couple cameras that I'd like to display the temperature and I feel like that should be something that is possible.

I have Dahua cameras and a Dahua nvr and am thinking that i can pull the temperature from Domoticz i currently have running on a raspberry pi. For now I'd be happy with the temperature pulled from the internet, but in the future I'd like to add some temperature sensors to Domoticz and use that data.
 
I use a cron job with Openhab to display the temps on mine. I don't know anything about Domoticz, but it's probably similar. I have a Raspberry Pi with a temp sensor, and Openhab polls it every few minutes to get the current temp.

Code:
<?php
//get garage temp from Openhab
$dookie = file_get_contents("http://192.168.2.1:8080/rest/items/GarageTemp/state");
//round to nearest tenth
$stinker = round($dookie,1);
//send temp to camera
exec("curl -u user:pass --anyauth -g \"http://10.0.0.51/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=$stinker%20F\"");
?>

rqSbsiL.jpg
 
Last edited:
I finally got a temperature sensor reporting to Domoticz and I'm trying to get it to display on my camera feed. I tried stealing the lua script from @nayr from his git hub page and recreating it in my Domoticz
Code:
-- Garage Temp OSD
--GARtemp = (otherdevices_temperature['Garage'] * 9) / 5 + 32
--GARtemp = libs.round(GARtemp,1)
--if (GARtemp ~= tonumber(uservariables["GARTemp"])) then
-- commandArray["Variable:GARTemp"]=tostring(GARtemp)
-- commandArray['OpenURL'] = uservariables['camLogin'] .. '@192.168.42.25/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=' .. tostring(GARtemp) .. '°F'
-- print('Updating temp on garage osd')
--end

-- Outdoor Temp OSD
ODtemp = (otherdevices_temperature['Online Weather'] * 9) / 5 + 32
ODtemp = libs.round(ODtemp,1)
if (ODtemp ~= tonumber(uservariables["ODTemp"])) then
commandArray["Variable:ODTemp"]=tostring(ODtemp)
commandArray['OpenURL'] = uservariables['camLogin'] .. '@north-ptc/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=' .. tostring(ODtemp) .. '°F'
print('Updating temp on north ptz osd')
end

and below is what I tried to convert it to my settings, but it isn't working (big surprise)

Code:
-- Coop Temp OSD
Coop Temp = (otherdevices_temperature['Coop Temp']
Coop Temp = libs.round(Coop Temp,1)
if (Coop Temp ~= tonumber(uservariables["Coop Temp"])) then
        commandArray["Variable:Coop Temp"]=tostring(Coop Temp)  
        commandArray['OpenURL'] = uservariables['username:password'] .. '@192.168.1.55/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=' .. tostring(Coop Temp) .. '°F'
   print('Updating Coop Temp osd')
end

Does anybody have an idea as to what I'm doing wrong? Disclaimer -- I have no idea what I'm doing....

@randytsuch
 
The only thing I edited out of that second set of code was the ['username: password'] in my setup I actually have my username and password there.
 
Hi David
I have no idea what or how Nayr did that.
All of my domoticz scripts are in dzvents, which is similar to lua but different lol.
So I'm not used to how to call domoticz variables and stuff from scripts because dzvents does it differently.

I think the key to Nayr's script is this line
commandArray['OpenURL'] = uservariables['username:password'] .. '@192.168.1.55/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=' .. tostring(Coop Temp) .. '°F'

OpenURL would be making a browser call.
I don't understand what uservariables['username:password'] does.
I would guess Nayr also created a user variable, likely string type, that is used here, but not sure how.

I think if you figure out how to add an overlay from a browser from a PC on your network, then you could adjust the OpenURL command to make it work correctly.

Sorry I can't help more.

Maybe try asking on the Domoticz forum.

EDIT. I'm not sticking my tongue out lol

Randy
 
Well, after a lot of trial and error (still don't really know what I'm doing haha) I got it to work. Haven't figured out how to get rid of the decimal yet (these sensors aren't even accurate to the 1/10 of a degree anyway) but it's at least usable. All that's really left to do is actually mount this all in its permanent location.

Screenshot_20170914-124738.png

I'll post my code, what I changed and some other notes later tonight or this week. I'm tired of doing all of this on my phone!
 
Last edited:
The following is for someone as new as me that wants to get this working. If you have domoticz, you can probably just use online weather if you wanted to get started. That was my plan but I didn't get my ass in gear till I got my temperature sensor hardware and put it all together.

Ok so I tried getting the temperature (from the sensor that's still on my workbench) ported into a second camera. To set the scene I've got two cameras, one insinde my chicken coop and one in the chicken run. So I've named these events Coop and Run so you can follow along with the code. I've pretty much stolen all of this from @nayr so thank you to him.

Code:
commandArray = {}
libs = require("libs")

-- Coop Temp OSD
Coop = otherdevices_temperature['Coop Temp']*9/5+32
Coop = libs.round(Coop,0)
if (Coop ~= tonumber(uservariables["Coop"])) then
        commandArray["Variable:Coop"]=tostring(Coop)
        commandArray['OpenURL'] = uservariables['camlogin'] .. '@192.168.1.55/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=' .. tostring(Coop) .. '°F'
   print('Updating Coop Temp OSD')
end

-- Run Temp OSD
Run = otherdevices_temperature['Coop Temp']*9/5+32
Run = libs.round(Run,0)
if (Run ~= tonumber(uservariables["Run"])) then
        commandArray["Variable:Run"]=tostring(Run)
        commandArray['OpenURL'] = uservariables['camlogin'] .. '@192.168.1.56/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=' .. tostring(Run) .. '°F'
   print('Updating Run Temp OSD')
end

return commandArray

I know nothing about this stuff but I'll share what I have figured out so far. The code above is what I've got in Domoticz. The libs = require("libs") line pulls some common functions that @nayr uses in a lot of his code into this so he/you/I don't have to retype a bunch of stuff. I followed his github section on his libs file and made one myself.

Follow this link to his page about that - domoticz-scripts/libs.lua at master · nayrnet/domoticz-scripts · GitHub

Basically I made the folders he lists at the top on my Raspberry PI in the places he says to. Then used nano to make a file with all of the actual code in it and named it libs.lua simple as that. Then the libs = require("libs") & Coop = libs.round(Coop,0) & Run = libs.round(Run,0) lines worked for me which was really cool because I got rid of the decimal (these temp sensors aren't good to the 1/10 of a degree anyway).


Code:
 Coop = otherdevices_temperature['Coop Temp']*9/5+32
Coop = libs.round(Coop,0)
This line makes Coop a variable I think, and it pulls the data from my temperature device that I've named Coop Temp and converts it from C to F then stores the data under Coop. Then it takes Coop and rounds it to 0 decimal places.

Code:
 if (Coop ~= tonumber(uservariables["Coop"])) then
        commandArray["Variable:Coop"]=tostring(Coop)

This converts the numeric value of Coop to a string so that it is a word not a number.

Code:
commandArray['OpenURL'] = uservariables['camlogin'] .. '@192.168.1.56/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=' .. tostring(Run) .. '°F'
I had to go into domoticz and set a custom uservariable of 'camlogin' this is my username : password (without the spaces...I added those to not make it show this in the middle :p ) saved under "camlogin" this way I can use "camlogin" instead of putting my actual credentials in each piece of code. It's either safer or easier or both, not sure, you'd have to ask @nayr
Then it logs into my camera and adds °F to the end. (note, I was/am having issues and it's nice to add numbers or letters before the degree symbol to make sure the OSD is actually updating for testing)

Code:
   print('Updating Run Temp OSD')

this just updates the log. Useful to see if it thinks its working or not.

Right now I'm having an issue though, for some reason it's only updating the second camera. I just copied and pasted my code and changed what I needed to change, but for some reason it's only updating whatever is last and I'm not sure why.
 
Last edited:
Oh and one more very important thing.... Make sure that the screen overlay option is enabled in the cameras settings.
 
Just wanted to share my implentation using a bash script (see below). The script is located in /home/pi/domoticz/scripts and is called tempcam.sh

192.168.1.1 is my domoticz Server (not the real ip of course)

316 is the index of the temperature sensor i use

I'm cutting off to 1 digit

then I send it to 2 camera's (Ip's ending with .2 and .3), also note that the camera's both have different ways of logging on.

In my crontab I have the following;

*/15 * * * * sudo /home/pi/domoticz/scripts/tempcam.sh >/dev/null 2>&1

This updates my camera's every 15 minutes. The script can be triggered manually of course.

To check if the temp is at least retrieved you can uncomment the line
# echo "Temp=$TEMP" (so remove the #)

Code:
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/pi/domoticz/scripts

SHELL=/bin/sh

function jsonValue() {
   KEY=$1
   num=$2
   awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'$KEY'\042/){print $(i+1)}}}' | tr -d '"' | sed -n ${num}p
}
DOMOTICZ=`curl -s --connect-timeout 2 --max-time 5 "http://192.168.1.1:8080/json.htm?type=devices&rid=316"`
if [ -z "$DOMOTICZ" ]
then
   exit 1

else
   TEMP=$(echo $DOMOTICZ | jsonValue Temp 1)
   TEMPCLEAN=${TEMP%.*}
   TEMP=$(printf '%.1f' $TEMP)
#  echo "Temp=$TEMP"
fi

# Frontdoor
URL="http://admin:pass@192.168.1.2/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=Temp%20$TEMP%20°C"
# Remove spaces, otherwise url is invalid
URL=$(echo $URL | tr -d ' ')
# Send to cam
curl -g --user admin:pass --digest $URL

# Backdoor
URL="http://admin:pass@192.168.1.3/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=Temp%20$TEMP%20°C"
# Remove spaces, otherwise url is invalid
URL=$(echo $URL | tr -d ' ')
# Send to cam
curl -g $URL
 
Last edited:
Update to "my" code. (not really mine...I didn't build it, but it works perfectly now)

Code:
time = os.date("*t")
mins = time.min + time.hour * 60
commandArray = {}
libs = require("libs")
cmdurl = "/cgi-bin/configManager.cgi?action=setConfig&VideoInOptions[0].NightOptions.SwitchMode="

-- Coop Temp OSD
Coop = otherdevices_temperature['Coop Temp']*9/5+32
Coop = libs.round(Coop,0)
if (Coop ~= tonumber(uservariables["Coop"])) then
        table.insert(commandArray, {["Variable:Coop"] = tostring(Coop)})
        table.insert(commandArray, {['OpenURL'] = uservariables['camlogin'] .. '@192.168.1.55/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=' .. tostring(Coop) .. '°F'})
   print('Updating Coop Temp OSD')
end

-- Run Temp OSD
Run = otherdevices_temperature['Coop Temp']*9/5+32
Run = libs.round(Run,0)
if (Run ~= tonumber(uservariables["Run"])) then
        table.insert(commandArray, {["Variable:Run"]=tostring(Run)})  
        table.insert(commandArray, {['OpenURL'] = uservariables['camlogin'] .. '@192.168.1.56/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=' .. tostring(Run) .. '°F'})
   print('Updating Run Temp OSD')
end

-- Day/Night Video Profile Switching
if (mins >= timeofday['SunsetInMinutes']) and (tonumber(uservariables["ODCam-Profile"]) ~= 1) then
   print("Switching Outdoor Cameras to Night Profile.")
   table.insert(commandArray, {['OpenURL'] = table.concat({uservariables['camlogin'], "@192.168.1.52", cmdurl, '3' })})
   table.insert(commandArray, {['OpenURL'] = table.concat({uservariables['camlogin'], "@192.168.1.53", cmdurl, '3' })})
   table.insert(commandArray, {['OpenURL'] = table.concat({uservariables['camlogin'], "@192.168.1.54", cmdurl, '3' })})
   table.insert(commandArray, {['OpenURL'] = table.concat({uservariables['camlogin'], "@192.168.1.55", cmdurl, '3' })})
     table.insert(commandArray, {['OpenURL'] = table.concat({uservariables['camlogin'], "@192.168.1.56", cmdurl, '3' })})
     table.insert(commandArray, {["Variable:ODCam-Profile"] = "1" })
elseif (mins >= timeofday['SunriseInMinutes']) and (tonumber(uservariables["ODCam-Profile"]) ~= 0) and (mins < timeofday['SunsetInMinutes']) then
   print("Switching Outdoor Cameras to Day Profile.")
   table.insert(commandArray, {['OpenURL'] = table.concat({uservariables['camlogin'], "@192.168.1.52", cmdurl, '0' })})
   table.insert(commandArray, {['OpenURL'] = table.concat({uservariables['camlogin'], "@192.168.1.53", cmdurl, '0' })})
   table.insert(commandArray, {['OpenURL'] = table.concat({uservariables['camlogin'], "@192.168.1.54", cmdurl, '0' })})
   table.insert(commandArray, {['OpenURL'] = table.concat({uservariables['camlogin'], "@192.168.1.55", cmdurl, '0' })})
     table.insert(commandArray, {['OpenURL'] = table.concat({uservariables['camlogin'], "@192.168.1.56", cmdurl, '0' })})
     table.insert(commandArray, {["Variable:ODCam-Profile"] = "0" })
end

return commandArray

reference - Script only running the second command - Domoticz
 
@raymondkoppen
well done. I hope your scrip can be used on my cams behind a nvr and raspberian too, I will try to use it for controlling focus and day/night
Maybe spaces in the url has causes my problems.
 
I played around a while, but for an nvr it´s not working. I can´t find anywhere a valid http-api description for nvr. It´s in fact not the same url, because you must give a channel parameter, but I don´t know how. Has someone an idea?

edit:
damm :banghead: how simple, i found it:
for example:
Code:
URL="http://x.x.x.x/cgi-bin/devVideoInput.cgi?action=autoFocus&channel=1"
 
Last edited:
  • Like
Reactions: Bramboo
Hi all..
I'm trying to use the http API and the CustomTitle[1].Text object (I think it's an object) to overlay windspeed. It's working on the Main Stream, but I can't work out how to enable OSD on the Sub Stream that Easy4ip seems to use.

So... can OSD be displayed on Easy4ip? Can Easy4ip display the Main Stream instead of Substream?

All advice welcome!

PS: is there a specific sub-forum for Easy4ip questions? I have multiple issues :)
 
Just wanted to share my implentation using a bash script (see below). The script is located in /home/pi/domoticz/scripts and is called tempcam.sh

192.168.1.1 is my domoticz Server (not the real ip of course)

316 is the index of the temperature sensor i use

I'm cutting off to 1 digit

then I send it to 2 camera's (Ip's ending with .2 and .3), also note that the camera's both have different ways of logging on.

In my crontab I have the following;

*/15 * * * * sudo /home/pi/domoticz/scripts/tempcam.sh >/dev/null 2>&1

This updates my camera's every 15 minutes. The script can be triggered manually of course.

To check if the temp is at least retrieved you can uncomment the line
# echo "Temp=$TEMP" (so remove the #)

Code:
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/pi/domoticz/scripts

SHELL=/bin/sh

function jsonValue() {
   KEY=$1
   num=$2
   awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'$KEY'\042/){print $(i+1)}}}' | tr -d '"' | sed -n ${num}p
}
DOMOTICZ=`curl -s --connect-timeout 2 --max-time 5 "http://192.168.1.1:8080/json.htm?type=devices&rid=316"`
if [ -z "$DOMOTICZ" ]
then
   exit 1

else
   TEMP=$(echo $DOMOTICZ | jsonValue Temp 1)
   TEMPCLEAN=${TEMP%.*}
   TEMP=$(printf '%.1f' $TEMP)
#  echo "Temp=$TEMP"
fi

# Frontdoor
URL="http://admin:pass@192.168.1.2/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=Temp%20$TEMP%20°C"
# Remove spaces, otherwise url is invalid
URL=$(echo $URL | tr -d ' ')
# Send to cam
curl -g --user admin:pass --digest $URL

# Backdoor
URL="http://admin:pass@192.168.1.3/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=Temp%20$TEMP%20°C"
# Remove spaces, otherwise url is invalid
URL=$(echo $URL | tr -d ' ')
# Send to cam
curl -g $URL



thanks, your script works for me, but how to add humidity value in this same script?
I want temperature and humidity in the same camera
 
thanks, your script works for me, but how to add humidity value in this same script?
I want temperature and humidity in the same camera

To also add Humidity, add this right after the temp is fetched (after 'fi') , change the id (1218) to a domoticz device that has your humidity

Bash:
DOMOTICZ=`curl -s --connect-timeout 2 --max-time 5 "http://192.168.1.1:8080/json.htm?type=devices&rid=1218"`
if [ -z "$DOMOTICZ" ]
then
   exit 1

else
   HUM=$(echo $DOMOTICZ | jsonValue Humidity 1)
   HUM=$(printf '%.1f' $HUM)
#  echo "Humidity=$HUM"
fi

Then change camera URL= to include the humidity;

Bash:
URL="http://192.168.1.2/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text=Temp%20$TEMP%20°C%20Hum%20$HUM%25"
 
Last edited:
  • Like
Reactions: betogar
How much of the entire exercise do you need or want to carry out with c++ ?

My understanding is that updating OSD with the http API pretty much has to use 'digest' authentication. That is trivial in a scripting environment (e.g. curl in any Unix, or an analgous Windows utility). You could get all the functionality in a program using libcurl, but.... it seems like a lot of integration work if you don't very specifically need it.

Once upon a time I did implement a standalone digest auth.... that's a week of my life I will never get back. Do it as an intellectual exercise if you are that way inclined, but there are much easier ways of getting stable digest auth.

If you are reading your temperature probe or otherwise retrieving data with c++ code then you could use that code to format the OSD then (in a Unix environment) call a curl script to write to the screen. For example:

Bash:
#!/bin/bash

# HTTP GET to IP address $1 path '/cgi-bin/configManager.cgi' sending $2 as data
#  NB: $2 can be '@filename'

curl -s --anyauth -u USERNAME:PASSWORD -d $2 -G http://$1/cgi-bin/configManager.cgi
 
Hello all,

I have a question regarding overlaying the temperature meassured by a sensor on a dahua camera.
Did already someone try to do this with a Teltonika RUT956 router. The Teltonika RUT956 has a RS485, RS232 and some analog/digital inputs.

The idea is that the temperature-sensor will be connect to the Teltonika router (idealy via RS485) and the router sends the measured value to a server or directly to the camera.

Would this be possible? When yes, can someone help to set this up.

Best Josef