<?php

require_once('URCSystemData.php');
require_once('DataGenerator.php');
require_once('RMSDealer.php');
require_once('URCAmazonData.php');

class SystemController extends BaseController {
	
	public function isFactoryUser($username) {

		$factoryUserName = './scripts/factory_user.json';
		if(!file_exists($factoryUserName)) { 

			return false;
		}
		
		$fUserJson = file_get_contents($factoryUserName);
		$fUserData = json_decode($fUserJson);
		if(!isset($fUserData->users) || count($fUserData->users) < 1) {
			return false;
		}

		foreach($fUserData->users as $user) {
			if(strcasecmp($user, $username) == 0) {
				return true;
			}
		}

		return false;
	}
	
	public function doGetSystemTypes() {

		$arData = URCValues::getBasestations();
		return Response::json(array('result' => true, 'data' => json_encode($arData)));
	}

	public function doGetSystemTypesEx() {

		$arData = URCValues::getBasestationsEx();
		return Response::json(array('result' => true, 'data' => $arData));
	}

	public function doGetRemoteTypes() {

		$arData = URCValues::getRemotes();
		return Response::json(array('result' => true, 'data' => json_encode($arData)));
	}

	public function doGetRemoteTypesEx() {

		$arData = URCValues::getRemotesEx();
		return Response::json(array('result' => true, 'data' => $arData));
	}


	public function doSystemControl($funcType, $systemId = -1) {
		
		if(!$this->chkJWTTokenWithLevel(URCValues::LOGIN_USER, $errMsg, $errNo)) {
			return Response::make($errMsg, $errNo);
		}

		if($funcType == 'create') {

			$rules = array(
				'systemName' => 'Required',
				'key' => 'Required|min:16',
				'timezone_id' => 'Required',
				'timezone_dst' => 'Required',
				'time_type' => 'Required',
				'roomName' => 'Required',
				'modelType' => 'Required',
				'bstationName' => 'Required',
				'bstationMac' => 'Required|min:12');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$systemName = Input::get('systemName');
			$modelType = Input::get('modelType');//HCM-C1';			
			$keyValue = Input::get('key');
			$timezoneId = Input::get('timezone_id');//HCM-C1';			
			$timezoneDst = Input::get('timezone_dst');		
			$timeType = Input::get('time_type');
			$roomName = Input::get('roomName');
			$bstationName = Input::get('bstationName');
			$bstationMac = Input::get('bstationMac');	

			$cAddress = '';
			$cPhone = '';
			$cName = '';
			$dealerName = '';
			if(Input::has('customerAddress')) {
				$cAddress = Input::get('customerAddress');
			}
			if(Input::has('customerPhone')) {
				$cPhone = Input::get('customerPhone');
			}
			if(Input::has('customerName')) {
				$cName = Input::get('customerName');
			}
			if(Input::has('installerName')) {
				$dealerName = Input::get('installerName');
			}

			$progKey = BStationManager::genKeyFromUserData($modelType, $keyValue);
			if($progKey === false) {
				return Response::json(array('result' => false, 'error' => 'invalid type key'));
			}

			if(BStationManager::getDataFromKey($progKey, $prgMac, $modelTypeId, $randId) === false ||
				$prgMac !== $bstationMac) {
				return Response::json(array('result' => false, 'error' => 'invalid type key'));
			}

			//Key Check	
			$bstationMgr = new BStationManager(URCValues::WAIT_SEC);		
			//$bstationMgr = new BStationManager('323', 32323, URCValues::WAIT_SEC, 'ad', 'gg'); //$cloudSvr, $cloudPort, URCValues::WAIT_SEC, $cloudAdmin, $cloudPass); 
			if(Config::get('editorenv.debugSkipBStationChk') != true) {
				if($bstationMgr->customCheckKey($progKey) !== true) {
					return Response::json(array('result' => false, 'error' => $bstationMgr->getErrResult()));
				}
			}

			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());
			
			//check already used
			$chkExisting = DB::table('a_bstations')->where('mac', '=', $bstationMac)->first();
			if($chkExisting) {
				//delete existing
				if($urcSystem->deleteBStationFromOther($chkExisting) == false) {
					return Response::json(array('result' => false, 'error' => 'The basestation is already being used'));
				}
			}

			$newControllerId = BStationManager::getControllerIdFromKey($progKey);
			if($newControllerId === false) {
				return Response::json(array('result' => false, 'error' => 'invalid type key'));
			}

			//check existing basestation;
			$sip_user = DB::table('sip_user')->where('mac', '=', $bstationMac)->first();
			if(!$sip_user) {
				return Response::json(array('result' => false, 'error' => 'The basestation is not registered'));
			}
			if($sip_user->controller_id !== $newControllerId) {
				return Response::json(array('result' => false, 'error' => 'The registered basestation is not matched'));
			}

			$bstationId = $urcSystem->createSystem($modelType, $bstationName, $bstationMac, 
				$systemName, $roomName, $newControllerId, $timezoneId, $timezoneDst, $timeType,
				$cAddress, $cName, $cPhone, $dealerName);
			if($bstationId < 0) {
				return Response::json(array('result' => false, 'error' => 'System creation fail'));
			}

			//
			$cspCtlObj = new CSPCtrl();

			$userDetail = DB::table('user_detail')->where('user_id', '=', $this->usr_id)->first();
			if($userDetail) {
				$rmsDealer = new RMSDealer();
				$serialNo = $rmsDealer->getSerialNumber($bstationMac);

				if($cspCtlObj->register($newControllerId, $bstationMac, $userDetail->user_email, Config::get('editorenv.editor_name'), $serialNo) != true) {
					ErrorDebug::write('errorCSP'.$bstationMac);
				}			
			}
			
			return Response::json(array('result' => true, 'bstationId' => $bstationId));
		}

		if($funcType == 'list') {
			
			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());
			$systems = $urcSystem->getSystems();

			foreach($systems as $obj) {
				unset($obj->user_id);
			}

