dzVents Script for Dahua IP Cameras (Switch day/night profile)

Moderator: leecollings

Post Reply
BakSeeDaa
Posts: 485
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi / ODroid
Domoticz version:

dzVents Script for Dahua IP Cameras (Switch day/night profile)

Post by BakSeeDaa »

Inspired by a post on IP Cam Talk made by @nayr, I made a dzvents script that takes care of that task. The script adds temperature and humidity to the camera OSD. I also added the ability to enable and disable privacy masks. Tested on Dahua IPC-HDW4231EM-AS and IPC-HDW5231R-Z

Prerequisites: dzVents version 2.3.1 or higher.

Documentation is the code. Some notes though ...

You should create a virtual switch device to control the privacy masks.

Each camera is defined in the webCams table. Each entry has a ['switchProfiles'] key. It can be a boolean or a function.
['switchProfiles'] = true The camera will switch profiles according to the timer triggers defined in TIME_SWITCH_DAY_PROFILE and TIME_SWITCH_NIGHT_PROFILE

['switchProfiles'] = false Profile switching will not occur.

['switchProfiles'] = function Define a function that either returns "day" or "night". Make sure to also add devices you use in your function as dzVents device triggers (if needed). (Named LightingMood in the example code below)

This script will need some customization and changes to work on your system. It's not intended to work "as is" for everyone. If you like it, copy it and make it yours. Don't try this script unless you are quite familiar with Lua scripting and dzvents. If You have IP camera related questions you should ask them on IP Cam Talk.

Code: Select all

--[[
dahuaCams.lua, a Domoticz dzVents Script for Dahua IP Cameras


--]]

local SEC_MASK_DEV_NAME = 'SEC MASK' -- The name of the device in your system
local TIME_INTERVAL = 'every 15 minutes'
local TIME_SWITCH_DAY_PROFILE = '5 minutes before sunrise'
local TIME_SWITCH_NIGHT_PROFILE = '5 minutes after sunset'
local SCRIPT_VERSION = '1.0.0'

