Difference between revisions of "API"
(27 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
This is community documentation for the API. To see official documentation, review zoneminder.readthedocs. | This is community documentation for the API. To see official documentation, review https://zoneminder.readthedocs.io/en/stable/api.html. | ||
Users reading this doc may also want to read the wiki page for [[ZMNinja]]. | |||
==Test API is Working (1.32+)== | ==Test API is Working (1.32+)== | ||
Line 7: | Line 8: | ||
curl -X GET http://serverip/zm/api/host/getVersion.json | curl -X GET http://serverip/zm/api/host/getVersion.json | ||
If you are having further trouble, try searching the forum or possibly enabling debugging in cakephp, and also in the web server. | If you are having further trouble, try searching the forum or possibly enabling debugging in cakephp, and also in the web server. | ||
===API changes in 1.37=== | |||
See for example: https://forums.zoneminder.com/viewtopic.php?t=32884 | |||
==SSL Configuration== | ==SSL Configuration== | ||
Line 21: | Line 25: | ||
Setting up self signed SSL certs for apache2 is a common sysadmin task that will not be covered in this guide. Search online for more info. | Setting up self signed SSL certs for apache2 is a common sysadmin task that will not be covered in this guide. Search online for more info. | ||
==Configuring CakePHP for "x webserver"== | ==Examples== | ||
There are quite a few examples on the official docs. See: https://zoneminder.readthedocs.io/en/stable/api.html#examples | |||
Here are some additional notes. | |||
===Adjusting Monitor from Modect to Monitor=== | |||
Start motion detection on monitor 3 | |||
/usr/bin/curl -XPOST http://localhost/zm/api/monitors/3.json -d "Monitor[Function]=Modect&Monitor[Enabled]=1" | |||
Stop motion detection on monitor 3 | |||
/usr/bin/curl -XPOST http://localhost/zm/api/monitors/3.json -d "Monitor[Function]=Monitor&Monitor[Enabled]=1" | |||
from: https://forums.zoneminder.com/viewtopic.php?t=32771 | |||
===Turning off Recording and Motion Detection 1.37=== | |||
For those looking later, this turns off my motion detection recording: | |||
/usr/bin/curl -XPOST http://localhost/zm/api/monitors/3.json -d "Monitor[Analysing]=None&Monitor[Recording]=None&Monitor[Enabled]=1" | |||
and this turns on my motion detect recording: | |||
/usr/bin/curl -XPOST http://localhost/zm/api/monitors/6.json -d "Monitor[Analysing]=Always&Monitor[Recording]=OnMotion&Monitor[Enabled]=1" | |||
from: https://forums.zoneminder.com/viewtopic.php?t=32884 | |||
Note that the API is different from 1.36 to 1.37. Function has been removed. | |||
===Finding something in the API=== | |||
There is no reference documentation for the API, so instead review the source code. The CakePHP implementation is easy enough to understand. Although, it helps to be familiar with the ZM database structure. All commands are listed in https://github.com/ZoneMinder/zoneminder/tree/master/web/api/app/Controller. So for example, | |||
curl -X POST -d "user=somename&pass=somepass" http://serverip/zm/api/host/getVersion.json | |||
References the HostController. Any other Controller can be referenced by substituting the <name>Controller in /api/<name>/ section of the URL above. Therefore to get events we would use: | |||
curl -X POST -d "user=somename&pass=somepass" http://serverip/zm/api/events/<somecommand> | |||
To find the <somecommand>, simply look at the functions available for this controller/class. For events, a couple of them will expect parameters, so you might want to start with one that just runs as-is. The index command seems like a good choice, and if you run the following, you will get an index of events (note that this uses pagination, see: https://zoneminder.readthedocs.io/en/stable/api.html#return-a-list-of-all-events) | |||
curl -X POST -d "user=somename&pass=somepass" http://serverip/zm/api/events/index.json | |||
From there it's just a matter of knowing what the Controller expects as input. See the examples from the official docs and the source code. | |||
==Troubleshooting== | |||
===Configuring CakePHP for "x webserver"=== | |||
Having recently setup the API for lighttpd, I found the following was necessary in order to get | Having recently setup the API for lighttpd, I found the following was necessary in order to get | ||
it to work properly. Perhaps this information will assist someone else who isn't using Apache / Nginx / Lighttpd as | it to work properly. Perhaps this information will assist someone else who isn't using Apache / Nginx / Lighttpd as | ||
the configuration should be similar for any webserver that supports PHP, aliases and rewrites. | the configuration should be similar for any webserver that supports PHP, aliases and rewrites. | ||
===Alias'=== | ====Alias'==== | ||
First off the webroot for zm may look something like this: | First off the webroot for zm may look something like this: | ||
Line 50: | Line 85: | ||
requests to myserver/api go to /usr/share/zoneminder/www/api/app/webroot | requests to myserver/api go to /usr/share/zoneminder/www/api/app/webroot | ||
===Rewrites=== | ====Rewrites==== | ||
The final thing you need to understand is that CakePHP has a single index.php file that does all the work for the API. | The final thing you need to understand is that CakePHP has a single index.php file that does all the work for the API. | ||
So when you request <code>http://serverip/zm/api/host/getVersion.json</code> what is actually happening is that | So when you request <code>http://serverip/zm/api/host/getVersion.json</code> what is actually happening is that | ||
Line 69: | Line 104: | ||
"^/zm/api(.+)$" => "/zm/api/index.php" | "^/zm/api(.+)$" => "/zm/api/index.php" | ||
) | ) | ||
The apache one is not intuitive so instead look at lighttpd. This is a (pcre) regex with ^-start with /zm/api then (.+) any number | |||
of characters to the end $ then change to /zm/api/index.php. Essentially, any request that is /zm/api-whatever will be converted to /zm/api/index.php. | of characters to the end $ then change to /zm/api/index.php. Essentially, any request that is /zm/api-whatever will be converted to /zm/api/index.php. | ||
===curl -X GET http://serverip/zm/api/host/getVersion.json returns with 'page not found'=== | |||
Check that you have an up to date copy of the /etc/apache2/conf-available/zoneminder.conf file. If in doubt, compare to a working installation. I recently had a case, where the zoneminder.conf file was missing some of the configurations (it must've been from migrating an older ZM to 1.36), it should be around 50+ lines of code for 1.36. Also make sure the appropriate apache modules are enabled (a2enmod rewrites, a2enmod cgi, and there are some others, see wiki.zoneminder.com/Debian). | |||
===Example Configuration for /etc/apache2/conf-enabled/zoneminder.conf=== | |||
See also the example in the github gist below. Although that one does not | |||
work for me, but the following one does. | |||
<pre> | |||
# Remember to enable cgi mod (i.e. "a2enmod cgi"). | |||
ScriptAlias /zm/cgi-bin "/usr/lib/zoneminder/cgi-bin" | |||
<Directory "/usr/lib/zoneminder/cgi-bin"> | |||
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch | |||
AllowOverride All | |||
Require all granted | |||
</Directory> | |||
# Order matters. This alias must come first. | |||
Alias /zm/cache /var/cache/zoneminder/cache | |||
<Directory /var/cache/zoneminder/cache> | |||
Options -Indexes +FollowSymLinks | |||
AllowOverride None | |||
<IfModule mod_authz_core.c> | |||
# Apache 2.4 | |||
Require all granted | |||
</IfModule> | |||
</Directory> | |||
Alias /zm /usr/share/zoneminder/www | |||
<Directory /usr/share/zoneminder/www> | |||
Options -Indexes +FollowSymLinks | |||
<IfModule mod_dir.c> | |||
DirectoryIndex index.php | |||
</IfModule> | |||
</Directory> | |||
# For better visibility, the following directives have been migrated from the | |||
# default .htaccess files included with the CakePHP project. | |||
# Parameters not set here are inherited from the parent directive above. | |||
<Directory "/usr/share/zoneminder/www/api"> | |||
RewriteEngine on | |||
RewriteRule ^$ app/webroot/ [L] | |||
RewriteRule (.*) app/webroot/$1 [L] | |||
RewriteBase /zm/api | |||
</Directory> | |||
<Directory "/usr/share/zoneminder/www/api/app"> | |||
RewriteEngine on | |||
RewriteRule ^$ webroot/ [L] | |||
RewriteRule (.*) webroot/$1 [L] | |||
RewriteBase /zm/api | |||
</Directory> | |||
<Directory "/usr/share/zoneminder/www/api/app/webroot"> | |||
RewriteEngine On | |||
RewriteCond %{REQUEST_FILENAME} !-d | |||
RewriteCond %{REQUEST_FILENAME} !-f | |||
RewriteRule ^ index.php [L] | |||
RewriteBase /zm/api | |||
</Directory> | |||
</pre> | |||
==See Also== | |||
* [[ZMNinja]] | |||
* [[External_Live_Stream]] - An example of using the API to show the camera streams in a webpage. | |||
* https://gist.github.com/connortechnology/9ca83f812d94b2777b93ad54ee45067e Example apache config | |||
[[Category:Dummies_Guide]] | [[Category:Dummies_Guide]] |
Latest revision as of 17:05, 26 August 2024
This is community documentation for the API. To see official documentation, review https://zoneminder.readthedocs.io/en/stable/api.html. Users reading this doc may also want to read the wiki page for ZMNinja.
Test API is Working (1.32+)
Use this command if you've enabled authentication.
curl -X POST -d "user=somename&pass=somepass" http://serverip/zm/api/host/getVersion.json
Make sure all of this is included. It is not necessary to use login.json before running this command. The ampersand must be between user and pass. If you aren't using authentication then use the following:
curl -X GET http://serverip/zm/api/host/getVersion.json
If you are having further trouble, try searching the forum or possibly enabling debugging in cakephp, and also in the web server.
API changes in 1.37
See for example: https://forums.zoneminder.com/viewtopic.php?t=32884
SSL Configuration
Related to the API, if you wish to have some encryption, refer to /etc/apache2/ports.conf You will see that it requires the ssl module, and the symbolic link.
a2enmod ssl
Add the symbolic link for /etc/apache2/sites-available/default-ssl.conf to sites-enabled.
And uncomment / enable SSLEngine, SSLCertificateKey, and SSLCertificateKeyFile in /etc/apache2/sites-available/default-ssl.conf.
You may optionally want to generate a new SSL key.
Setting up self signed SSL certs for apache2 is a common sysadmin task that will not be covered in this guide. Search online for more info.
Examples
There are quite a few examples on the official docs. See: https://zoneminder.readthedocs.io/en/stable/api.html#examples Here are some additional notes.
Adjusting Monitor from Modect to Monitor
Start motion detection on monitor 3 /usr/bin/curl -XPOST http://localhost/zm/api/monitors/3.json -d "Monitor[Function]=Modect&Monitor[Enabled]=1" Stop motion detection on monitor 3 /usr/bin/curl -XPOST http://localhost/zm/api/monitors/3.json -d "Monitor[Function]=Monitor&Monitor[Enabled]=1"
from: https://forums.zoneminder.com/viewtopic.php?t=32771
Turning off Recording and Motion Detection 1.37
For those looking later, this turns off my motion detection recording: /usr/bin/curl -XPOST http://localhost/zm/api/monitors/3.json -d "Monitor[Analysing]=None&Monitor[Recording]=None&Monitor[Enabled]=1" and this turns on my motion detect recording: /usr/bin/curl -XPOST http://localhost/zm/api/monitors/6.json -d "Monitor[Analysing]=Always&Monitor[Recording]=OnMotion&Monitor[Enabled]=1"
from: https://forums.zoneminder.com/viewtopic.php?t=32884
Note that the API is different from 1.36 to 1.37. Function has been removed.
Finding something in the API
There is no reference documentation for the API, so instead review the source code. The CakePHP implementation is easy enough to understand. Although, it helps to be familiar with the ZM database structure. All commands are listed in https://github.com/ZoneMinder/zoneminder/tree/master/web/api/app/Controller. So for example,
curl -X POST -d "user=somename&pass=somepass" http://serverip/zm/api/host/getVersion.json
References the HostController. Any other Controller can be referenced by substituting the <name>Controller in /api/<name>/ section of the URL above. Therefore to get events we would use:
curl -X POST -d "user=somename&pass=somepass" http://serverip/zm/api/events/<somecommand>
To find the <somecommand>, simply look at the functions available for this controller/class. For events, a couple of them will expect parameters, so you might want to start with one that just runs as-is. The index command seems like a good choice, and if you run the following, you will get an index of events (note that this uses pagination, see: https://zoneminder.readthedocs.io/en/stable/api.html#return-a-list-of-all-events)
curl -X POST -d "user=somename&pass=somepass" http://serverip/zm/api/events/index.json
From there it's just a matter of knowing what the Controller expects as input. See the examples from the official docs and the source code.
Troubleshooting
Configuring CakePHP for "x webserver"
Having recently setup the API for lighttpd, I found the following was necessary in order to get it to work properly. Perhaps this information will assist someone else who isn't using Apache / Nginx / Lighttpd as the configuration should be similar for any webserver that supports PHP, aliases and rewrites.
Alias'
First off the webroot for zm may look something like this:
/usr/share/zoneminder/www$ ls ajax css graphics index.php lang skins vendor api fonts includes js robots.txt tools views
What you need to know is that the api is NOT at
/usr/share/zoneminder/www/api
but in fact is located at
/usr/share/zoneminder/www/api/app/webroot
So clients to the webserver will navigate to yourserverip/zm/api
but the webserver will deliver yourserverip/www/api/app/webroot
assuming that www == zm.
(in apache, this is handled by /etc/apache2/conf-available/zoneminder.conf
with Alias /zm /usr/share/zoneminder/www
)
The API is handled in a similar manner. Instead of aliasing /zm to /usr/share/zoneminder/www/ there will be an
alias from /zm/api to /usr/share/zoneminder/www/api/app/webroot. Yes, it is confusing that there is a folder named
API that is NOT the API, when in fact the webroot folder is the API. Don't ask me. I didn't design it. Apache doesn't
help with its verbose configuration, compared to the leaner config found in lighttpd which is more intuitive.
So now we have the following
requests to myserver/zm go to /usr/share/zoneminder/www/ requests to myserver/api go to /usr/share/zoneminder/www/api/app/webroot
Rewrites
The final thing you need to understand is that CakePHP has a single index.php file that does all the work for the API.
So when you request http://serverip/zm/api/host/getVersion.json
what is actually happening is that
the server will pass /host/getVersion.json
to /zm/api/index.php, and index.php will do its black
magic to get the ZM version. This is because if you try to navigate directly to http://serverip/zm/api/host/getVersion.json
(without a rewrite rule in place) you will get a 404, because there is no such file in /www/api/app/webroot
. How this is handled in the
web servers is there is a rewrite rule (not an alias this time) that takes anything that is /zm/api-whatever (the
regex covers everything after /zm/api) and changes it to /zm/api/index.php. Then this index.php handles the request.
In apache this rule looks like:
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] RewriteBase /zm/api
In lighttpd this rule looks like:
url.rewrite = ( "^/zm/api(.+)$" => "/zm/api/index.php" )
The apache one is not intuitive so instead look at lighttpd. This is a (pcre) regex with ^-start with /zm/api then (.+) any number of characters to the end $ then change to /zm/api/index.php. Essentially, any request that is /zm/api-whatever will be converted to /zm/api/index.php.
curl -X GET http://serverip/zm/api/host/getVersion.json returns with 'page not found'
Check that you have an up to date copy of the /etc/apache2/conf-available/zoneminder.conf file. If in doubt, compare to a working installation. I recently had a case, where the zoneminder.conf file was missing some of the configurations (it must've been from migrating an older ZM to 1.36), it should be around 50+ lines of code for 1.36. Also make sure the appropriate apache modules are enabled (a2enmod rewrites, a2enmod cgi, and there are some others, see wiki.zoneminder.com/Debian).
Example Configuration for /etc/apache2/conf-enabled/zoneminder.conf
See also the example in the github gist below. Although that one does not work for me, but the following one does.
# Remember to enable cgi mod (i.e. "a2enmod cgi"). ScriptAlias /zm/cgi-bin "/usr/lib/zoneminder/cgi-bin" <Directory "/usr/lib/zoneminder/cgi-bin"> Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch AllowOverride All Require all granted </Directory> # Order matters. This alias must come first. Alias /zm/cache /var/cache/zoneminder/cache <Directory /var/cache/zoneminder/cache> Options -Indexes +FollowSymLinks AllowOverride None <IfModule mod_authz_core.c> # Apache 2.4 Require all granted </IfModule> </Directory> Alias /zm /usr/share/zoneminder/www <Directory /usr/share/zoneminder/www> Options -Indexes +FollowSymLinks <IfModule mod_dir.c> DirectoryIndex index.php </IfModule> </Directory> # For better visibility, the following directives have been migrated from the # default .htaccess files included with the CakePHP project. # Parameters not set here are inherited from the parent directive above. <Directory "/usr/share/zoneminder/www/api"> RewriteEngine on RewriteRule ^$ app/webroot/ [L] RewriteRule (.*) app/webroot/$1 [L] RewriteBase /zm/api </Directory> <Directory "/usr/share/zoneminder/www/api/app"> RewriteEngine on RewriteRule ^$ webroot/ [L] RewriteRule (.*) webroot/$1 [L] RewriteBase /zm/api </Directory> <Directory "/usr/share/zoneminder/www/api/app/webroot"> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] RewriteBase /zm/api </Directory>
See Also
- ZMNinja
- External_Live_Stream - An example of using the API to show the camera streams in a webpage.
- https://gist.github.com/connortechnology/9ca83f812d94b2777b93ad54ee45067e Example apache config