			return Response::json(array('result' => true, 'systems' => $systems));
		}

		if($funcType == 'get') {
			
			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());
			$system = $urcSystem->getSystem($systemId);

			if($system === false) {
				return Response::json(array('result' => false, 'error' => 'user id and system id are not matched' ));
			}

			//ErrorDebug::write('system');
			//ErrorDebug::write(json_encode($system));

			/*
			$genBStation = new BStationDataGenerator(Auth::id(), $systemId);
			$genBStation->save('bstation.json');

			$genClient = new ClientDataGenerator(Auth::id());
			$genClient->saveSystems('client_sys.json');
			$genClient->saveRoom('client_room.json', $systemId, $system->rooms[0]->id);
			*/
			
			$return = array();
			$return['result'] = true;
			$return['data'] = $system;
			return Response::json($return);
		}

		if($funcType == 'delete') {

			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			$foundSystem = URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id()*/, $systemId);
			if($foundSystem === false) {
				return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
			}

			$controllerId = $foundSystem->controller_id;//URCSystemData::getControllerId(Auth::id(), $systemId);
			
			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());
			$result = $urcSystem->destroySystem($systemId);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to delete the system' ));
			}

			$urcSystem->deleteSystemFromDownData($systemId);

			return Response::json(array('result' => true));
		}

		if($funcType == 'edit') {
			
			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			$rules = array(
				'name' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$systemName = Input::get('name');

			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());
			$result = $urcSystem->editSystem($systemId, $systemName);

			URCSystemData::updateEditTime($systemId, '');
			
			return Response::json(array('result' => true));
		}

		if($funcType == 'check_key') {

			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			if(URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id())*/, $systemId) === false) {
				return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
			}

			$rules = array(
				'modelType' => 'Required',
				'key' => 'Required|min:16');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$modelType = Input::get('modelType');//HCM-C1';			
			$keyValue = Input::get('key');
			
			$progKey = BStationManager::genKeyFromUserData($modelType, $keyValue);
			if($progKey === false) {
				return Response::json(array('result' => false, 'error' => 'invalid type key'));
			}

			if(BStationManager::getDataFromKey($progKey, $bstationMac, $modelTypeId, $randId) === false) {
				return Response::json(array('result' => false, 'error' => 'invalid type key'));
			}

			//Key Check	
			$bstationMgr = new BStationManager(URCValues::WAIT_SEC);		
			//$bstationMgr = new BStationManager('323', 32323, URCValues::WAIT_SEC, 'ad', 'gg'); //$cloudSvr, $cloudPort, URCValues::WAIT_SEC, $cloudAdmin, $cloudPass); 
			if(Config::get('editorenv.debugSkipBStationChk') != true) {
				if($bstationMgr->customCheckKey($progKey) !== true) {
					return Response::json(array('result' => false, 'error' => $bstationMgr->getErrResult()));
				}
			}

			//check already used
			$chkExisting = DB::table('a_bstations')->where('mac', '=', $bstationMac)->first();
			if($chkExisting) {
				if($chkExisting->system_id != $systemId) {
					$system = DB::table('a_systems')->where('id', '=', $chkExisting->system_id)->first();
					if($system->user_id == $this->usr_id) {//already used
						return Response::json(array('result' => false, 'error' => 'The basestation is already being used'));
					}
					else {
						$data = array('mac' => $bstationMac, 'room' => '');				
						return Response::json(array('result' => true, 'data' => (object)$data));
					}
				}
				$roomChk = DB::table('a_rooms')->where('id', '=', $chkExisting->room_id)->first();
				if($roomChk) {
					$data = array('mac' => $bstationMac, 'room' => $roomChk->name);
					return Response::json(array('result' => true, 'data' => (object)$data));
				}
			}
			else {			
				$data = array('mac' => $bstationMac, 'room' => '');				
				return Response::json(array('result' => true, 'data' => (object)$data));
			}
		}

		if($funcType == 'assign_master') {

			$rules = array(
				'modelType' => 'Required',
				'key' => 'Required|min:16',
				'roomId' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$modelType = Input::get('modelType');//HCM-C1';			
			$keyValue = Input::get('key');
			$roomId = Input::get('roomId');

			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			$foundSystem = URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id())*/, $systemId);
			if($foundSystem === false) {
				return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
			}

			$progKey = BStationManager::genKeyFromUserData($modelType, $keyValue);
			if($progKey === false) {
				return Response::json(array('result' => false, 'error' => 'invalid type key'));
			}

			if(BStationManager::getDataFromKey($progKey, $prgMac, $modelTypeId, $randId) === false) {
				return Response::json(array('result' => false, 'error' => 'invalid type key'));
			}

			if(!$this->chkUser()) {
				return Response::json(array('result' => false, 'error' => 'Invalid user'));
			}

			$room = DB::table('a_rooms')->where('id', '=', $roomId)->first();
			if(!$room || $room->system_id != $systemId) {
				return Response::json(array('result' => false, 'error' => 'not found'));		
			}			

			$bstationMgr = new BStationManager(URCValues::WAIT_SEC);					

			if(Config::get('editorenv.debugSkipBStationChk') != true) {
				
				//Key Check	
				if($bstationMgr->customCheckKey($progKey) !== true) {
					return Response::json(array('result' => false, 'error' => $bstationMgr->getErrResult()));
				}
			}
			$newControllerId = BStationManager::getControllerIdFromKey($progKey);
			if($newControllerId === false) {
				return Response::json(array('result' => false, 'error' => 'invalid type key'));
			}
			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());

			if(!$urcSystem->changeSystem($this->usr, $systemId, '', $roomId, '', $modelType, $prgMac, $newControllerId)) {
				return Response::json(array('result' => false, 'error' => 'error'));
			}

			URCSystemData::updateEditTime($systemId, '');

			//
			$cspCtlObj = new CSPCtrl();

			$userDetail = DB::table('user_detail')->where('user_id', '=', $this->usr_id)->first();
			if($userDetail) {
				$rmsDealer = new RMSDealer();
				$serialNo = $rmsDealer->getSerialNumber($prgMac);

				if($cspCtlObj->register($newControllerId, $prgMac, $userDetail->user_email, Config::get('editorenv.editor_name'), $serialNo) != true) {
					ErrorDebug::write('errorCSP'.$prgMac);
				}			
			}
			
			return Response::json(array('result' => true));
		}

		if($funcType == 'change_master_from_factory') {

			$rules = array(
				'modelType' => 'Required',
				'mac' => 'Required',
				'org_mac' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$modelType = Input::get('modelType');//HCM-C1';			
			$newMac = Input::get('mac');
			$orgMac = Input::get('org_mac');

			if(strcasecmp($orgMac, $newMac) == 0) {
				return Response::json(array('result' => false, 'error' => 'mac addresses are same'));
			}
			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			$foundSystem = URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id())*/, $systemId);
			if($foundSystem === false) {
				return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
			}

			$controllerId = $foundSystem->controller_id;//URCSystemData::getControllerId(Auth::id(), $systemId);	
						
			if(!$this->chkUser()) {
				return Response::json(array('result' => false, 'error' => 'Invalid user'));
			}
			
			if(!$this->isFactoryUser($this->username)) {
				return Response::json(array('result' => false, 'error' => 'Not factory user'));
			}

			//check already used
			$chkExisting = DB::table('a_bstations')->where('system_id', '=', $systemId)->
				where('mac', '=', $orgMac)->first();
			if(!$chkExisting) {
				return Response::json(array('result' => false, 'error' => 'not found'));
			}
			if(!$chkExisting->master) {
				return Response::json(array('result' => false, 'error' => 'master error'));	
			}

			$roomOrg = DB::table('a_rooms')->where('id', '=', $chkExisting->room_id)->first();
			if(!$roomOrg || $roomOrg->system_id != $systemId) {
				return Response::json(array('result' => false, 'error' => 'not found'));		
			}			

			$bstationMgr = new BStationManager(URCValues::WAIT_SEC);					

			$sip_user = DB::table('sip_user')->where('mac', '=', $newMac)->first();
			if(!$sip_user) {
				return Response::json(array('result' => false, 'error' => 'not registered mac:'.$newMac));
			}

			$newControllerId = $sip_user->controller_id;
			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());

			if(!$urcSystem->changeSystem($this->usr, $systemId, $controllerId, $chkExisting->room_id, $chkExisting->mac, $modelType, $newMac, $newControllerId)) {
				return Response::json(array('result' => false, 'error' => 'error'));
			}

			URCSystemData::updateEditTime($systemId, '');

			//
			$cspCtlObj = new CSPCtrl();

			$userDetail = DB::table('user_detail')->where('user_id', '=', $this->usr_id)->first();
			if($userDetail) {
				$rmsDealer = new RMSDealer();
				$serialNo = $rmsDealer->getSerialNumber($newMac);

				if($cspCtlObj->register($newControllerId, $newMac, $userDetail->user_email, Config::get('editorenv.editor_name'), $serialNo) != true) {
					ErrorDebug::write('errorCSP'.$newMac);
				}			
			}
			
			return Response::json(array('result' => true));
		}

		if($funcType == 'change_master') {

			$rules = array(
				'modelType' => 'Required',
				'key' => 'Required|min:16',
				'org_mac' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$modelType = Input::get('modelType');//HCM-C1';			
			$keyValue = Input::get('key');
			$orgMac = Input::get('org_mac');

			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			$foundSystem = URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id())*/, $systemId);
			if($foundSystem === false) {
				return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
			}

			$controllerId = $foundSystem->controller_id;//URCSystemData::getControllerId(Auth::id(), $systemId);	
						
			$progKey = BStationManager::genKeyFromUserData($modelType, $keyValue);
			if($progKey === false) {
				return Response::json(array('result' => false, 'error' => 'invalid type key'));
			}

			if(BStationManager::getDataFromKey($progKey, $prgMac, $modelTypeId, $randId) === false) {
				return Response::json(array('result' => false, 'error' => 'invalid type key'));
			}

			if(!$this->chkUser()) {
				return Response::json(array('result' => false, 'error' => 'Invalid user'));
			}

			//check already used
			$chkExisting = DB::table('a_bstations')->where('system_id', '=', $systemId)->
				where('mac', '=', $orgMac)->first();
			if(!$chkExisting) {
				return Response::json(array('result' => false, 'error' => 'not found'));
			}
			if(!$chkExisting->master) {
				return Response::json(array('result' => false, 'error' => 'master error'));	
			}

			$roomOrg = DB::table('a_rooms')->where('id', '=', $chkExisting->room_id)->first();
			if(!$roomOrg || $roomOrg->system_id != $systemId) {
				return Response::json(array('result' => false, 'error' => 'not found'));		
			}			

			$bstationMgr = new BStationManager(URCValues::WAIT_SEC);					

			if(Config::get('editorenv.debugSkipBStationChk') != true) {
				/*
				$password = Crypt::decrypt(Auth::user()->password);
				if($bstationMgr->customCheckConnection(Auth::user()->username, $password, Auth::user()->cloud_id, $controllerId) !== true) {
					return Response::json(array('result' => false, 'error' => $bstationMgr->getErrResult()));
				}				
				*/
			
				//Key Check	
				if($bstationMgr->customCheckKey($progKey) !== true) {
					return Response::json(array('result' => false, 'error' => $bstationMgr->getErrResult()));
				}
			}
			$newControllerId = BStationManager::getControllerIdFromKey($progKey);
			if($newControllerId === false) {
				return Response::json(array('result' => false, 'error' => 'invalid type key'));
			}
			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());

			if(!$urcSystem->changeSystem($this->usr, $systemId, $controllerId, $chkExisting->room_id, $chkExisting->mac, $modelType, $prgMac, $newControllerId)) {
				return Response::json(array('result' => false, 'error' => 'error'));
			}
			
			URCSystemData::updateEditTime($systemId, '');

			//
			$cspCtlObj = new CSPCtrl();

			$userDetail = DB::table('user_detail')->where('user_id', '=', $this->usr_id)->first();
			if($userDetail) {
				$rmsDealer = new RMSDealer();
				$serialNo = $rmsDealer->getSerialNumber($prgMac);

				if($cspCtlObj->register($newControllerId, $prgMac, $userDetail->user_email, Config::get('editorenv.editor_name'), $serialNo) != true) {
					ErrorDebug::write('errorCSP'.$prgMac);
				}			
			}
			

			return Response::json(array('result' => true));
		}

		if($funcType == 'change_slave') {

			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			if(URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id())*/, $systemId) === false) {
				return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
			}

			$rules = array(
				'org_mac' => 'Required',
				'modelType' => 'Required',
				'new_mac' => 'Required|min:12');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}			

			$bstationMacOrg = Input::get('org_mac');
			$modelType = Input::get('modelType');//HCM-C1';			
			$bstationMacNew = Input::get('new_mac');

			//check already used
			$chkExisting = DB::table('a_bstations')->where('system_id', '=', $systemId)->
				where('mac', '=', $bstationMacOrg)->first();
			if(!$chkExisting) {
				return Response::json(array('result' => false, 'error' => 'not found'));
			}
			if($chkExisting->master) {
				return Response::json(array('result' => false, 'error' => 'master error'));	
			}

			$roomOrg = DB::table('a_rooms')->where('id', '=', $chkExisting->room_id)->first();
			if(!$roomOrg || $roomOrg->system_id != $systemId) {
				return Response::json(array('result' => false, 'error' => 'not found'));		
			}		

			//check already used
			$chkExisting = DB::table('a_bstations')->where('mac', '=', $bstationMacNew)->first();
			if($chkExisting) {
				$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());			
				if(!$urcSystem->deleteBStationFromOther($chkExisting)) {
					return Response::json(array('result' => false, 'error' => 'The basestation is already being used'));
				}
			}

			$urcRoom = new URCRoomData($systemId);
			$urcRoom->setBStation($roomOrg->id, $bstationMacOrg, $modelType, $bstationMacNew);

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}


		if($funcType == 'set_timezone') {
			
			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			$rules = array(
				'id' => 'Required',
				'dst' => 'Required',
				'time_type' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}			

			$timezoneId = Input::get('id');
			$dst = Input::get('dst');
			$timeType = Input::get('time_type');

			$selData = DB::table('timezone')->where('id', '=', $timezoneId)->first();
			if(!$selData) {
				return Response::json(array('result' => false, 'error' => 'timezone data was not found'));
			}			

			if($dst !== 0) {
				if($selData->d_bias == 0) {
					return Response::json(array('result' => false, 'error' => 'not valid dst option'));
				}

				$chkTime = '0.0.0 00:00:00';
				if($chkTime === $selData->s_time) {
					return Response::json(array('result' => false, 'error' => 'not valid dst option'));
				}
			} 

			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());
			$urcSystem->setTimezone($systemId, $timezoneId, $dst, $timeType);

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'twoway_types') {

			/*
			$data = array();
			$data[] = (object)array('module' => 'Locks', 'script' => 'zwave_locks.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_locks.dat');
			$data[] = (object)array('module' => 'Lighting', 'script' => 'zwave_lighting.tcl', 'parameter' => 'mac=<<mac>>\r\nlaunch=1\r\nroomid=<<roomid>>', 'data_file' => 'urc_zwave_lighting.dat');
			$data[] = (object)array('module' => 'Scenes', 'script' => 'zwave_scenes.tcl', 'parameter' => 'mac=<<mac>>\r\nlaunch=1\r\nroomid=<<roomid>>', 'data_file' => 'urc_zwave_scenes.dat');
			$data[] = (object)array('module' => 'HVAC', 'script' => 'zwave_tstats.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_tstats.dat');	
			$data[] = (object)array('module' => 'Modes', 'script' => 'zwave_modes.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_modes.dat');	

			DB::table('a_twoway_categories')->where('id', '=', 100)->update(array('twoway_modules' => json_encode($data)));
			
			$data = array();
			$data[] = (object)array('module' => 'Sonos', 'script' => 'sonos_module.tcl', 'parameter' => 'COUNT=20', 'data_file' => 'Sonos.dat');
			DB::table('a_twoway_categories')->insert(array('id' => 102, 'name' => 'Sonos', 'target_type' => 1, 
				'script' => 'sonos.tcl', 'parameter' => '<<mac>>', 'twoway_modules' => json_encode($data)));
			*/
			$edit_version = Config::get('editorenv.prg_version');
			switch($edit_version)//public(0), beta(1), alpha(2), rc(3), factory(4), eng(5)
			{
			case 0:
				$version = 0;
				break;
			case 1:
				$version = 2;
				break;
			case 2:
				$version = 3;
				break;
			case 3:
				$version = 1;
				break;
			case 5:
				$version = 3;
				break;
			default:
				$version = 0;
				break;
			}

			if(Input::has('version')) {
				$version = Input::get('version');
			}

			//$models = DB::table('a_db2_models')->where('major', '=', 1)->
			//	where('version', '<=', $version)->select('id', 'name', 'target_type', 'variables')->orderBy('name', 'asc')->get();

			$models = DB::table('a_db2_models')->join('a_db2_brands', function($join)
			{
				$join->on('a_db2_models.brand_id', '=', 'a_db2_brands.id');
			})->where('a_db2_models.version', '<=', $version)->select('a_db2_models.id', 'a_db2_models.name', 'a_db2_models.target_type', 'a_db2_models.cmds', 'a_db2_models.variables', 'a_db2_brands.name AS brand_name', 'a_db2_brands.category_id AS category_id')->orderBy('a_db2_models.name', 'asc')->get();
			

			foreach($models as $model) {
				if(strlen($model->cmds) > 0)
				{
					$model->cmds = json_decode($model->cmds);
				}
				else {
					unset($model->cmds);
				}
				$model->variables = json_decode($model->variables);				
			}
			return Response::json(array('result' => true, 'data' => $models));

			//$types = DB::table('a_twoway_categories')->select('id', 'name', 'target_type')->get();
			//return Response::json(array('result' => true, 'data' => $types));
		}

		if($funcType == 'twoway_categories') {

			$categories = DB::table('a_db2_categories')->orderBy('name', 'asc')->get();
			return Response::json(array('result' => true, 'data' => $categories));
		}

		if($funcType == 'twoway_brands') {
			
			$rules = array(
				'categoryId' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}			

			$categoryId = Input::get('categoryId');

			$brands = DB::table('a_db2_brands')->where('category_id', '=', $categoryId)->select('id', 'name')->orderBy('name', 'asc')->get();
			return Response::json(array('result' => true, 'data' => $brands));
		}

		if($funcType == 'twoway_models') {

			$rules = array(
				'brandId' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$edit_version = Config::get('editorenv.prg_version');
			switch($edit_version)//public(0), beta(1), alpha(2), rc(3), factory(4), eng(5)
			{
			case 0:
				$version = 0;
				break;
			case 1:
				$version = 2;
				break;
			case 2:
				$version = 3;
				break;
			case 3:
				$version = 1;
				break;
			case 5:
				$version = 3;
				break;
			default:
				$version = 0;
				break;
			}
			
			if(Input::has('version')) {
				$version = Input::get('version');
			}

			/*
			$data = array();
			$data[] = (object)array('module' => 'Locks', 'script' => 'zwave_locks.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_locks.dat');
			$data[] = (object)array('module' => 'Lighting', 'script' => 'zwave_lighting.tcl', 'parameter' => 'mac=<<mac>>\r\nlaunch=1\r\nroomid=<<roomid>>', 'data_file' => 'urc_zwave_lighting.dat');
			$data[] = (object)array('module' => 'Scenes', 'script' => 'zwave_scenes.tcl', 'parameter' => 'mac=<<mac>>\r\nlaunch=1\r\nroomid=<<roomid>>', 'data_file' => 'urc_zwave_scenes.dat');
			$data[] = (object)array('module' => 'HVAC', 'script' => 'zwave_tstats.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_tstats.dat');	
			$data[] = (object)array('module' => 'Modes', 'script' => 'zwave_modes.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_modes.dat');	

			DB::table('a_twoway_categories')->where('id', '=', 100)->update(array('twoway_modules' => json_encode($data)));
			
			$data = array();
			$data[] = (object)array('module' => 'Sonos', 'script' => 'sonos_module.tcl', 'parameter' => 'COUNT=20', 'data_file' => 'Sonos.dat');
			DB::table('a_twoway_categories')->insert(array('id' => 102, 'name' => 'Sonos', 'target_type' => 1, 
				'script' => 'sonos.tcl', 'parameter' => '<<mac>>', 'twoway_modules' => json_encode($data)));
			*/

			$brandId = Input::get('brandId');

			$models = DB::table('a_db2_models')->where('brand_id', '=', $brandId)->where('version', '<=', $version)->select('id', 'name', 'target_type', 'cmds', 'variables')->orderBy('name', 'asc')->get();
			foreach($models as $model) {
				if(strlen($model->cmds) > 0) {
					$model->cmds = json_decode($model->cmds);
				}
				else {
					unset($model->cmds);
				}
				$model->variables = json_decode($model->variables);				
			}
			return Response::json(array('result' => true, 'data' => $models));
		}

		if($funcType == 'get_db_twoway_model') {

			$rules = array(
				'categoryId' => 'Required',
				'category' => 'Required',
				'brandId' => 'Required',
				'brand' => 'Required',
				'modelId' => 'Required',
				'model' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$categoryId = Input::get('categoryId');
			$category = Input::get('category');
			$brandId = Input::get('brandId');
			$brand = Input::get('brand');
			$modelId = Input::get('modelId');
			$model = Input::get('model');

			$data = "";
			$urcDBMgr = new URCTwowayDBMgr($this->username, $this->usr_level);
			
			if(!$urcDBMgr->getTwowayModelData((int)$categoryId, $category, (int)$brandId, $brand, (int)$modelId, $model, $data)) {
				return Response::json(array('result' => false, 'error' => $urcDBMgr->getErrMsg()));
			}

			/*
			$data = array();
			$data[] = (object)array('module' => 'Locks', 'script' => 'zwave_locks.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_locks.dat');
			$data[] = (object)array('module' => 'Lighting', 'script' => 'zwave_lighting.tcl', 'parameter' => 'mac=<<mac>>\r\nlaunch=1\r\nroomid=<<roomid>>', 'data_file' => 'urc_zwave_lighting.dat');
			$data[] = (object)array('module' => 'Scenes', 'script' => 'zwave_scenes.tcl', 'parameter' => 'mac=<<mac>>\r\nlaunch=1\r\nroomid=<<roomid>>', 'data_file' => 'urc_zwave_scenes.dat');
			$data[] = (object)array('module' => 'HVAC', 'script' => 'zwave_tstats.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_tstats.dat');	
			$data[] = (object)array('module' => 'Modes', 'script' => 'zwave_modes.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_modes.dat');	

			DB::table('a_twoway_categories')->where('id', '=', 100)->update(array('twoway_modules' => json_encode($data)));
			
			$data = array();
			$data[] = (object)array('module' => 'Sonos', 'script' => 'sonos_module.tcl', 'parameter' => 'COUNT=20', 'data_file' => 'Sonos.dat');
			DB::table('a_twoway_categories')->insert(array('id' => 102, 'name' => 'Sonos', 'target_type' => 1, 
				'script' => 'sonos.tcl', 'parameter' => '<<mac>>', 'twoway_modules' => json_encode($data)));
			*/

			return Response::json(array('result' => true, 'data' => $data));
		}

		if($funcType == 'add_db_twoway_model') {

			$rules = array(
				'categoryId' => 'Required',
				'category' => 'Required',
				'brandId' => 'Required',
				'brand' => 'Required',
				'modelId' => 'Required',
				'model' => 'Required',
				'data' => 'Required',
				'version' => 'Required',
				'major' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$categoryId = Input::get('categoryId');
			$category = Input::get('category');
			$brandId = Input::get('brandId');
			$brand = Input::get('brand');
			$modelId = Input::get('modelId');
			$model = Input::get('model');
			$data = Input::get('data');
			$version = Input::get('version');
			$major = Input::get('major');

			$urcDBMgr = new URCTwowayDBMgr($this->username, $this->usr_level);
			if(!$urcDBMgr->addTwowayModelToDB((int)$categoryId, $category, (int)$brandId, $brand, (int)$modelId, $model, $data, (int)$version, (int)$major)) {
				return Response::json(array('result' => false, 'error' => $urcDBMgr->getErrMsg()));
			}

			/*
			$data = array();
			$data[] = (object)array('module' => 'Locks', 'script' => 'zwave_locks.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_locks.dat');
			$data[] = (object)array('module' => 'Lighting', 'script' => 'zwave_lighting.tcl', 'parameter' => 'mac=<<mac>>\r\nlaunch=1\r\nroomid=<<roomid>>', 'data_file' => 'urc_zwave_lighting.dat');
			$data[] = (object)array('module' => 'Scenes', 'script' => 'zwave_scenes.tcl', 'parameter' => 'mac=<<mac>>\r\nlaunch=1\r\nroomid=<<roomid>>', 'data_file' => 'urc_zwave_scenes.dat');
			$data[] = (object)array('module' => 'HVAC', 'script' => 'zwave_tstats.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_tstats.dat');	
			$data[] = (object)array('module' => 'Modes', 'script' => 'zwave_modes.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_modes.dat');	

			DB::table('a_twoway_categories')->where('id', '=', 100)->update(array('twoway_modules' => json_encode($data)));
			
			$data = array();
			$data[] = (object)array('module' => 'Sonos', 'script' => 'sonos_module.tcl', 'parameter' => 'COUNT=20', 'data_file' => 'Sonos.dat');
			DB::table('a_twoway_categories')->insert(array('id' => 102, 'name' => 'Sonos', 'target_type' => 1, 
				'script' => 'sonos.tcl', 'parameter' => '<<mac>>', 'twoway_modules' => json_encode($data)));
			*/

			return Response::json(array('result' => true));
		}

		if($funcType == 'set_db_twoway_model') {

			$rules = array(
				'categoryId' => 'Required',
				'category' => 'Required',
				'brandId' => 'Required',
				'brand' => 'Required',
				'modelId' => 'Required',
				'model' => 'Required',
				'data' => 'Required',
				'version' => 'Required', 
				'major' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$categoryId = Input::get('categoryId');
			$category = Input::get('category');
			$brandId = Input::get('brandId');
			$brand = Input::get('brand');
			$modelId = Input::get('modelId');
			$model = Input::get('model');
			$data = Input::get('data');
			$version = Input::get('version');
			$major = Input::get('major');

			$urcDBMgr = new URCTwowayDBMgr($this->username, $this->usr_level);
			if(!$urcDBMgr->setTwowayModelToDB((int)$categoryId, $category, (int)$brandId, $brand, (int)$modelId, $model, $data, (int)$version, (int)$major)) {
				return Response::json(array('result' => false, 'error' => $urcDBMgr->getErrMsg()));
			}

			/*
			$data = array();
			$data[] = (object)array('module' => 'Locks', 'script' => 'zwave_locks.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_locks.dat');
			$data[] = (object)array('module' => 'Lighting', 'script' => 'zwave_lighting.tcl', 'parameter' => 'mac=<<mac>>\r\nlaunch=1\r\nroomid=<<roomid>>', 'data_file' => 'urc_zwave_lighting.dat');
			$data[] = (object)array('module' => 'Scenes', 'script' => 'zwave_scenes.tcl', 'parameter' => 'mac=<<mac>>\r\nlaunch=1\r\nroomid=<<roomid>>', 'data_file' => 'urc_zwave_scenes.dat');
			$data[] = (object)array('module' => 'HVAC', 'script' => 'zwave_tstats.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_tstats.dat');	
			$data[] = (object)array('module' => 'Modes', 'script' => 'zwave_modes.tcl', 'parameter' => 'mac=<<mac>>', 'data_file' => 'urc_zwave_modes.dat');	

			DB::table('a_twoway_categories')->where('id', '=', 100)->update(array('twoway_modules' => json_encode($data)));
			
			$data = array();
			$data[] = (object)array('module' => 'Sonos', 'script' => 'sonos_module.tcl', 'parameter' => 'COUNT=20', 'data_file' => 'Sonos.dat');
			DB::table('a_twoway_categories')->insert(array('id' => 102, 'name' => 'Sonos', 'target_type' => 1, 
				'script' => 'sonos.tcl', 'parameter' => '<<mac>>', 'twoway_modules' => json_encode($data)));
			*/

			return Response::json(array('result' => true));
		}

		if($funcType == 'set_home_btn') {

			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			$rules = array(
				'option' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}			

			if(URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id())*/, $systemId) === false) {
				return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
			}

			$option = Input::get('option');
			
			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());
			$urcSystem->setHomeBtnOption($systemId, $option);

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'get_vars') {
			
			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			if(URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id())*/, $systemId) === false) {
				return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
			}

			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());
			$vars = $urcSystem->getVariables($systemId);

			return Response::json(array('result' => true, 'data' => $vars));
		}

		if($funcType == 'add_var') {
			
			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			$rules = array(
				'type' => 'Required',
				'name' => 'Required',
				'value' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			if(URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id())*/, $systemId) === false) {
				return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
			}

			$type = Input::get('type');
			$name = Input::get('name');
			$value = Input::get('value');

			$errMsg = '';
			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());
			$result = $urcSystem->addVariable($systemId, $name, $type, $value, $errMsg);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => $errMsg));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($funcType == 'del_var') {
			
			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			$rules = array(
				'id' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$varId = Input::get('id');

			if(URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id())*/, $systemId) === false) {
				return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
			}

			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());
			$urcSystem->delVariables($systemId, $varId);

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'edit_var') {
			
			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			$rules = array(
				'id' => 'Required',
				'type' => 'Required',
				'name' => 'Required',
				'value' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			if(URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id())*/, $systemId) === false) {
				return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
			}

			$varId = Input::get('id');
			$type = Input::get('type');
			$name = Input::get('name');
			$value = Input::get('value');

			$errMsg = '';
			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());
			$result = $urcSystem->setVariable($systemId, $varId, $name, $type, $value, $errMsg);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => $errMsg));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($funcType == 'set_dealer') {

			$rules = array(
				'username' => 'Required',
				'password' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$username = Input::get('username');
			$password = Input::get('password');

			$dealerId = '';
			$dealerGrpId = '';
			$dealerGrpName = '';
			$isAdmin = 0;
			$rmsDealer = new RMSDealer();
			if(!$rmsDealer->login($username, $password, $dealerId, $dealerGrpId, $dealerGrpName, $isAdmin)) {
				return Response::json(array('result' => false, 'error' => 'An invalid username or password has been entered for a Dealer/Employee Account. Please try again.'));
			}

			if(!$rmsDealer->dealerValidate($dealerId, $password, $dealerGrpId, $dealerGrpName, $isAdmin)) {
				return Response::json(array('result' => false, 'error' => 'Validation Error.'));	
			}

			$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());
			$errMsg = '';
			$result = $urcSystem->setDealer($systemId, $dealerId, $dealerGrpId, $errMsg);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => $errMsg));
			}

			return Response::json(array('result' => true, 'company' => $dealerGrpName));
		}

		if($funcType == 'get_dealer') {

			if($systemId < 0) {
				return Response::json(array('result' => false, 'error' => 'system Id is wrong'));
			}

			$foundSystem = URCSystemData::isValidSystem($this->usr_id, $systemId);
			if($foundSystem === false) {
				return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
			}

			$rmsDealer = new RMSDealer();
			$errMsg = '';
			$dealerData = $rmsDealer->getDealerData($foundSystem->dealer_id, $errMsg);
			if($dealerData === false) {
				return Response::json(array('result' => false, 'error' => "fail to get the dealer information"));
			}

			return Response::json(array('result' => true, 'data' => $dealerData));
		}

		return Response::json(array('result' => false, 'error' => 'unknown command'));
	}


	public function doRoomControl($funcType, $systemId, $roomId = -1) {

		if(!$this->chkJWTTokenWithLevel(URCValues::LOGIN_USER, $errMsg, $errNo)) {
			return Response::make($errMsg, $errNo);
		}

		if(URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id())*/, $systemId) === false) {
			return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
		}

		if($funcType == 'create') {
			
			$rules = array(
				'name' => 'Required',
				'type' => 'Required',
				'bstationName' => 'Required',
				'bstationMac' => 'Required|min:12');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}		

			$roomName = Input::get('name');
			$bstationType = Input::get('type');
			$bstationName = Input::get('bstationName');
			$bstationMac = Input::get('bstationMac');
			
			$chkExisting = DB::table('a_bstations')->where('mac', '=', $bstationMac)->first();
			if($chkExisting) {
				$roomChk = DB::table('a_rooms')->where('id', '=', $chkExisting->room_id)->first();
				if(!$roomChk || $roomChk->system_id != $systemId) {
					$urcSystem = new URCSystemData($this->usr_id);
					if($urcSystem->deleteBStationFromOther($chkExisting) == false) {
						return Response::json(array('result' => false, 'error' => 'The basestation is already being used'));
					}
				}		
				else {
					return Response::json(array('result' => false, 'error' => 'room creation fail'));
				}
			}

			$urcRoom = new URCRoomData($systemId);
			if($urcRoom->isOverRoomCount()) {
				return Response::json(array('result' => false, 'error' => 'A maximum of eight rooms may be controllered in a home.'));
			}
			
			$roomId = $urcRoom->createRoom($bstationType, $bstationName, $bstationMac, $roomName, 'a');
			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room creation fail'));
			}

			URCSystemData::updateEditTime($systemId, '');
			
			return Response::json(array('result' => true, 'roomId' => $roomId));
		}

		if($funcType == 'get') {

			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$urcRoom = new URCRoomData($systemId);
			$room = $urcRoom->getRoom($roomId);

			//ErrorDebug::write('room');
			//ErrorDebug::write(json_encode($room));

			if($room === false) {
				return Response::json(array('result' => false, 'error' => 'not exist' ));
			}

			return Response::json(array('result' => true, 'data' => $room));
		}

		if($funcType == 'delete') {

			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			//check existing
			$chkExisting = DB::table('a_bstations')->where('room_id', '=', $roomId)->get();
			foreach($chkExisting as $roomChk) {

				if($roomChk->master == 1) {
					return Response::json(array('result' => false, 'error' => "can't delete - the master basestation exists"));
				}
			}

			$urcRoom = new URCRoomData($systemId);
			$result = $urcRoom->destroyRoom($roomId);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to delete room' ));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));

		}

		if($funcType == 'edit') {
			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$rules = array(
				'name' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$roomName = Input::get('name');

			$urcRoom = new URCRoomData($systemId);
			$result = $urcRoom->editRoom($roomId, $roomName);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to edit room' ));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'set_remote') {

			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$rules = array(
				'mac' => 'Required',
				'type' => 'Required',
				'name' => 'Required',
				'searchKey' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$mac = Input::get('mac');
			$type = Input::get('type');
			$name = Input::get('name');			
			$key = Input::get('searchKey');

			if(!URCValues::isRemoteControl($type)) {
				return Response::json(array('result' => false, 'error' => 'The type is wrong-'.$type));
			}

			if(!$this->checkSearchKey($key, $this->usr_id, $mac)) {
				return Response::json(array('result' => false, 'error' => 'Please refresh the list'));
			}
			
			//check existing
			if(strlen($mac) > 0) {

				$chkExisting = DB::table('a_remotes')->where('mac', '=', $mac)->get();
				$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());												
				foreach($chkExisting as $roomChk) {

					//ErrorDebug::write(json_encode($roomChk));
					//ErrorDebug::write('roomId:'.$roomId.'systemId:'.$systemId);

					if($roomChk->room_id == $roomId && $roomChk->system_id == $systemId) {  break; }

					if(!$urcSystem->deleteRemoteFromOther($roomChk)) {
						return Response::json(array('result' => false, 'error' => 'The remote control is already being used'));
					}
				}
			}

			$urcRoom = new URCRoomData($systemId);
			$result = $urcRoom->setRemote($roomId, $mac, $type, $name);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to store' ));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}
		if($funcType == 'add_remote') {

			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$rules = array(
				'mac' => 'Required',
				'type' => 'Required',
				'name' => 'Required',
				'searchKey' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$mac = Input::get('mac');
			$type = Input::get('type');
			$name = Input::get('name');	
			$key = Input::get('searchKey');

			if(!URCValues::isRemoteControl($type)) {
				return Response::json(array('result' => false, 'error' => 'The type is wrong-'.$type));
			}
			
			if(!$this->checkSearchKey($key, $this->usr_id, $mac)) {
				return Response::json(array('result' => false, 'error' => 'Please refresh the list'));
			}
			
			//check existing
			if(strlen($mac) > 0) {

				$chkExisting = DB::table('a_remotes')->where('mac', '=', $mac)->get();
				$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());												
				foreach($chkExisting as $roomChk) {

					//if($roomChk->room_id === $roomId) {  break; }
					if(!$urcSystem->deleteRemoteFromOther($roomChk)) {
						return Response::json(array('result' => false, 'error' => 'The remote control is already being used'));
					}
				}
			}

			$urcRoom = new URCRoomData($systemId);
			$result = $urcRoom->addRemote($roomId, $mac, $type, $name);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to store' ));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}
		if($funcType == 'del_remote') {

			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$rules = array(
				'mac' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$mac = Input::get('mac');

			//check existing
			$chkExisting = DB::table('a_remotes')->where('mac', '=', $mac)->get();
			foreach($chkExisting as $roomChk) {

				if($roomChk->room_id != $roomId || $roomChk->system_id != $systemId) {
					return Response::json(array('result' => false, 'error' => 'not valid remote control'));
				}
			}

			$urcRoom = new URCRoomData($systemId);
			$result = $urcRoom->delRemote($roomId, $mac);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to delete' ));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'add_bstation') {

			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$rules = array(
				'mac' => 'Required',
				'type' => 'Required',
				'name' => 'Required',
				'lightLevel' => 'Required',
				'searchKey' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$mac = Input::get('mac');
			$type = Input::get('type');
			$bstationName = Input::get('name');
			$lightLevel = Input::get('lightLevel');
			$key = Input::get('searchKey');

			if(!URCValues::isBasestation($type)) {
				return Response::json(array('result' => false, 'error' => 'The type is wrong-'.$type));
			}

			if(!$this->checkSearchKey($key, $this->usr_id, $mac)) {
				return Response::json(array('result' => false, 'error' => 'Please refresh the list'));
			}
			
			//check existing
			if(strlen($mac) > 0) {

				$chkExisting = DB::table('a_bstations')->where('mac', '=', $mac)->get();
				$urcSystem = new URCSystemData($this->usr_id);//JWT->Auth::id());								
				foreach($chkExisting as $roomChk) {

					//if($roomChk->room_id === $roomId) {  break; }
					if(!$urcSystem->deleteBStationFromOther($roomChk)) {
						return Response::json(array('result' => false, 'error' => 'The basestation is already being used'));
					}
				}
			}

			$urcRoom = new URCRoomData($systemId);
			$result = $urcRoom->addBStation($roomId, $mac, $type, $bstationName, $lightLevel);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to store' ));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}
		if($funcType == 'edit_bstation') {

			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$rules = array(
				'mac' => 'Required',
				'type' => 'Required',
				'name' => 'Required',
				'lightLevel' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$mac = Input::get('mac');
			$type = Input::get('type');
			$bstationName = Input::get('name');
			$lightLevel = Input::get('lightLevel');

			//check existing
			if(strlen($mac) > 0) {

				$chkExisting = DB::table('a_bstations')->where('mac', '=', $mac)->get();
				foreach($chkExisting as $roomChk) {

					if($roomChk->room_id != $roomId || $roomChk->system_id != $systemId) { 
						return Response::json(array('result' => false, 'error' => 'not valid basestation'));
					}

					if($roomChk->type !== $type) {
						return Response::json(array('result' => false, 'error' => 'The basestation type is different'));
					}
				}
			}

			$urcRoom = new URCRoomData($systemId);
			$result = $urcRoom->editBStation($roomId, $mac, $type, $bstationName, $lightLevel);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to store' ));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}
		if($funcType == 'del_bstation') {

			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$rules = array(
				'mac' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$mac = Input::get('mac');

			//check existing
			$chkExisting = DB::table('a_bstations')->where('mac', '=', $mac)->get();
			foreach($chkExisting as $roomChk) {

				if($roomChk->room_id != $roomId || $roomChk->system_id != $systemId) {
					return Response::json(array('result' => false, 'error' => 'not valid basestation'));
				}

				if($roomChk->master == 1) {
					return Response::json(array('result' => false, 'error' => "master basestation can't be deleted"));
				}
			}

			$urcRoom = new URCRoomData($systemId);
			$result = $urcRoom->delBStation($roomId, $mac);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to delete' ));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}
		if($funcType == 'list_bstation') {

			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$chkExisting = DB::table('a_bstations')->where('room_id', '=', $roomId)->get();
			foreach($chkExisting as $roomChk) {

				unset($chkExisting->room_id);
			}

			return Response::json(array('result' => true, 'data' => $chkExisting));
		}

		if($funcType == 'get_events') {
			
			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$scheObj = new URCScheEventData($systemId, $roomId);
			$events = $scheObj->getEvents();

			return Response::json(array('result' => true, 'data' => $events));
		}

		if($funcType == 'store_events') {

			if(!Input::has('data')) {
				
				$rules = array(
					'data' => 'Required');

				$v = Validator::make(Input::all(), $rules);
				if($v->fails()) {
					return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
				}	
			}

			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$data = Input::get('data');

			$scheObj = new URCScheEventData($systemId, $roomId);
			if($scheObj->storeEvents($data) === false) {
				return Response::json(array('result' => false, 'error' => 'fail to store'));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'get_event') {

			$rules = array(
				'id' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	
			
			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$id = Input::get('id');

			$scheObj = new URCScheEventData($systemId, $roomId);
			$result = $scheObj->getEvent($id);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to get' ));
			}

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($funcType == 'del_event') {
			
			$rules = array(
				'id' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	
			
			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$id = Input::get('id');

			$scheObj = new URCScheEventData($systemId, $roomId);
			$result = $scheObj->delEvent($id);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to delete' ));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'create_event') {
			
			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$rules = array(
				'display_text' => 'Required',
				'macro' => 'Required',
				'default_state' => 'Required',
				'option' => 'Required',
				'day_week' => 'Required',
				'time' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$text = Input::get('display_text');
			$imageName = '';
			if(Input::has('image_name')) {
				$imageName = Input::get('image_name');
			}
			$macro = Input::get('macro');
			$defaultState = Input::get('default_state');
			$option = Input::get('option');
			$dayWeek = Input::get('day_week');
			$time = Input::get('time');

			$scheObj = new URCScheEventData($systemId, $roomId);
			$result = $scheObj->createEvent($text, $imageName, $macro, $defaultState, $option, $dayWeek, $time);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to create' ));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'set_event') {
			
			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$rules = array(
				'id' => 'Required',
				'display_text' => 'Required',
				'macro' => 'Required',
				'default_state' => 'Required',
				'option' => 'Required',
				'day_week' => 'Required',
				'time' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$id = Input::get('id');
			$text = Input::get('display_text');
			$imageName = '';
			if(Input::has('image_name')) {
				$imageName = Input::get('image_name');
			}
			$macro = Input::get('macro');
			$defaultState = Input::get('default_state');
			$option = Input::get('option');
			$dayWeek = Input::get('day_week');
			$time = Input::get('time');

			$scheObj = new URCScheEventData($systemId, $roomId);
			$result = $scheObj->setEvent($id, $text, $imageName, $macro, $defaultState, $option, $dayWeek, $time);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to create' ));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'set_event_state') {
			
			if($roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$rules = array(
				'id' => 'Required',
				'default_state' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$id = Input::get('id');
			$defaultState = Input::get('default_state');

			$scheObj = new URCScheEventData($systemId, $roomId);
			$result = $scheObj->setEventStatus($id, $defaultState);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to create' ));
			}

			URCSystemData::updateEditTime($systemId, '');

			return Response::json(array('result' => true));
		}
	}

	public function doExternalDevControl($devType, $funcType, $systemId, $roomId = -1) {

		if(!$this->chkJWTTokenWithLevel(URCValues::LOGIN_USER, $errMsg, $errNo)) {
			return Response::make($errMsg, $errNo);
		}

		if(URCSystemData::isValidSystem($this->usr_id/*//JWT->Auth::id())*/, $systemId) === false) {
			return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
		}

		if($devType == 'amazon') {

			$amazonObj = new URCAmazonData($systemId);
			return $amazonObj->doFunc($funcType, $roomId);
		}

		return Response::json(array('result' => false, 'error' => 'unknown device type' ));
	}

	public function doTwowayDeviceControl($funcType, $roomId, $deviceId = -1) {

		if(!$this->chkJWTTokenWithLevel(URCValues::LOGIN_USER, $errMsg, $errNo)) {
			return Response::make($errMsg, $errNo);
		}

		$foundSystem = '';
		$foundRoom = '';
		if(!URCSystemData::isValidRoom2($this->usr_id/*//JWT->Auth::id())*/, $roomId, $foundSystem, $foundRoom)) {
			return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
		}

		if($funcType == 'create') {

			$rules = array(
				'name' => 'Required',
				'model' => 'Required',
				'targetType' => 'Required',
				'targetAddr' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$name = Input::get('name');
			$model = Input::get('model');
			if(Input::has('modelId')) {
				$modelId = (int)Input::get('modelId');
			}
			else {
				switch($model) {
				case 'Nest' :
					$modelId = 140500;
					break;
				case 'TRF-ZW1' :
					$modelId = 201800;
					break;
				case 'Sonos' :
					$modelId = 191500;
					break;
				case 'SNP-2' :
					$modelId = 22013;
					break;
				default:
					return Response::json(array('result' => false, 'error' => 'wrong model name'));
				}
			}

			$target = new stdClass;
			$target->type = Input::get('targetType');
			$target->addr = Input::get('targetAddr');

			$variables = null;
			if(Input::has('variables')) {
				$variables = Input::get('variables');
			}

			$isVolCmd = 0;
			if(Input::has('vol_cmd')) {
				$isVolCmd = (int)Input::get('vol_cmd');
			}

			$categoryId = 0;
			if(Input::has('categoryId')) {
				$categoryId = Input::get('categoryId');
			}

			if(URCValues::isEntertainmentTwowayDevice($model)) {

				$urcDevice = new URCDeviceData($roomId);

				switch($target->type & 0xffff)
				{
				case URCValues::TWOWAY_TYPE_MAC:
					$target->type = URCValues::DB_TYPE_MAC;
					$target->port = 0;
					break;
				case URCValues::TWOWAY_TYPE_IP:
					$target->type = URCValues::DB_TYPE_IP;
					$target->addr = '';
					$target->port = 0;
					break;
				case URCValues::TWOWAY_TYPE_SERVICE:
					$target->type = URCValues::DB_TYPE_NONE;
					$target->addr = '';
					$target->port = 0;
					break;
				default:
					$target->type = URCValues::DB_TYPE_NONE;
					$target->addr = '';
					$target->port = 0;
					break;
				}

				$deviceId = $urcDevice->createTwowayDevice($this->username, $name, $model, $modelId, $target);
				if($deviceId < 0) {
					return Response::json(array('result' => false, 'error' => 'Unable to add this device to your system.'));//'fail to create device' ));
				}
			}
			else {			

				$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
		
				//ErrorDebug::write('dbType:'.$dbType);		
				$errorInfo = '';
				$deviceId = $urcDevice->createDevice($this->username, $name, $model, $modelId, $categoryId, $target, $isVolCmd, $variables, $errorInfo);

				if($deviceId < 0) {
					return Response::json(array('result' => false, 'error' => $errorInfo));//'fail to create device' ));
				}

				if($model == 'TRF-ZW1') {
					
					$device = $urcDevice->getDevice($deviceId);
					
					if($this->chkUser() && $device !== false) {
					
						$sip_user = DB::table('sip_user')->where('controller_id', '=', $foundSystem->controller_id)->first();
						if($sip_user) {
						
							$bstationMgr = new BStationManager(URCValues::WAIT_SEC);	
							$passwordSip = Crypt::decrypt($sip_user->password);
							$resultData = $bstationMgr->customUpdateTwowayData($sip_user->sip_id, $passwordSip, $foundSystem->controller_id, $device->model, $device->target_addr);

							if($resultData !== false) {
								$updatedRow = 0;
								$urcDevice->updateDevice($deviceId, $resultData, $updatedRow);
							}
						}
					}				
				}
							
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'delete') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
			$result = $urcDevice->destroyDevice($deviceId);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to delete device' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'edit') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$rules = array(
				'name' => 'Required',
				'targetType' => 'Required',
				'targetAddr' => 'Required' );

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}


			$deviceName = Input::get('name');

			$target = new stdClass;
			$target->type = Input::get('targetType');
			$target->addr = Input::get('targetAddr');

			$variables = null;
			if(Input::has('variables')) {
				$variables = Input::get('variables');
			}
			
			$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
			$result = $urcDevice->editDevice($deviceId, $deviceName, $target, $variables);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to edit device' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'update') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
			$device = $urcDevice->getDevice($deviceId);
			if($device === false) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			if(!$this->chkUser()) {
				return Response::json(array('result' => false, 'error' => 'Invalid user'));
			}

			$sip_user = DB::table('sip_user')->where('controller_id', '=', $foundSystem->controller_id)->first();
			if(!$sip_user) {
				return Response::json(array('result' => false, 'error' => 'Not valid communication account'));
			}
					
			$bstationMgr = new BStationManager(URCValues::WAIT_SEC);	
			$passwordSip = Crypt::decrypt($sip_user->password);			
			$resultData = $bstationMgr->customUpdateTwowayData($sip_user->sip_id, $passwordSip, $foundSystem->controller_id, $device->model, $device->target_addr);
			if($resultData === false) {
				return Response::json(array('result' => false, 'error' => $bstationMgr->getErrResult()));
			}

			$updatedRow = 0;
			$result = $urcDevice->updateDevice($deviceId, $resultData, $updatedRow);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to update device' ));
			}

			if($updatedRow) {
				URCSystemData::updateEditTime($foundSystem->id, '');
			}

			return Response::json(array('result' => true, 'data' => $resultData));
		}

		if($funcType == 'get_punch') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
			$result = $urcDevice->getPunchDevice($deviceId);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to punch' ));
			}

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($funcType == 'punch') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$deviceFrom = Input::get('punchFrom');

			$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
			$result = $urcDevice->setPunchDevice($deviceFrom, $deviceId);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to punch' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'punch_multi') {

			$rules = array(
				'punchFrom' => 'Required',
				'punchTo' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$deviceFrom = Input::get('punchFrom');
			$devicesTo = Input::get('punchTo');

			$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
			$result = $urcDevice->setPunchDevices($deviceFrom, $devicesTo);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to punch' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'get_extra_info') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
			$result = $urcDevice->getExtraInfo($deviceId);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to get' ));
			}

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($funcType == 'set_extra_info') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$rules = array(
				'data' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$data = Input::get('data');

			//ErrorDebug::write('roomID'.$roomId);		
			//ErrorDebug::write('deviceID'.$deviceId);		
			//ErrorDebug::write(json_encode($data));		
			//ErrorDebug::write($data);		
			
			$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
			$result = $urcDevice->setExtraInfo($deviceId, $data);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to set' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'get_buttons') {

			$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
			$result = $urcDevice->getMacroButtonsFromDevice();
			if(!$result) {
				return Response::json(array('result' => false, 'error' => 'not exist' ));
			}

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($funcType == 'get_button_macro_with_device') {

			$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
			$result = $urcDevice->getMacroFromDevice($deviceId);
			if(!$result) {
				return Response::json(array('result' => false, 'error' => 'no match device' ));
			}

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($funcType == 'delete_button_macro_with_device') {

			$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
			$result = $urcDevice->delMacroFromDevice($deviceId);

			if(!$result) {
				return Response::json(array('result' => false, 'error' => 'no match device' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'store_button_macro_with_device') {

			$autoWait = Input::get('auto_wait');
			$activity = Input::get('activity');
			$editType = Input::get('edit_type');
			$popup = Input::get('popup');
			$macro = Input::get('macro');

			$urcDevice = new URCTwowayDeviceData($foundSystem, $roomId);
			$result = $urcDevice->storeMacroFromDevice($deviceId, $autoWait, $editType, $popup, $activity, $macro);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to store activity' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}
	}

	public function doDeviceControl($funcType, $roomId, $deviceId = -1) {

		if(!$this->chkJWTTokenWithLevel(URCValues::LOGIN_USER, $errMsg, $errNo)) {
			return Response::make($errMsg, $errNo);
		}

		if(!URCSystemData::isValidRoom2($this->usr_id/*//JWT->Auth::id())*/, $roomId, $foundSystem, $foundRoom)) {
			return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
		}

		if($funcType == 'create') {

			$rules = array(
				'name' => 'Required',
				'type' => 'Required',
				'brand' => 'Required',
				'model' => 'Required',
				'dbType' => 'Required',
				'modelId' => 'Required|Integer',
				'targetType' => 'Required',
				'targetAddr' => 'Required',
				'targetPort' => 'Required|Integer',
				'favEnable' => 'Required',
				'favDelay' => 'Required',
				'favEnter' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$urcDevice = new URCDeviceData($roomId);

			$name = Input::get('name');
			$category = Input::get('type');
			$brand = Input::get('brand');
			$model = Input::get('model');
			$dbType = Input::get('dbType');
			$modelId = Input::get('modelId');
			$target = new stdClass;
			$target->type = Input::get('targetType');
			$target->addr = Input::get('targetAddr');
			$target->port = Input::get('targetPort');
			$favOption =  new stdClass;
			$favOption->enable = Input::get('favEnable');
			if($favOption->enable) {
				$favOption->delay =  Input::get('favDelay');
			}
			else {
				$favOption->delay = 400;
			}
			$favOption->enter = Input::get('favEnter');

			//ErrorDebug::write('dbType:'.$dbType);
		
			$deviceId = $urcDevice->createDevice($this->username, $name, $category, $brand, $model, $dbType, $modelId, $target, $favOption);
			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'Unable to add this device to your system.'));//'fail to create device' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'create_custom') {

			$urcDevice = new URCDeviceData($roomId);
			$deviceData = Input::get('data');
			$deviceId = $urcDevice->createCustomDevice($deviceData);
			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'Unable to add this device to your system.'));//'fail to create device' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');
			
			return Response::json(array('result' => true));
		}

		if($funcType == 'delete') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$urcDevice = new URCDeviceData($roomId);
			$result = $urcDevice->destroyDevice($deviceId);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to delete device' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));

		}

		if($funcType == 'edit') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$rules = array(
				'name' => 'Required',
				'targetType' => 'Required',
				'targetPort' => 'Required|Integer',
				'repeatMin' => 'Required|Integer',
				'repeatMacro' => 'Required|Integer');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}


			$deviceName = Input::get('name');

			$target = new stdClass;
			$target->type = Input::get('targetType');
			$target->addr = Input::get('targetAddr');
			$target->port = Input::get('targetPort');

			$attr = new stdClass;
			$attr->repeat_min = Input::get('repeatMin');
			$attr->repeat_macro = Input::get('repeatMacro');
			if($target->type == URCValues::DB_TYPE_IP ||
				$target->type == URCValues::DB_TYPE_UDP) {
				$attr->ramp_start = Input::get('rampStart');
				$attr->ramp_speed = Input::get('rampSpeed');
				$attr->auto_cr = Input::get('autoCr');	
				/*
				$attr->con_time = 0;
				if(Input::has('conTime')) {
					$attr->con_time = Input::get('conTime');
				}
				*/
			}

			$urcDevice = new URCDeviceData($roomId);
			$result = $urcDevice->editDevice($deviceId, $deviceName, $target, $attr);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to edit device' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'favorite') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$favOption = Input::get('favOption');
			$favDelay = Input::get('favDelay');
			$favEnter = Input::get('favEnter');

			$urcDevice = new URCDeviceData($roomId);
			$result = $urcDevice->setFavoriteDevice($deviceId, $favOption, URCValues::FAV_DELAY_CHANGE, $favDelay, $favEnter);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to set the favorite option' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'get_punch') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$urcDevice = new URCDeviceData($roomId);
			$result = $urcDevice->getPunchDevice($deviceId);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to punch' ));
			}

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($funcType == 'punch') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$deviceFrom = Input::get('punchFrom');

			$urcDevice = new URCDeviceData($roomId);
			$result = $urcDevice->setPunchDevice($deviceFrom, $deviceId);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to punch' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'punch_multi') {

			$rules = array(
				'punchFrom' => 'Required',
				'punchTo' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$deviceFrom = Input::get('punchFrom');
			$devicesTo = Input::get('punchTo');

			$urcDevice = new URCDeviceData($roomId);
			$result = $urcDevice->setPunchDevices($deviceFrom, $devicesTo);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to punch' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'get_con_dev') {

			$urcDevice = new URCDeviceData($roomId);
			$data = $urcDevice->getConDevData($deviceId);
			foreach($data as $func) {
				unset($func->device_id);
				unset($func->room_id);
			}

			//$metaData = $urcDevice->getMetaData($deviceId);

			if(!$data || count($data) <= 0) {// || $metaData === false) {
				return Response::json(array('result' => false, 'error' => 'no connected device data' ));
			}

			/*
			$data = new stdClass;
			$data->conData = $conData;
			$data->metaData = new stdClass;
			$data->metaData->meta_pwr_on = $metaData->meta_pwr_on;
			$data->metaData->meta_pwr_off = $metaData->meta_pwr_off;
			$data->metaData->meta_pwr_toggle = $metaData->meta_pwr_toggle;		
			$data->metaData->meta_in_toggle = $metaData->meta_in_toggle;
			*/

			//ErrorDebug::write(json_encode($data));
			return Response::json(array('result' => true, 'data' => $data));
		}

		if($funcType == 'get_main') {

			$urcDevice = new URCDeviceData($roomId);

			$mainDeviceId = $urcDevice->getMainDeviceId();
			$device = $urcDevice->getDevice($mainDeviceId, true);

			//ErrorDebug::write('main');
			//ErrorDebug::write(json_encode($device));

			if($device === false) {
				return Response::json(array('result' => false, 'error' => 'not exist'.$roomId.' '.$mainDeviceId ));
			}

			return Response::json(array('result' => true, 'data' => $device));
		}

		if($funcType == 'store_main') {

			$deviceData = Input::get('data');
			$urcDevice = new URCDeviceData($roomId);

			$mainDeviceId = $urcDevice->getMainDeviceId();
			$result = $urcDevice->storeDevice($mainDeviceId, $deviceData, true);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => "couldn't save" ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'get') {

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$urcDevice = new URCDeviceData($roomId);

			$device = $urcDevice->getDevice($deviceId, false);

			//ErrorDebug::write('device');
			//ErrorDebug::write(json_encode($device));

			if($device === false) {
				return Response::json(array('result' => false, 'error' => 'not exist'.$roomId.' '.$deviceId ));
			}

			return Response::json(array('result' => true, 'data' => $device));
		}

		if($funcType == 'store') {
			
			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'device Id is wrong'));
			}

			$device = DB::table('a_devices')->where('room_id', '=', $roomId)->
	 			where('id', '=', $deviceId)->first();
	 		if($device && $device->dev_type != 0) {
	 			return Response::json(array('result' => false, 'error' => "couldn't save" ));
	 		}

			$deviceData = Input::get('data');
			$urcDevice = new URCDeviceData($roomId);

			$result = $urcDevice->storeDevice($deviceId, $deviceData, false);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => "couldn't save" ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}
	}


	public function doButtonControl($funcType, $roomId, $deviceId = -1, $buttonId = -1) {

		if(!$this->chkJWTTokenWithLevel(URCValues::LOGIN_USER, $errMsg, $errNo)) {
			return Response::make($errMsg, $errNo);
		}

		if(!URCSystemData::isValidRoom2($this->usr_id/*//JWT->Auth::id())*/, $roomId, $foundSystem, $foundRoom)) {
			return Response::json(array('result' => false, 'error' => 'not valid for this user' ));
		}

		if($funcType == 'create') {
			
			$rules = array(
				'edit_type' => 'Required|Integer');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$text = Input::get('text');
			$autoWait = Input::get('auto_wait');
			$activity = Input::get('activity');
			$editType = Input::get('edit_type');
			$popup = Input::get('popup');
			$macro = Input::get('macro');

			if($editType != URCValues::ETYPE_MACRO) {
				return Response::json(array('result' => false, 'error' => 'command error' ));
			}

			if($deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'no match device' ));
			}

			$urcBtn = new URCBtnData($roomId, $deviceId);
			
			$result = $urcBtn->createBtn($text, $autoWait, $popup, $activity, $macro);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to create button' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($funcType == 'get_button_macro_with_device') {

			$urcDev = new URCDeviceData($roomId);

			$mainDevId = $urcDev->getMainDeviceId();

			if($mainDevId < 0 || $deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'no match device' ));
			}

			$urcBtn = new URCBtnData($roomId, $mainDevId);
			$result = $urcBtn->getMacroFromDevice($deviceId);

			if(!$result) {
				return Response::json(array('result' => false, 'error' => 'no match device' ));
			}

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($funcType == 'delete_button_macro_with_device') {

			$urcDev = new URCDeviceData($roomId);

			$mainDevId = $urcDev->getMainDeviceId();

			if($mainDevId < 0 || $deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'no match device' ));
			}

			$urcBtn = new URCBtnData($roomId, $mainDevId);
			$result = $urcBtn->delMacroFromDevice($deviceId);

			if(!$result) {
				return Response::json(array('result' => false, 'error' => 'no match device' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'store_button_macro_with_device') {

			$autoWait = Input::get('auto_wait');
			$activity = Input::get('activity');
			$editType = Input::get('edit_type');
			$popup = Input::get('popup');
			$macro = Input::get('macro');

			$urcDev = new URCDeviceData($roomId);
			$mainDevId = $urcDev->getMainDeviceId();

			if($mainDevId < 0 || $deviceId < 0) {
				return Response::json(array('result' => false, 'error' => 'no match device' ));
			}

			$urcBtn = new URCBtnData($roomId, $mainDevId);

			$result = $urcBtn->storeMacroFromDevice($deviceId, $autoWait, $editType, $popup, $activity, $macro);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to store activity' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}

		if($funcType == 'get_button_macro') {

			$urcDev = new URCDeviceData($roomId);

			if($buttonId < 0) {
				return Response::json(array('result' => false, 'error' => 'no match button' ));
			}

			$urcBtn = new URCBtnData($roomId, $deviceId);
			$result = $urcBtn->getMacro($buttonId);

			if(!$result) {
				return Response::json(array('result' => false, 'error' => 'no match button' ));
			}

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($funcType == 'delete_button_macro') {

			$urcDev = new URCDeviceData($roomId);

			if($buttonId < 0) {
				return Response::json(array('result' => false, 'error' => 'no match button' ));
			}

			$urcBtn = new URCBtnData($roomId, $deviceId);
			$result = $urcBtn->delMacro($buttonId);

			switch($result)
			{
			case 0:
				return Response::json(array('result' => false, 'error' => 'no match button' ));
			case 2:
				return Response::json(array('result' => true, 'deleted' => true));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true, 'deleted' => false));			
		}

		if($funcType == 'store_button_macro') {

			$autoWait = Input::get('auto_wait');
			$activity = Input::get('activity');
			$editType = Input::get('edit_type');
			$popup = Input::get('popup');
			$macro = Input::get('macro');

			if($editType != URCValues::ETYPE_MACRO) {
				return Response::json(array('result' => false, 'error' => 'command error' ));
			}

			$urcDev = new URCDeviceData($roomId);
			if($buttonId < 0) {
				return Response::json(array('result' => false, 'error' => 'no match button' ));
			}

			$urcBtn = new URCBtnData($roomId, $deviceId);

			$result = $urcBtn->storeMacro($buttonId, $autoWait, $popup, $activity, $macro);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to store macro' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');
			
			return Response::json(array('result' => true));
		}

		if($funcType == 'get_power_macro') {

			$urcBtn = new URCBtnData($roomId, -1);
			$result = $urcBtn->getPowerMacro();
			if(!$result) {
				return Response::json(array('result' => false, 'error' => 'no match power' ));
			}

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($funcType == 'delete_power_macro') {

			$urcBtn = new URCBtnData($roomId, -1);
			$result = $urcBtn->delPowerMacro();
			if(!$result) {
				return Response::json(array('result' => false, 'error' => 'no match power' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));			
		}

		if($funcType == 'store_power_macro') {

			$autoWait = Input::get('auto_wait');
			$activity = Input::get('activity');
			$editType = Input::get('edit_type');
			$popup = Input::get('popup');
			$macro = Input::get('macro');

			$urcBtn = new URCBtnData($roomId, -1);
			$result = $urcBtn->storePowerMacro($autoWait, $editType, $popup, $activity, $macro);

			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to store activity' ));
			}

			URCSystemData::updateEditTime($foundSystem->id, '');

			return Response::json(array('result' => true));
		}
	}

	public function microtime_gap($microTimeSt, $microTimeEd)
	{
	     list($usecSt, $secSt) = explode(" ", $microTimeSt);
	     $stTime = ((float)$usecSt + (float)$secSt);

	     list($usecEd, $secEd) = explode(" ", $microTimeEd);
	     $edTime = ((float)$usecEd + (float)$secEd);

	     return ($edTime - $stTime);
	}

	public function checkSearchKey($key, $userId, $mac) {

		if(strlen($key) < 4) {
			return false;
		}

		try
		{
			$realKey = Crypt::decrypt($key);
		}
		catch(\Exception $e) 
		{
			return false;
		}

		if(!$realKey || strlen($realKey) < 4) {
			return false;
		}

		$subMac = substr($mac, -4);
		$pos = strpos($realKey, $subMac);
		if($pos === false) {
			return false;
		}

		$arData = explode('|', $realKey);
		if(count($arData) < 3) {//0:userId, 1:timestamp, from 2...
			return false;
		}

		if($arData[0] !== ((string)$userId)) {
			return false;
		}

		$seconds = $this->microtime_gap($arData[1], microtime());
		if($seconds < 0 || $seconds > 360) {
			return false;
		}

		return true;
	}
}