return {
	active = true,
	logging = {
		level = domoticz.LOG_INFO, -- Select one of LOG_DEBUG, LOG_INFO, LOG_ERROR, LOG_FORCE to override system log level
		marker = 'dahuaCams V'..SCRIPT_VERSION
	},
	on = {
		devices = {SEC_MASK_DEV_NAME, 'LightingMood'},
		timer = {TIME_INTERVAL, TIME_SWITCH_DAY_PROFILE, TIME_SWITCH_NIGHT_PROFILE}
	},
	data = {
		camsLastProfile = {initial={}}, odTemp = {initial=-273.15}, odHum = {initial=-1}, idTemp = {initial=-273.15}, idHum = {initial=-1}
	},
	execute = function(domoticz, device, triggerInfo)

		-- ========================================
		local CAM_DOMAIN = 'somedomain.com' -- 
		local camLogin = 'admin:XXXPASSYYY'
		-- ========================================

		local webCams = {
			['cam-driveway'] = {['enabled'] = true, ['PTZ'] = false,['outDoors'] = true, ['useSecMask'] = true, ['switchProfiles'] = true,},
			['cam-living-room'] = {['enabled'] = true, ['PTZ'] = false, ['outDoors'] = false, ['useSecMask'] = false, ['switchProfiles'] =
				function(domoticz, device, triggerInfo)
					if domoticz.devices('Day State').text == 'night'
					and domoticz.devices('LightingMood').text == 'off' then
						return 'night'
					else
						return 'day'
					end
				end},
			['cam-main-entrance'] = {['enabled'] = true, ['PTZ'] = false, ['outDoors'] = true, ['useSecMask'] = true, ['switchProfiles'] = true},
		}

		-- Make sure that there is a saved day/night profile state in the array for each camera
		local camsLastProfile = domoticz.data.camsLastProfile
		for key, _value in pairs(webCams) do
			if camsLastProfile[key] == nil then
				camsLastProfile[key] = 'unknown'
			end
		end

		if triggerInfo.type == domoticz.EVENT_TYPE_DEVICE then

			if device.name == SEC_MASK_DEV_NAME then
				local toState = tostring(device.active)
				for hostName, camConfig in pairs(webCams) do
					if camConfig.enabled and camConfig.useSecMask then
						domoticz.log('Setting security mask for camera: '..hostName..' to: '..toState, domoticz.LOG_INFO)
						domoticz.openURL(camLogin..'@'..hostName..'.'..CAM_DOMAIN..'/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].Covers[0].EncodeBlend='..toState..'&VideoWidget[0].Covers[1].EncodeBlend='..toState..'&VideoWidget[0].Covers[2].EncodeBlend='..toState..'&VideoWidget[0].Covers[3].EncodeBlend='..toState)
					end
				end
			else

				-- A device event occurred. We need to go through all the cameras that have
				-- a function defined for switching between day/night mode. Cameras that have a boolean
				-- for switching between day/night mode are not handled here (See timer triggerd events) 
				domoticz.log('A device event for '..device.name..' occurred that might cause shifting day/night profile', domoticz.LOG_INFO)
				for hostName, camConfig in pairs(webCams) do
					local switchProfiles = (type(camConfig.switchProfiles) == 'function') and camConfig.switchProfiles(domoticz, device, triggerInfo) or false
					if camConfig.enabled and switchProfiles and camsLastProfile[hostName] ~= switchProfiles then
						camsLastProfile[hostName] = switchProfiles -- Saving state
						if camConfig.PTZ then
							domoticz.log('Switching PTZ cam: '..hostName..' to use '..switchProfiles..' profile', domoticz.LOG_INFO)
							local newValue = switchProfiles == 'day' and '1' or '2'
							domoticz.openURL(camLogin..'@'..hostName..'.'..CAM_DOMAIN..'/cgi-bin/configManager.cgi?action=setConfig&VideoInMode[0].Config[0]='..newValue)
						else
							domoticz.log('Switching IPC cam: '..hostName..' to use '..switchProfiles..' profile', domoticz.LOG_INFO)
							local newValue = switchProfiles == 'day' and '0' or '3'
							domoticz.openURL(camLogin..'@'..hostName..'.'..CAM_DOMAIN..'/cgi-bin/configManager.cgi?action=setConfig&VideoInOptions[0].NightOptions.SwitchMode='..newValue)
						end
					end
				end

			end

		elseif triggerInfo.type == domoticz.EVENT_TYPE_TIMER then

			if triggerInfo.trigger == TIME_INTERVAL then 
				-- Outdoor and indoor Temp and humidity for camera OSD
				local odTemp = domoticz.round(domoticz.devices('F750 Outdoor Temp.').temperature, 1)
				local odHum = domoticz.round(domoticz.devices('Vinden C + RH').humidity, 0)
				local idTemp = domoticz.round(domoticz.devices('WH2600 Indoor TempHum').temperature, 1)
				local idHum = domoticz.round(domoticz.devices('WH2600 Indoor TempHum').humidity, 0)
		
				if (odTemp ~= domoticz.data.odTemp) or (odHum ~= domoticz.data.odHum) then
					domoticz.data.odTemp = odTemp
					domoticz.data.odHum = odHum
					local osdText = string.gsub(domoticz.urlEncode(tostring(odTemp)..'°C, '.. tostring(odHum)..'% RH'), '+', '%%20')
					for hostName, camConfig in pairs(webCams) do
						if camConfig.enabled and camConfig.outDoors then
							domoticz.log('Cam: '..hostName..': '..tostring(odTemp)..'°C, '.. tostring(odHum)..'% RH', domoticz.LOG_INFO)
							domoticz.openURL(camLogin..'@'..hostName..'.'..CAM_DOMAIN..'/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text='..osdText)
						end
					end
				end
				if (idTemp ~= domoticz.data.idTemp) or (idHum ~= domoticz.data.idHum) then
					domoticz.data.idTemp = idTemp
					domoticz.data.idHum = idHum
					local osdText = string.gsub(domoticz.urlEncode(tostring(idTemp)..'°C, '.. tostring(idHum)..'% RH'), '+', '%%20')
					for hostName, camConfig in pairs(webCams) do
						if camConfig.enabled and not camConfig.outDoors then
							domoticz.log('Cam: '..hostName..': '..tostring(idTemp)..'°C, '.. tostring(idHum)..'% RH', domoticz.LOG_INFO)
							domoticz.openURL(camLogin..'@'..hostName..'.'..CAM_DOMAIN..'/cgi-bin/configManager.cgi?action=setConfig&VideoWidget[0].CustomTitle[1].Text='..osdText)
						end
					end
				end

			-- Toggling day/night mode for cameras that has ['switchProfiles'] = true (Must be a boolean and set to true)
			elseif triggerInfo.trigger == TIME_SWITCH_DAY_PROFILE or triggerInfo.trigger == TIME_SWITCH_NIGHT_PROFILE then 
				domoticz.log('Time for switching cameras to use the day/night profile', domoticz.LOG_INFO)
				for hostName, camConfig in pairs(webCams) do
					--local switchProfiles = (type(camConfig.switchProfiles) == 'function') and camConfig.switchProfiles(domoticz, device, triggerInfo) or camConfig.switchProfiles
					local switchProfiles = (type(camConfig.switchProfiles) == 'function') and false or camConfig.switchProfiles
					local newState = (triggerInfo.trigger == TIME_SWITCH_DAY_PROFILE and 'day' or 'night')
					if camConfig.enabled and switchProfiles and camsLastProfile[hostName] ~= newState then
						camsLastProfile[hostName] = newState -- Saving state
						if camConfig.PTZ then
							domoticz.log('Switching PTZ cam: '..hostName..' to use '..newState..' profile', domoticz.LOG_INFO)
							local newValue = triggerInfo.trigger == TIME_SWITCH_DAY_PROFILE and '1' or '2'
							domoticz.openURL(camLogin..'@'..hostName..'.'..CAM_DOMAIN..'/cgi-bin/configManager.cgi?action=setConfig&VideoInMode[0].Config[0]='..newValue)
						else
							domoticz.log('Switching IPC cam: '..hostName..' to use '..newState..' profile', domoticz.LOG_INFO)
							local newValue = triggerInfo.trigger == TIME_SWITCH_DAY_PROFILE and '0' or '3'
							domoticz.openURL(camLogin..'@'..hostName..'.'..CAM_DOMAIN..'/cgi-bin/configManager.cgi?action=setConfig&VideoInOptions[0].NightOptions.SwitchMode='..newValue)
						end
					end
				end
			end

		end

	end
}
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest