{"id":16520278,"url":"https://github.com/andreacioni/motionctrl","last_synced_at":"2026-05-08T12:44:37.797Z","repository":{"id":57578736,"uuid":"120762735","full_name":"andreacioni/motionctrl","owner":"andreacioni","description":"more than just a simple motion proxy","archived":false,"fork":false,"pushed_at":"2020-09-20T10:05:42.000Z","size":244,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-13T10:34:57.944Z","etag":null,"topics":["home","https","integration","ipcam","ipcamera","motion","proxy","rest-api"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andreacioni.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-02-08T13:08:16.000Z","updated_at":"2018-04-25T19:44:41.000Z","dependencies_parsed_at":"2022-09-26T19:14:10.851Z","dependency_job_id":null,"html_url":"https://github.com/andreacioni/motionctrl","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreacioni%2Fmotionctrl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreacioni%2Fmotionctrl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreacioni%2Fmotionctrl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreacioni%2Fmotionctrl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andreacioni","download_url":"https://codeload.github.com/andreacioni/motionctrl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241587917,"owners_count":19986627,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["home","https","integration","ipcam","ipcamera","motion","proxy","rest-api"],"created_at":"2024-10-11T16:50:16.708Z","updated_at":"2026-05-08T12:44:32.759Z","avatar_url":"https://github.com/andreacioni.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# motionctrl [![Travis CI](https://travis-ci.org/andreacioni/motionctrl.svg?branch=master)](https://travis-ci.org/andreacioni/motionctrl) [![Release](https://img.shields.io/badge/release-passing-brightgreen.svg)](https://github.com/andreacioni/motionctrl/releases) [![Go Report Card](https://goreportcard.com/badge/github.com/andreacioni/motionctrl)](https://goreportcard.com/report/github.com/andreacioni/motionctrl)\n\nmotionctrl is a RESTful API written in Golang that acts as a controller/proxy for [motion](https://github.com/Motion-Project/motion/) (with some sweet additional feature). It also can help you to build an IP camera and control it from any other third-part application.\n\n__Why motionctrl?__\n\nmotionctlr allows you to:\n- start/stop motion through an easy REST api service\n- provide only one point to access both stream and webcontrol\n- improve motion stream/webcontrol security with HTTPS\n- managing motion with JSON REST api that replace the old text webcontrol interface integrated in motion\n- backup old image/video in Google Drive* (archive \u0026 encryption support) (more [here](#backup))\n- notify event through Telegram* to every device you want (more [here](#notification))\n- host simple frontend application (more [here](#application-path))\n\n*: more backup and notify services could be implemented easily, take a look inside backup/ notify/ folders!\n\n__Download__\n\nDownload of precompiled version is available [here](https://github.com/andreacioni/motionctrl/releases)\n\n__Configuration__\n\nIn order to execute *motionctrl* you need a valid JSON configuration file, an example of it could be:\n\n```json\n{\n    \"address\" : \"127.0.0.1\",\n    \"port\" : 8888,\n    \"motionConfigFile\" : \"/etc/motion/motion.conf\",\n\n    \"username\" : \"user\",\n    \"password\" : \"pass\",\n\n    \"appPath\" : \"/path/to/app\",\n\n    \"ssl\" : {\n        \"key\" : \"/path/to/key.key\",\n        \"cert\" : \"/path/to/cert.pem\"\n    },\n\n    \"backup\" :  {\n        \"when\" : \"@every 1m\",\n        \"method\" : \"google\",\n        \"encryptionKey\" : \"super_secret_key\",\n        \"archive\":true,\n        \"filePerArchive\" : 10\n    },\n\n    \"notify\" : {\n        \"method\" : \"telegram\",\n        \"token\" : \"YOUR TELEGRAM API KEY\",\n        \"to\": [\"12345678\"],\n        \"message\": \"Motion recognized\",\n        \"photo\": 2\n    }\n}\n```\n\nTo allow *motionctrl* to interact with motion correctly you MUST set some *motion* parameter (defined inside ```motionConfigFile```) to following values:\n\nName | Value\n---- | -----\nwebcontrol_port | TCP/IP port \nstream_port | TCP/IP port \nstream_auth_method | 0 \nstream_authentication | comment this \nwebcontrol_html_output| off \nwebcontrol_parms | 2 \nwebcontrol_authentication | comment this \nprocess_id_file | pid file path \ntarget_dir | target directory file path \n\nAn example of a valid configuration should be:\n\n\n```\ntarget_dir /home/pi/motion/output\n\nprocess_id_file /home/pi/motion/run/motion.pid\n\nwebcontrol_port 8080\n\nwebcontrol_parms 2\n\n#webcontrol_authentication\n\nwebcontrol_html_output off\n\nstream_port 8081\n\nstream_auth_method 0\n\n#stream_authentication\n\n[...]\n\n```\n\n\n__Launch__\n\nSimple usage: ```$\u003e ./motionctrl```\n\nAccepted command line arguments ( ```$\u003e ./motionctrl -h```):\n```\n  -a    start motion right after motionctrl\n  -c string\n        configuration file path (default \"config.json\")\n  -d    when -a is set, starts with motion detection enabled\n  -l string\n        set log level (default \"WARN\")\n```\n\n# Available APIs\n\nAll the following APIs are accessible from ```/api```\n\n- [/control](#controlstartup)\n  - [/startup](#controlstartup)\n  - [/shutdown](#controlshutdown)\n  - [/restart](#controlrestart)\n  - [/status](#controlstatus)\n- [/detection](#detectionstart)\n  - [/start](#detectionstart)\n  - [/stop](#detectionstop)\n  - [/status](#detectionstatus)\n- [/config](#configlist)\n  - [/list](#configlist)\n  - [/get](#configgetconfig)\n  - [/set](#configset)\n  - [/write](#configwrite)\n- [/camera](#camerastream)\n  - [/stream](#camerastream)\n  - [/snapshot](#camerasnapshot)\n  - [/makemovie](#makemovie)\n- [/targetdir](#targetdirlist)\n  - [/list](#targetdirlist)\n  - [/size](#targetdirsize)\n  - [/get](#targetdirgetfilename)\n  - [/remove](#targetdirremovefilename)\n- [/backup](#backupstatus)\n  - [/status](#backupstatus)\n  - [/launch](#backuplaunch)\n\n### /control/startup\n\n- **Description**: launch motion\n- **Method**: ``` GET ```\n- **Parameters**:\n  - *detection*: should be used to start motion with motion detection enabled at startup (default: ```false```)\n- **Return**:\n  - *Status Code + Body*:\n    - 200: motion started succefully\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 400: detection parameter **must** be ```true``` or ```false```\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n - Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/control/startup?detection=true\n\nOutput: {\"message\":\"motion started\"}\n ```\n### /control/shutdown\n\n- **Description**: shutdown motion\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: motion shutdown succefully\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n - Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/control/shutdown\n\nOutput: {\"message\":\"motion stopped\"}\n ```\n\n### /control/restart\n\n- **Description**: restart motion\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: motion restarted succefully\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 409: motion not started yet\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```   \n - Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/control/restart\n\nOutput: {\"message\":\"motion restarted\"}\n ```\n\n### /control/status\n\n- **Description**: restart motion\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: motion status retrieved succefully\n    - Response type: JSON\n    ```\n    {\"motionStarted\": true|false}\n    ```\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```   \n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/control/status\n\nOutput: {\"motionStarted\":false}\n ```\n\n### /detection/start\n\n- **Description**: start motion detection\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: motion detection enabled\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 409: motion not started yet\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/detection/start\n\n{\"message\":\"motion detection started\"}\n ```\n\n### /detection/stop\n\n- **Description**: stop motion detection\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: motion detection paused\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 409: motion not started yet\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/detection/stop\n\n{\"message\":\"motion detection paused\"}\n ```\n\n### /detection/status\n\n- **Description**: return the current state of motion detection\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: motion detection status retrieved\n    - Response type: JSON\n    ```\n    {\"motionDetectionEnabled\": true|false}\n    ```\n    - 409: motion not started yet\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/detection/status\n\n{\"motionDetectionEnabled\":false}\n ```\n\n### /config/list\n\n- **Description**: list all motion configuration\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: configuration list retrieved correctly\n    - Response type: JSON\n    ```\n    { \n      \u003cCONFIG_KEY1\u003e: \u003cCONFIG_VALUE1\u003e,\n      \u003cCONFIG_KEY2\u003e: \u003cCONFIG_VALUE2\u003e,\n      ...\n    }\n    ```\n    - 409: motion not started yet\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/config/list\n\n{\"area_detect\":null,\"auto_brightness\":0,\"camera\":null,\"camera_dir\":null,\"camera_id\":0,\"camera_name\":null,\"daemon\":true,\" ... }\n ```\n\n### /config/get/:config:\n\n- **Description**: get the specified configuration parameter\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: configuration parameter retrieved correctly\n    - Response type: JSON\n    ```\n    { \u003cCONFIG_KEY\u003e: \u003cCONFIG_VALUE\u003e }\n    ```\n    - 409: motion not started yet\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/config/get/event_gap\n\n{\"event_gap\":20}\n ```\n\n### /config/set\n\n- **Description**: set the specified configuration to a specified value\n- **Method**: ``` GET ```\n- **Parameters**: \n  - *\\\u003ckey\\\u003e*:\\\u003cvalue\\\u003e set \\\u003ckey\\\u003e configuration to \\\u003cvalue\\\u003e\n  - *writeback* (optional): indicates if the configuration will be written to the motion configuration file (default: ```false```)\n- **Return**:\n  - *Status Code + Body*:\n    - 200: configuration set correctly\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 409: motion not started yet\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/config/set?event_gap=60\u0026writeback=true\n\n{\"event_gap\":60}\n ```\n\n### /config/write\n\n- **Description**: write current configuration to motion configuration file\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: configuration wrote correctly to file\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 409: motion not started yet\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/config/write\n\n{\"message\":\"configuration written to file\"}\n ```\n\n### /camera/stream\n\n- **Description**: camera stream\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: streaming\n    - Response type: MJPEG stream\n    - 409: motion not started yet\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/control/startup\n\nOpen your browser and go to: http://localhost:8888/api/camera/stream\n ```\n\n### /camera/snapshot\n\n- **Description**: capture and retrieve snapshot from camera\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: snapshot\n    - Response type: image\n    - 409: motion not started yet\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/control/startup\n\nOpen your browser and go to: http://localhost:8888/api/camera/snapshot\n ```\n \n ### /camera/makemovie\n\n- **Description**: make a movie and save it inside *target_dir*\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: making a movie\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 409: motion not started yet\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/control/startup; curl  http://localhost:8888/api/camera/makemovie\n ```\n\n### /targetdir/list\n\n- **Description**: list all files in *target_dir*\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: snapshot\n    - Response type: JSON\n    ```\n    [\n      {\n        \"name\": \u003cSTRING\u003e,\n        \"creationDate\": \u003cDATE\u003e\n      },\n      ...\n    ]\n    ```\n    - 500: generic internal server error\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/targetdir/list\n\nOutput: [{\"name\":\"01-20180314152202-01.jpg\",\"creationDate\":\"2018-03-14T15:22:02.88866395+01:00\"},{\"name\":\"01-20180314152202.mkv\",\"creationDate\":\"2018-03-14T15:22:16.728497457+01:00\"}, ... ]\n ```\n\n### /targetdir/size\n\n- **Description**: evaluate the *target_dir* folder size\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: size evaluated succefully\n    - Response type: JSON\n    ```\n    { \"size\": \u003cINTEGER\u003e }\n    ```\n    - 500: generic internal server error\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/targetdir/size\n\nOutput: {\"size\":3753260} ~ 3.75 MB\n ```\n\n### /targetdir/get/:filename:\n\n- **Description**: retrieve *filename* from *target_dir*\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: file retrieved correctly\n    - Response type: file from *target_dir*\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\nOpen your browser and go to: http://10.8.0.1:8888/api/targetdir/get/01-20180314152211-01.jpg\n ```\n\n### /targetdir/remove/:filename:\n\n- **Description**: remove *filename* from *target_dir*\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: file removed correctly\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/targetdir/remove/06-20180314114422-01.jpg\n\nOutput: {\"message\":\"06-20180314114422-01.jpg successfully removed\"}\n ```\n\n### /backup/status\n\n- **Description**: get the current state of backup service\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: status retrieved correctly\n    - Response type: JSON\n    ```\n    {\"status\": \"ACTIVE_IDLE\" | \"ACTIVE_RUNNING\" | \"NOT_ACTIVE\"}\n    ```\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/backup/status\n\nOutput: {\"status\":\"ACTIVE_IDLE\"}\n ```\n\n### /backup/launch\n\n- **Description**: run backup service now\n- **Method**: ``` GET ```\n- **Parameters**: N.D.\n- **Return**:\n  - *Status Code + Body*:\n    - 200: backup service stared\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n    - 500: generic internal server error\n    - Response type: JSON\n    ```\n    {\"message\": \u003cSTRING\u003e}\n    ```\n- Example:\n ```\n$\u003e curl http://10.8.0.1:8888/api/backup/launch\n\nOutput: {\"message\":\"backup service is running now\"}\n ```\n\n### Internal APIs\n\nThere are some APIs that are not accessible directly by the user. These APIs (accessible from ```/internal```) are necessary to let *motion* communicate events to *motionctrl*.\n\nThis APIs are required by built-in [notification service](#notification) of *motionctrl*\n\n# Backup\n\nFollowing steps are needed only if you want to enable backup service available in *motionctrl*\n\n*motionctrl* allows you to backup files produced by *motion* (images, videos) to your Google Drive account.\n\nHere below some example showing, only, backup section of motionctrl config file:\n\n1. Manual backup trigger it with (/api/backup/launch)[#backuplaunch]\n```json\n\"backup\" :  {\n        \"when\" : \"manual\",\n        \"method\" : \"google\",\n    }\n```\n\n2. Automatic backup when ```target_dir``` size is greater than 10 Mbyte\n```json\n\"backup\" :  {\n        \"when\" : \"10MB\",\n        \"method\" : \"google\",\n    }\n```\n\n3. Automatic backup every day at 22:00\n```json\n\"backup\" :  {\n        \"when\" : \"0 22 * * *\",\n        \"method\" : \"google\",\n    }\n```\n\n4. Automatic backup every day at 22:00, encrypt every single file before upload\n```json\n\"backup\" :  {\n        \"when\" : \"0 22 * * *\",\n        \"method\" : \"google\",\n        \"encryptionKey\": \"secret_password\",\n    }\n```\n\n5. Automatic backup every day at 22:00, create archives with max 10 files and encrypt them before upload\n```json\n\"backup\" :  {\n        \"when\" : \"0 22 * * *\",\n        \"method\" : \"google\",\n        \"encryptionKey\": \"secret_password\",\n        \"archive\":true,\n        \"filePerArchive\" : 10\n    }\n```\n\nIn order to correctly login to your account you must simply run *motionctrl* and follow the istructions on the command line.\n\n# Notification\n\nFollowing steps are needed only if you want to enable notification service available in *motionctrl*\n\n- Install ```curl```\n- Open your motion configuration file (e.g. /etc/motion/motion.conf)\n- Set ```on_event_start``` and ```on_event_end``` ```on_picture_save``` to:\n\n```\n# Command to be executed when an event starts. (default: none)\n# An event starts at first motion detected after a period of no motion defined by event_gap\non_event_start curl http://localhost:8888/internal/event/start\n\n# Command to be executed when an event ends after a period of no motion\n# (default: none). The period of no motion is defined by option event_gap.\non_event_end curl http://localhost:8888/internal/event/end\n\n# Command to be executed when a picture (.ppm|.jpg) is saved (default: none)\n# To give the filename as an argument to a command append it with %f\non_picture_save curl http://localhost:8888/internal/event/picture/saved?picturepath=%f\n```\n\n**NOTE**: curl command syntax could differ in case you have enabled HTTPS (replace ```http``` with ```https```).\n\nNow you can add *notify* section to your *motionctrl* configuration file.\n\n```json\n\"notify\" : {\n        \"method\" : \"telegram\",\n        \"token\" : \"324565775:JHBFEIFEIBFedae-2neuifbEDEEGEFEAF\",\n        \"to\": [\"12345678\", \"87654321\"],\n        \"message\": \"Motion recognized\",\n        \"photo\": 2\n    }\n```\n\n```photo``` parameter indicates how many photos are sent to configured chats after an event starts.\n\n# Application Path\n\nIn *motionctrl* configuration file you could specify the ```appPath``` parameter to point to the directory that contains the frontend application files.\nThose files are accessible from: ```http://\u003cIP\u003e:\u003cPORT\u003e/app/```\n\n# FAQ\n\n - How can I obtain valid cert/key to enable HTTPS support?\n   - You can obtain them by issuing: ```openssl genrsa -out key.pem 1024 \u0026\u0026 openssl req -new -x509 -sha256 -key key.pem -out cert.pem -days 365```. This will give you a self signed certificate valid for 365 days.\n   \n - How can I open encrypted backup files?\n   - In order to open *.aes file you need ```aescrypt``` installed on your system. AES Crypt is a cross-plattform AES file encryption/decryption tool that you can download [here](https://www.aescrypt.com/download/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreacioni%2Fmotionctrl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandreacioni%2Fmotionctrl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreacioni%2Fmotionctrl/lists"}