
import struct
import types
import json
import syslog
from time import sleep

from onvif import ONVIFCamera
from onvif.exceptions import ONVIFError
mycam = 0
media = 0
ptz = 0
media_profile = 0
request = 0
onvif_error_info = 0
ptz_error_info = 0

def InitIPCamera(ip_addr, port, user, password):
	syslog.syslog("python ipcamera InitIPCamera")
	global mycam, media, ptz, media_profile, request, onvif_error_info, ptz_error_info
	print(ip_addr, port, user, password)

	try:
		if mycam:
			print mycam
			syslog.syslog("python ipcamera update auth url")
			mycam.update_auth(user,password)
			mycam.update_url(ip_addr, port)

		syslog.syslog("python ipcamera ONVIFCamera in...")
		mycam = ONVIFCamera(ip_addr, 80, user, password, '/usr/wsdl')
		syslog.syslog("python ipcamera ONVIFCamera out...")
		# Create media service object
		media = mycam.create_media_service()

		# Get target profile
		media_profile = media.GetProfiles()[0]
		try:
			# Create ptz service object
			ptz = mycam.create_ptz_service()
			request = ptz.create_type('GetConfigurationOptions')
			request.ConfigurationToken = media_profile.PTZConfiguration._token
			ptz_configuration_options = ptz.GetConfigurationOptions(request)

			ptz.Stop({'ProfileToken': media_profile._token})
		except ONVIFError,e:
			syslog.syslog("python ipcamera ptz except...")
			syslog.syslog(e.reason)
			ptz_error_info = e.reason
			ptz = 0
		else:
			ptz_error_info = 0
			syslog.syslog("python ipcamera  ptz ok...")
	except ONVIFError,e:
		syslog.syslog("python ipcamera exceptions")
		syslog.syslog(e.reason)
		onvif_error_info = e.reason
		media_profile = 0
	else:
		syslog.syslog("python ipcamera ONVIFCamera init ok...")
		# Get PTZ configuration options for getting continuous move range
		
def ipc_CheckPtz():
	if ptz_error_info != 0 or ptz == 0:
		return 1
	return 0

def ipc_GetStreamUri():
	print 'ipc_GetStreamUri...'
	request = media.create_type('GetStreamUri')
	request.ProfileToken = media_profile._token
	url = media.GetStreamUri(request)
	print url, "url"
	obj_result = {}
	obj_result['rtspUrl'] = url.Uri
	obj_result['streamCnt'] = len(media.GetProfiles())
	obj_result['result'] = 0
	data_json = json.dumps(obj_result)
	return data_json

def perform_move(ptz, request, timeout):
    # Start continuous move
    ptz.ContinuousMove(request)
    # Wait a certain time
    sleep(timeout)
    # Stop continuous move
    ptz.Stop({'ProfileToken': request.ProfileToken})

def move_ContinuousMove(x, y, z=0, timeout=1):
    print 'move_ContinuousMove...'
    request = ptz.create_type('ContinuousMove')
    request.ProfileToken = media_profile._token
    request.Velocity.PanTilt._x = x
    request.Velocity.PanTilt._y = y
    request.Velocity.Zoom._x = z
    perform_move(ptz, request, timeout)

def perform_RelativeMove(ptz, request, timeout):
    # Start continuous move
    ptz.RelativeMove(request)
    # Wait a certain time
    sleep(timeout)
    # Stop continuous move
    ptz.Stop({'ProfileToken': request.ProfileToken})
    
def move_RelativeMove(x, y, z=0, timeout=1):
    print 'move_RelativeMove...'
    syslog.syslog('move_RelativeMove...')
    request = ptz.create_type('RelativeMove')
    request.ProfileToken = media_profile._token
    request.Translation.PanTilt._x = x
    request.Translation.PanTilt._y = y
    request.Translation.Zoom._x = z
    perform_RelativeMove(ptz, request, timeout)

def ptz_GetPresets():
	print 'ptz_GetPresets...'
	syslog.syslog('ptz_GetPresets...')
	request = ptz.create_type('GetPresets')
	request.ProfileToken = media_profile._token
	presets = ptz.GetPresets(request)
	obj_result = {}
	data = []
	for index in range(len(presets)):
		tmp_data = {}
		tmp_data['token'] = presets[index]._token
		tmp_data['name'] = presets[index].Name
		data.append(tmp_data)

	obj_result['result'] = 0
	obj_result['presets'] = data
	data_json = json.dumps(obj_result)
	return data_json

