Set function from API does not work

Forum for questions and support relating to the 1.28.x releases only.
marcolino7
Posts: 73
Joined: Wed Sep 16, 2015 12:20 pm

Re: Set function from API does not work

Post by marcolino7 »

Hi asker,
sorry for less information provided, but meanwhile I did some other test, and rebooted all server, Zoneminder and Openhab.
After reboot, seems API working from both, browser and curl.
I did more test this evening, and I'll keep you updated.

Regards

Marco
Production Zoneminder 1.31.4 Ubuntu 16.04 LTS on VmWare ESXi
6 Cameras FOSCAM FI8918W
OpenHab Integration
marcolino7
Posts: 73
Joined: Wed Sep 16, 2015 12:20 pm

Re: Set function from API does not work

Post by marcolino7 »

Hi asker,
all working fine now. I have last version of ZM and API, authentication works, and I can control my ZM from OpenHab.

Now I'm back on original issue, the funcion does not work due a bug in MonitorsController.php.
Here is my version of the file, can you help me to add daemon controller?

Code: Select all

<?php
App::uses('AppController', 'Controller');
/**
 * Monitors Controller
 *
 * @property Monitor $Monitor
 * @property PaginatorComponent $Paginator
 */
class MonitorsController extends AppController {


/**
 * Components
 *
 * @var array
 */
	public $components = array('Paginator', 'RequestHandler');

/**
 * index method
 *
 * @return void
 */
	public function index() {
                $this->Monitor->recursive = 0;
        	$monitors = $this->Monitor->find('all');
        	$this->set(array(
        	    'monitors' => $monitors,
        	    '_serialize' => array('monitors')
        	));
	}

/**
 * view method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function view($id = null) {
		$this->Monitor->recursive = 0;
		if (!$this->Monitor->exists($id)) {
			throw new NotFoundException(__('Invalid monitor'));
		}
		$options = array('conditions' => array('Monitor.' . $this->Monitor->primaryKey => $id));
		$monitor = $this->Monitor->find('first', $options);
		$this->set(array(
			'monitor' => $monitor,
			'_serialize' => array('monitor')
		));
	}

/**
 * add method
 *
 * @return void
 */
	public function add() {
		if ($this->request->is('post')) {
			$this->Monitor->create();
			if ($this->Monitor->save($this->request->data)) {
				$this->daemonControl($this->Monitor->id, 'start', $this->request->data);
				return $this->flash(__('The monitor has been saved.'), array('action' => 'index'));
			}
		}
	}

/**
 * edit method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function edit($id = null) {
		$this->Monitor->id = $id;

		if (!$this->Monitor->exists($id)) {
			throw new NotFoundException(__('Invalid monitor'));
		}

		if ($this->Monitor->save($this->request->data)) {
			$message = 'Saved';
		} else {
			$message = 'Error';
		}

		$this->set(array(
			'message' => $message,
			'_serialize' => array('message')
		));
	}

/**
 * delete method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function delete($id = null) {
		$this->Monitor->id = $id;
		if (!$this->Monitor->exists()) {
			throw new NotFoundException(__('Invalid monitor'));
		}
		$this->request->allowMethod('post', 'delete');

		$this->daemonControl($this->Monitor->id, 'stop');

		if ($this->Monitor->delete()) {
			return $this->flash(__('The monitor has been deleted.'), array('action' => 'index'));
		} else {
			return $this->flash(__('The monitor could not be deleted. Please, try again.'), array('action' => 'index'));
		}
	}

	public function sourceTypes() {
		$sourceTypes = $this->Monitor->query("describe Monitors Type;");

		preg_match('/^enum\((.*)\)$/', $sourceTypes[0]['COLUMNS']['Type'], $matches);
		foreach( explode(',', $matches[1]) as $value ) {
			$enum[] = trim( $value, "'" );
		}

		$this->set(array(
			'sourceTypes' => $enum,
			'_serialize' => array('sourceTypes')
		));
	}

	// Check if a daemon is running for the monitor id
	public function daemonStatus() {
		$id = $this->request->params['named']['id'];
		$daemon = $this->request->params['named']['daemon'];

		if (!$this->Monitor->exists($id)) {
			throw new NotFoundException(__('Invalid monitor'));
		}

		$monitor = $this->Monitor->find('first', array(
			'fields' => array('Id', 'Type', 'Device'),
			'conditions' => array('Id' => $id)
		));

		// Clean up the returned array
		$monitor = Set::extract('/Monitor/.', $monitor);

		// Pass -d for local, otherwise -m
		if ($monitor[0]['Type'] == 'Local') {
			$args = "-d ". $monitor[0]['Device'];	
		} else {
			$args = "-m ". $monitor[0]['Id'];
		}

		// Build the command, and execute it
		$zm_path_bin = Configure::read('ZM_PATH_BIN');
		$command = escapeshellcmd("$zm_path_bin/zmdc.pl status $daemon $args");
		$status = exec( $command );

		// If 'not' is present, the daemon is not running, so return false
		// https://github.com/ZoneMinder/ZoneMinder/issues/799#issuecomment-108996075
		// Also sending back the status text so we can check if the monitor is in pending
		// state which means there may be an error
		$statustext = $status;
		$status = (strpos($status, 'not')) ? false : true;

		$this->set(array(
			'status' => $status,
			'statustext' => $statustext,
			'_serialize' => array('status','statustext'),
		));
	}

	public function daemonControl($id, $command, $monitor=null, $daemon=null) {
		$args = '';
		$daemons = array();

		if (!$monitor) {
			// Need to see if it is local or remote
			$monitor = $this->Monitor->find('first', array(
				'fields' => array('Type', 'Function'),
				'conditions' => array('Id' => $id)
			));
			$monitor = $monitor['Monitor'];
		}

		if ($monitor['Type'] == 'Local') {
			$args = "-d " . $monitor['Device'];
		} else {
			$args = "-m " . $id;
		}

		if ($monitor['Function'] == 'Monitor') {
			array_push($daemons, 'zmc');
		} else {
			array_push($daemons, 'zmc', 'zma');
		}
		
		$zm_path_bin = Configure::read('ZM_PATH_BIN');

		foreach ($daemons as $daemon) {
			$shellcmd = escapeshellcmd("$zm_path_bin/zmdc.pl $command $daemon $args");
			$status = exec( $shellcmd );
		}
	}

}

Thanks
Production Zoneminder 1.31.4 Ubuntu 16.04 LTS on VmWare ESXi
6 Cameras FOSCAM FI8918W
OpenHab Integration
marcolino7
Posts: 73
Joined: Wed Sep 16, 2015 12:20 pm

Re: Set function from API does not work

Post by marcolino7 »

Hi @asker,
finally it seems I have fixed. Let me know if my code is fine and Can you add this to ZM code? may I have to open an issue on git?
Thanks

Code: Select all

	public function edit($id = null) {
		$this->Monitor->id = $id;

		if (!$this->Monitor->exists($id)) {
			throw new NotFoundException(__('Invalid monitor'));
		}

		if ($this->Monitor->save($this->request->data)) {
			$message = 'Saved';
		} else {
			$message = 'Error';
		}

		$this->set(array(
			'message' => $message,
			'_serialize' => array('message')
		));

		//I added Line Below
		$this->daemonControl($this->Monitor->id, 'restart');

	}
Production Zoneminder 1.31.4 Ubuntu 16.04 LTS on VmWare ESXi
6 Cameras FOSCAM FI8918W
OpenHab Integration
marcolino7
Posts: 73
Joined: Wed Sep 16, 2015 12:20 pm

Re: Set function from API does not work

Post by marcolino7 »

Hi @asker,
unfornunately my code does not work.

When I setup Function to "Monitor" via API, the monitor still continue to record on motion.

Please let me know what you need to troubleshoot.

Regards
Production Zoneminder 1.31.4 Ubuntu 16.04 LTS on VmWare ESXi
6 Cameras FOSCAM FI8918W
OpenHab Integration
User avatar
asker
Posts: 1553
Joined: Sun Mar 01, 2015 12:12 pm

Re: Set function from API does not work

Post by asker »

Please change your line to

Code: Select all

$this->daemonControl($this->Monitor->id, 'restart', $this->request->data);
I tested and it works - just refresh your web console and you will see the monitor has been updated. If you monitor your logs you will also see that your monitor restarts correctly.
marcolino7 wrote:Hi @asker,
unfornunately my code does not work.

When I setup Function to "Monitor" via API, the monitor still continue to record on motion.

Please let me know what you need to troubleshoot.

Regards
I no longer work on zmNinja, zmeventnotification, pyzm or mlapi. I may respond on occasion based on my available time/interest.

Please read before posting:
How to set up logging properly
How to troubleshoot and report - ES
How to troubleshoot and report - zmNinja
ES docs
zmNinja docs
marcolino7
Posts: 73
Joined: Wed Sep 16, 2015 12:20 pm

Re: Set function from API does not work

Post by marcolino7 »

Hi,
I got something like that:

Code: Select all

2015-09-28 17:41:58.143934	zma_m1	9960	INF	In mode 2/0, warming up	zma.cpp	142
2015-09-28 17:41:58.083790	zmdc	9960	INF	'zma -m 1' started at 15/09/28 17:41:58	zmdc.pl	
2015-09-28 17:41:58.083780	zmdc	1186	INF	'zma -m 1' starting at 15/09/28 17:41:58, pid = 9960	zmdc.pl	
2015-09-28 17:41:58.078040	zmdc	1186	INF	Starting pending process, zma -m 1	zmdc.pl	
2015-09-28 17:41:58.012956	zmc_m1	9959	INF	Starting Capture version 1.28.106	zmc.cpp	250
2015-09-28 17:41:57.965330	zmdc	1186	INF	'zma -m 1' exited normally	zmdc.pl	
2015-09-28 17:41:57.948209	zma_m1	9602	INF	Got signal 15 (Terminated), exiting	zm_signal.cpp	40
2015-09-28 17:41:57.943270	zmdc	1186	INF	'zma -m 1' sending stop to pid 9602 at 15/09/28 17:41:57	zmdc.pl	
2015-09-28 17:41:57.908340	zmdc	9959	INF	'zmc -m 1' started at 15/09/28 17:41:57	zmdc.pl	
2015-09-28 17:41:57.908310	zmdc	1186	INF	'zmc -m 1' starting at 15/09/28 17:41:57, pid = 9959	zmdc.pl	
2015-09-28 17:41:57.900420	zmdc	1186	INF	Starting pending process, zmc -m 1	zmdc.pl	
2015-09-28 17:41:57.810104	zma_m2	9954	INF	In mode 2/0, warming up	zma.cpp	142
2015-09-28 17:41:57.788180	zmdc	1186	INF	'zmc -m 1' exited normally	zmdc.pl	
it seems a restart of daemon for monitor with id 1.
I'll keep under monitor.

Marco
Production Zoneminder 1.31.4 Ubuntu 16.04 LTS on VmWare ESXi
6 Cameras FOSCAM FI8918W
OpenHab Integration
Locked