docs: function OnvifDevice(params) {
  	if (!params || typeof (params) !== 'object') {
  		throw new Error('The parameter was invalid.');
  	}
  
  	this.address = '';
  	this.xaddr = '';
  	this.user = '';
  	this.pass = '';
  	this.keepAddr = false;
  	this.lastResponse = null; // for debug
  
  	if (('xaddr' in params) && typeof (params['xaddr']) === 'string') {
  		this.xaddr = params['xaddr'];
  		let ourl = mUrl.parse(this.xaddr);
  		this.address = ourl.hostname;
  	} else if (('address' in params) && typeof (params['address']) === 'string') {
  		this.keepAddr = true;
  		this.address = params['address'];
  		this.xaddr = 'http://' + this.address + '/onvif/device_service';
  	} else {
  		throw new Error('The parameter was invalid.');
  	}
  	if (('user' in params) && typeof (params['user']) === 'string') {
  		this.user = params['user'] || '';
  	}
  	if (('pass' in params) && typeof (params['pass']) === 'string') {
  		this.pass = params['pass'] || '';
  	}
  
  	this.oxaddr = mUrl.parse(this.xaddr);
  	if (this.user) {
  		this.oxaddr.auth = this.user + ':' + this.pass;
  	}
  
  	this.time_diff = 0;
  
  	this.information = null;
  	this.services = {
  		'device': new mOnvifServiceDevice({ 'xaddr': this.xaddr, 'user': this.user, 'pass': this.pass }),
  		'events': null,
  		'imaging': null,
  		'media': null,
  		'ptz': null
  	};
  	this.profile_list = [];
  
  	this.current_profile = null;
  	this.ptz_moving = false;
  
  	mEventEmitter.call(this);
  }