def ptz_SetPreset(name):
	print 'ptz_SetPreset...'
	syslog.syslog('ptz_SetPreset...')
	request = ptz.create_type('SetPreset')
	request.ProfileToken = media_profile._token
	request.PresetName = name
	token = None
	try:
		token = ptz.SetPreset(request)
	except ONVIFError,e:
		token = None
	else:
		return token
	return token
    
def ptz_GotoPreset(token):
    print 'ptz_GotoPreset...'
    syslog.syslog('ptz_GotoPreset...')
    request = ptz.create_type('GotoPreset')
    request.ProfileToken = media_profile._token
    request.PresetToken = token
    preset = ptz.GotoPreset(request)

def ptz_RemovePreset(token):
    print 'ptz_RemovePreset...'
    syslog.syslog('ptz_RemovePreset...')
    request = ptz.create_type('RemovePreset')
    request.ProfileToken = media_profile._token
    request.PresetToken = token
    preset = ptz.RemovePreset(request)

def ptz_GotoHomePosition():
    print 'ptz_GotoHomePosition...'
    syslog.syslog('ptz_GotoHomePosition...')
    request = ptz.create_type('GotoHomePosition')
    request.ProfileToken = media_profile._token
    preset = ptz.GotoHomePosition(request)

def ptz_SetHomePosition():
    print 'ptz_SetHomePosition...'
    syslog.syslog('ptz_SetHomePosition...')
    request = ptz.create_type('SetHomePosition')
    request.ProfileToken = media_profile._token
    preset = ptz.SetHomePosition(request)

def perform_AbsoluteMove(ptz, request, timeout):
    # Start continuous move
    ptz.RelativeMove(request)
    # Wait a certain time
    sleep(timeout)
    # Stop continuous move
    ptz.Stop({'ProfileToken': request.ProfileToken})
    
def move_AbsoluteMove(x, y, z=0, timeout=1):
    print 'move_AbsoluteMove..1.'
    request = ptz.create_type('AbsoluteMove')
    request.ProfileToken = media_profile._token
    request.Position.PanTilt._x = x
    request.Position.PanTilt._y = y
    request.Position.Zoom._x = z
    perform_RelativeMove(ptz, request, timeout)

def protocol_encode(json_str, length):
	err_code=0
	#parse
	obj=json.loads(json_str)
	obj_result={}
	#encode
	identifier = obj['identifier']
	syslog.syslog("python ipcamera protocol_encode in...")
	if identifier == 'InitIPCamera':
		print(obj['ip_addr'], obj['port'], obj['user'], obj['password'])
		InitIPCamera(obj['ip_addr'], obj['port'], obj['user'], obj['password'])
		if media_profile == 0:
			err_code = 1
			obj_result['error_info'] = onvif_error_info

		obj_result['result'] = err_code
		json_str=json.dumps(obj_result)
		print json_str, 'json_str...'
		return 12288+err_code,json_str,len(json_str)
	elif media_profile == 0:
		err_code = 1
		obj_result['result'] = err_code
		obj_result['error_info'] = onvif_error_info
		json_str=json.dumps(obj_result)
		print json_str, 'json_str...'
		return 12288+err_code,json_str,len(json_str)
	elif identifier == 'RelativeMove':
		err_code = ipc_CheckPtz()
		if err_code != 0:
			obj_result['error_info'] = ptz_error_info
		else:
			move_RelativeMove(obj['x'], obj['y'])
		obj_result['result'] = err_code
		json_str=json.dumps(obj_result)
		print json_str, 'json_str...'
		return 12288+err_code,json_str,len(json_str)
	elif identifier == 'GetStreamUri':
		json_str = ipc_GetStreamUri()
		print json_str, 'json_str...'
		return 12288+err_code,json_str,len(json_str)
	elif identifier == 'GetPresets':
		err_code = ipc_CheckPtz()
		if err_code != 0:
			obj_result['error_info'] = ptz_error_info
			obj_result['result'] = err_code
			json_str=json.dumps(obj_result)
		else:
			json_str = ptz_GetPresets()
		print json_str, 'json_str...'
		return 12288+err_code,json_str,len(json_str)
	elif identifier == 'SetPreset':
		err_code = ipc_CheckPtz()
		if err_code != 0:
			obj_result['error_info'] = ptz_error_info
		else:
			preset_token = ptz_SetPreset(obj['preset_name'])
			if preset_token == None:
				err_code = 1
			else:
				obj_result['preset_token'] = preset_token
		obj_result['result'] = err_code
		json_str=json.dumps(obj_result)
		print json_str, 'json_str...'
		return 12288+err_code,json_str,len(json_str)
	elif identifier == 'GotoPreset':
		err_code = ipc_CheckPtz()
		if err_code != 0:
			obj_result['error_info'] = ptz_error_info
		else:
			preset_token = ptz_GotoPreset(obj['preset_token'])
		obj_result['result'] = err_code
		json_str=json.dumps(obj_result)
		print json_str, 'json_str...'
		return 12288+err_code,json_str,len(json_str)
	elif identifier == 'RemovePreset':
		err_code = ipc_CheckPtz()
		if err_code != 0:
			obj_result['error_info'] = ptz_error_info
		else:
			preset_token = ptz_RemovePreset(obj['preset_token'])
		obj_result['result'] = err_code
		json_str=json.dumps(obj_result)
		print json_str, 'json_str...'
		return 12288+err_code,json_str,len(json_str)
	elif identifier == 'GotoHomePosition':
		err_code = ipc_CheckPtz()
		if err_code != 0:
			obj_result['error_info'] = ptz_error_info
		else:
			preset_token = ptz_GotoHomePosition()
		obj_result['result'] = err_code
		json_str=json.dumps(obj_result)
		print json_str, 'json_str...'
		return 12288+err_code,json_str,len(json_str)
	elif identifier == 'SetHomePosition':
		err_code = ipc_CheckPtz()
		if err_code != 0:
			obj_result['error_info'] = ptz_error_info
		else:
			preset_token = ptz_SetHomePosition()
		obj_result['result'] = err_code
		json_str=json.dumps(obj_result)
		print json_str, 'json_str...'
		return 12288+err_code,json_str,len(json_str)
	elif identifier == 'ContinuousMove':
		err_code = ipc_CheckPtz()
		if err_code != 0:
			obj_result['error_info'] = ptz_error_info
		else:
			move_ContinuousMove(obj['x'], obj['y'])
		obj_result['result'] = err_code
		json_str=json.dumps(obj_result)
		print json_str, 'json_str...'
		return 12288+err_code,json_str,len(json_str)	
	else:
		syslog.syslog("ERROR can't find cmd")

	syslog.syslog("python ipcamera protocol_encode out...")
	obj_result['result'] = 1
	json_str=json.dumps(obj_result)
	return 4097,json_str,len(json_str)

def protocol_decode(input_str, length):
    err_code=0
    #parse arg
    input_obj=json.loads(input_str)
    bin_str=input_obj['raw_data']
    id=input_obj['identifier']
    fmt=">3B9H"
    obj={}
    #convert
    t_str=''
    for i in range(0,len(bin_str),2):
        t_str=t_str + chr(int(bin_str[i:i+2], 16))
    bin_str=t_str
    #parse
    addr,_,_,wendu,shidu,guangzhao,zaosheng,PM2,PM10,daqiya,TVOC,crc=struct.unpack(fmt, bin_str)
    #calc
    obj['wendu_DLg7l']=round((wendu&0x7F00)/10.0,2)
    obj['shifushidu_tNmsf']=round(shidu/10.0,2)
    obj['zhaodu_OiTQg']=guangzhao*4
    obj['zaoyin_hqSLz']=round(zaosheng/10,2)
    obj['PM25_NOhQr']=PM2
    obj['PM10_2unGk']=PM10
    obj['daqiya']=round(daqiya/100.0,2)
    obj['TVOC']=round(TVOC/10.0,2)
    #encode
    obj['identifier']=id
    obj['term_addr']=("%02X" % addr)
    json_str=json.dumps(obj)
    #print(err_code, json_str, len(json_str))
    return err_code,json_str,len(json_str)

#init_ipcamera()
# move right
#move_ContinuousMove(1, 0)
#move_ContinuousMove(0, 1)
#move_RelativeMove(1, 0)
#move_AbsoluteMove(1, 0, 0)

#init_ipcamera('{"ip":"192.168.0.103","port":80,"user":"admin","password":"a12345678","identifier":"init"}',91)
#protocol_encode('{"ip":"192.168.0.103","port":80,"user":"admin","password":"a12345678","identifier":"AbsoluteMove","x":1,"y":0}',111)
#protocol_decode('{"identifier":"post","raw_data":"010310012A021B002F022B000D0011FFFFFFFF59B7"}',74)
        
