{"_id":"543d4a17a10ab32000b3aace","version":{"_id":"543b943865bf840e00b473b6","__v":5,"project":"543b943865bf840e00b473b3","createdAt":"2014-10-13T08:58:32.703Z","releaseDate":"2014-10-13T08:58:32.703Z","categories":["543b943865bf840e00b473b7","543b96e1b1479b1400c42f3d","543d1cdc3a300f20000d31ee","553e061924ec240d00b1f897","553e06431a946a0d00ad6f78"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":true,"codename":"","version_clean":"1.0.0","version":"1.0"},"category":{"_id":"543b943865bf840e00b473b7","version":"543b943865bf840e00b473b6","project":"543b943865bf840e00b473b3","__v":15,"pages":["543ffb2c22a3b30e001bdc37","543b965fb1479b1400c42f3a","543d1cbb5276641a00a593c3","543d3ff2a10ab32000b3aa9e","543d1fa83a300f20000d3206","543f8f8a051bdc0e00dfbf02","543d4a17a10ab32000b3aace","543ea21f3f50eb1a00ed2050","543ea6ac3f50eb1a00ed205e","543ebaedcc182e08005d0cc4","543f8cb422a3b30e001bdb48","543f838422a3b30e001bdb36","544184629c7623200053c8e7","5541356a69a03a2d00ce0b3b"],"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2014-10-13T08:58:32.718Z","from_sync":false,"order":9999,"slug":"documentation","title":"Documentation"},"user":"543b93f865bf840e00b473b2","is_link":false,"project":"543b943865bf840e00b473b3","__v":13,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2014-10-14T16:06:47.243Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"basic_auth":false,"results":{"codes":[]},"try":true,"auth":"never","params":[],"url":""},"isReference":false,"order":6,"body":"[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Debugging apps\"\n}\n[/block]\nThis section gives some guidance on how to develop and debug bridge-apps. Everyone will have their own preference, so this is mainly guidance from a personal perspective. The guidance is given from someone who tends not to use IDEs, but for those who do like IDEs, we have had some good experience using JetBrain's PyCharm IDE. \n[block:callout]\n{\n  \"type\": \"success\",\n  \"title\": \"Getting started: copying an existing app.\",\n  \"body\": \"To deploy an app, it needs to be in GitHub, so GitHub is a good place to start. In your GitHub account, click on \\\"New Repository\\\". Give your new repository a name and a description and initialize it with a Readme. After you've created it, click the \\\"HTTPS clone URL\\\" on the right-hand side of the GitHub repository page and copy it to the clipboard. You can then cd to ~/apps_dev (create the directory first if it doesn't exist) and git clone your new repository. Eg:\\n\\n    git clone https://github.com/ContinuumBridge/my_app.git\\n    \\nYou can then git clone an existing app repository. Eg:\\n\\n   git clone https://github.com/ContinuumBridge/demo_switch_app.git\\n\\nAnd copy the files from this into your new repository.\"\n}\n[/block]\nOnce you've written the first version of your app, you'll need to register it so that it will appear in the portal and you can add it to your bridge (as described in The ContinuumBridge Portal section). Do this as described in the “deploying apps” section. Once you've done this, if you refresh your browser tab, the app will appear in the “app market” and you will be able to add it to your bridge and connect devices to it.\n\nWe tend to do most debugging using logging. ContinuumBridge has a logging methodology built on top of Python logging that puts logging messages from all apps and adaptors, along with the cbridge core modules, in the same log file (from v0.7.8 of cbridge onwards, these are /var/log/cbridge.log and /var/log/cbshell.log). To write a log message, use the cbLog method in your app:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"self.cbLog(LOGLEVEL, \\\"a string\\\")\",\n      \"language\": \"python\"\n    }\n  ]\n}\n[/block]\nwhere LOGLEVEL is one of:\n\n    debug\n    info\n    warning\n    error\n    critical\n   \nFor example, you can write things like:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"self.cbLog(\\\"debug\\\", \\\"switchID:\\\" + self.switchID)\",\n      \"language\": \"python\"\n    }\n  ]\n}\n[/block]\nThis writes the value of self.switchID to the file /var/log/cbridge.log (/opt/cbridge/thisbridge/bridge.log prior to v0.7.8 of cbridge). This file contains logging from all apps and adaptors on the bridge, as well as from cbridge itself. Each line has a timestamp, which makes it easier to see what is happening in your app relative to other things that are happening on the bridge. \n\nThe level of logging is controlled using the CB_LOG_ENVIRONMENT variable, which is set by editing the file /opt/cbridge/thisbridge/thisbridge.sh, and including the line:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"export CB_LOG_ENVIRONMENT='debug'\",\n      \"language\": \"shell\"\n    }\n  ]\n}\n[/block]\nreplacing “debug” with the required level. There are five levels of logging: debug, info, warning, error and critical. The example above uses debug. The debug level displays all messages that are labels as debug, info, warning, error and critical; the info level just displays messages labelled as info, warning and error, as so on.\n\nThere are examples of the use of logging in the ContinuummBridge example apps. For example, you can include lines such as:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"self.cbLog(\\\"debug\\\", \\\"Trying to turn on/off before switch connected\\\")\\nself.cbLog(\\\"debug\\\", \\\"received message: \\\" + str(message))\",\n      \"language\": \"python\"\n    }\n  ]\n}\n[/block]\nRemember that the second parameter of self.cbLog must be a string, so you need to cast other types (eg: integers, floats, dictionaries, lists) to strings, as in the above example.\n\nIt's common to want to log a message that may have been received from an adaptor. This can be made more readable in the log file using json.dumps() with an indent, as in this example:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"self.cbLog(\\\"debug\\\", \\\"onadaptorData, message: \\\" + str(json.dumps(message, indent=4)))\",\n      \"language\": \"python\"\n    }\n  ]\n}\n[/block]\nNow that this is all in place, you can run your app. Having added it in the portal, remember to press “Update” to download the configuration to the bridge (this requirement will go in a future version). Then press “Restart” to restart cbridge with your app. We tend to debug by tailing the log file and also the shell.log file in a separate shell:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"cd /var/log\\ntail -f cbridge.log cbshell.log\",\n      \"language\": \"shell\"\n    }\n  ]\n}\n[/block]\nAll logging messages appear in cbridge.log. If your app crashes then the traceback information that Python would normally write to the screen is written to cbshell.log. Cbridge uses rotational log files. The maximum size of cbridge.log is limtied to 1 MB, after which it will be renamed to cbridge.log.1. In all, five log files of this form are kept before the oldest one is deleted.\n\nVarious environment variables can be set in /opt/cbridge/thisbridge/thisbridge.sh. We've already looked at CB_LOG_ENVIRONMENT. Here are the others that you can set. The file also contains various other variables (such as the key for accessing the bridge controller), which you must not change.  \n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Variable\",\n    \"h-1\": \"Allowed Values\",\n    \"h-2\": \"Description\",\n    \"0-0\": \"CB_DEV_BRIDGE\",\n    \"0-1\": \"True, False\",\n    \"0-2\": \"f true, this is a development bridge. Apps and adaptors can be located in the apps_dev and adaptors_dev directories in the user's home directory.\",\n    \"1-0\": \"CB_DEV_APPS\",\n    \"1-1\": \"String\",\n    \"1-2\": \"A list of app names separated by commas. Eg: 'app1, app2'. These are the apps that the bridge will look for in apps_dev.\",\n    \"2-0\": \"CB_DEV_ADAPTORS\",\n    \"2-1\": \"String\",\n    \"2-2\": \"A list of adaptor names separated by commas. Eg: 'adaptor 1, adaptor2'. Behaves as CB_DEV_APPS.\",\n    \"3-0\": \"CB_USERNAME\",\n    \"3-2\": \"The name of the user where apps_dev and adaptors_dev is located. If you are thce default “pi” user, you should set this to pi.\",\n    \"3-1\": \"String\",\n    \"4-0\": \"CB_ZWAVE_BRIDGE\",\n    \"4-1\": \"True, False\",\n    \"4-2\": \"This is set to True if a Razberry Z-wave board and associated software are included on the bridge.\"\n  },\n  \"cols\": 3,\n  \"rows\": 5\n}\n[/block]\nSet each of these as an environment variable using an export statement, as in the debug example, above.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Deploying apps\"\n}\n[/block]\nYou can copy an app to the apps_dev directories on as many Raspberry Pies as you like and use them in development mode, but if you want to distribute it widely you will probably want to put it in the ContinuumBridge App Market.  It can then be found by anyone with a bridge by clicking on the “Download Apps” button on their user portal. Currently, all bridge-apps are deployed via Github and the process is as follows. A basic familiarity with git and GitHub is assumed.\n\nFirstly, ensure that the code you want to deploy is in Github and tagged as a release. Eg: v1.0.0. If you're new to GitHub and writing a simple app, push your code to GitHub using the following commands (for an app called \"mylovelyapp\"):\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"cd ~/apps_dev/mylovelyapp\\ngit add .\\ngit commit -m \\\"A helpful comment\\\"\\ngit push\",\n      \"language\": \"shell\"\n    }\n  ]\n}\n[/block]\nOnce you've pushed your code to GitHub, you can tag it as follows:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"git tag -a v1.0.0. -m \\\"The first version of my lovely app\\\"\\ngit push --tags\",\n      \"language\": \"shell\"\n    }\n  ]\n}\n[/block]\nNavigate to the release in Github and copy the link address of the tar.gz file for the release. This will be of the form:\n\nhttps://github.com/ContinuumBridge/mylovelyapp/archive/v1.0.0.tar.gz\n\nNext, you need to create a JSON configuration file in the home directory of your app. For the example we used, the following text would be put in the file: ~/apps_dev/demo_switch_app/config.json\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n    \\\"name\\\": \\\"Demo Switch App\\\",\\n    \\\"url\\\": \\\"https://github.com/ContinuumBridge/demo_switch_app/archive/v1.0.0.tar.gz\\\",\\n    \\\"exe\\\": \\\"demo_switch_app.py\\\",\\n    \\\"description\\\": \\\"Controls a switch using binary sensors\\\",\\n    \\\"provider\\\": \\\"ContinuumBridge\\\",\\n    \\\"version\\\": \\\"1.0.0\\\"\\n}\\n\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nThe keys have the following meanings:\n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"\\\"name\\\"\",\n    \"0-1\": \"The name of your app. This appears on the user portal and should be a human-friendly name.\",\n    \"1-0\": \"\\\"url\\\"\",\n    \"1-1\": \"This is the link to the GitHub release, as described above.\",\n    \"2-0\": \"\\\"exe\\\"\",\n    \"2-1\": \"The app executable that the bridge manager should run when it starts your app.\",\n    \"3-0\": \"\\\"description\\\"\",\n    \"3-1\": \"This can be as long as you like and tells a user what your app does.\",\n    \"4-0\": \"\\\"provider\\\"\",\n    \"4-1\": \"Your name or the name or your organisation.\",\n    \"5-0\": \"\\\"version\\\"\",\n    \"5-1\": \"This should correspond to the release tag.\"\n  },\n  \"cols\": 2,\n  \"rows\": 6\n}\n[/block]\nNext, for this example, you would go into the app's home directory and initialzse the app, as follows:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"cd ~/apps_dev/demo_switch_app\\ncb --app post config.json --user <user name> --password <password>\",\n      \"language\": \"shell\"\n    }\n  ]\n}\n[/block]\nIf you leave out the user name or password you will be prompted for them (and you can type the password without it being visible). \n\nIf you get any error or warning messages, then make any corrections necessary, otherwise you should find your app on the portal. The cb --app command alters the config.json file. It's a good idea to add, commit and push this to GitHib, so that everything is up to date. \n\nYou can check that your app has been successfully deployed by typing:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"cb --app get config.json --user <user name> --password <password>\",\n      \"language\": \"shell\"\n    }\n  ]\n}\n[/block]\nYou will also see your bridge-app in the portal, but you'll need to refresh the tab of your browser first.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"A full list of cb commands can be found here:  [The cb Command](doc:the-cb-command)\",\n  \"title\": \"The cb command\"\n}\n[/block]\nTo check that the deployed app works on your development bridge, you can switch your Raspberry Pi back from being a development bridge to a standard bridge by removing the line that says export CB_DEV_BRIDGE='True' from /opt/cbridge/thisbridge/thisbridge.sh or by setting the value to 'False'. You'll then need to restart cbridge by typing:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"sudo service cbridge restart\",\n      \"language\": \"shell\"\n    }\n  ]\n}\n[/block]\nYou can also use the commands \"start\" and \"stop\" instead of \"restart\" with the above.\n\nThen go to the portal and press Update (note: not Upgrade), followed by Restart. When you press Update, you should see a message saying that your app has been updated. Congratulations!\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"A simple development process\"\n}\n[/block]\n With a simple app, as you make releases, you'll probably find it easiest to adopt a process like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"cd ~/apps/mylovelyapp\\n# To make sure you have the latest code:\\ngit pull\",\n      \"language\": \"shell\"\n    }\n  ]\n}\n[/block]\nEdit and debug your code\nEdit config.json and change the url and version values. Eg: from v1.0.0 to v1.1.0\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"# Note you use patch rather than post after the first time:\\ncb --app patch config.json\\ngit add .\\ngit commit -m \\\"Added some wonderful new features\\\"\\ngit push\\ngit tag -a v1.1.0 -m \\\"Added some wonderful new features\\\"\\ngit push --tags\",\n      \"language\": \"shell\"\n    }\n  ]\n}\n[/block]\n[Next ...](doc:the-bridge-app-api)","excerpt":"","slug":"developing-bridge-apps","type":"basic","title":"Developing Apps"}
[block:api-header] { "type": "basic", "title": "Debugging apps" } [/block] This section gives some guidance on how to develop and debug bridge-apps. Everyone will have their own preference, so this is mainly guidance from a personal perspective. The guidance is given from someone who tends not to use IDEs, but for those who do like IDEs, we have had some good experience using JetBrain's PyCharm IDE. [block:callout] { "type": "success", "title": "Getting started: copying an existing app.", "body": "To deploy an app, it needs to be in GitHub, so GitHub is a good place to start. In your GitHub account, click on \"New Repository\". Give your new repository a name and a description and initialize it with a Readme. After you've created it, click the \"HTTPS clone URL\" on the right-hand side of the GitHub repository page and copy it to the clipboard. You can then cd to ~/apps_dev (create the directory first if it doesn't exist) and git clone your new repository. Eg:\n\n git clone https://github.com/ContinuumBridge/my_app.git\n \nYou can then git clone an existing app repository. Eg:\n\n git clone https://github.com/ContinuumBridge/demo_switch_app.git\n\nAnd copy the files from this into your new repository." } [/block] Once you've written the first version of your app, you'll need to register it so that it will appear in the portal and you can add it to your bridge (as described in The ContinuumBridge Portal section). Do this as described in the “deploying apps” section. Once you've done this, if you refresh your browser tab, the app will appear in the “app market” and you will be able to add it to your bridge and connect devices to it. We tend to do most debugging using logging. ContinuumBridge has a logging methodology built on top of Python logging that puts logging messages from all apps and adaptors, along with the cbridge core modules, in the same log file (from v0.7.8 of cbridge onwards, these are /var/log/cbridge.log and /var/log/cbshell.log). To write a log message, use the cbLog method in your app: [block:code] { "codes": [ { "code": "self.cbLog(LOGLEVEL, \"a string\")", "language": "python" } ] } [/block] where LOGLEVEL is one of: debug info warning error critical For example, you can write things like: [block:code] { "codes": [ { "code": "self.cbLog(\"debug\", \"switchID:\" + self.switchID)", "language": "python" } ] } [/block] This writes the value of self.switchID to the file /var/log/cbridge.log (/opt/cbridge/thisbridge/bridge.log prior to v0.7.8 of cbridge). This file contains logging from all apps and adaptors on the bridge, as well as from cbridge itself. Each line has a timestamp, which makes it easier to see what is happening in your app relative to other things that are happening on the bridge. The level of logging is controlled using the CB_LOG_ENVIRONMENT variable, which is set by editing the file /opt/cbridge/thisbridge/thisbridge.sh, and including the line: [block:code] { "codes": [ { "code": "export CB_LOG_ENVIRONMENT='debug'", "language": "shell" } ] } [/block] replacing “debug” with the required level. There are five levels of logging: debug, info, warning, error and critical. The example above uses debug. The debug level displays all messages that are labels as debug, info, warning, error and critical; the info level just displays messages labelled as info, warning and error, as so on. There are examples of the use of logging in the ContinuummBridge example apps. For example, you can include lines such as: [block:code] { "codes": [ { "code": "self.cbLog(\"debug\", \"Trying to turn on/off before switch connected\")\nself.cbLog(\"debug\", \"received message: \" + str(message))", "language": "python" } ] } [/block] Remember that the second parameter of self.cbLog must be a string, so you need to cast other types (eg: integers, floats, dictionaries, lists) to strings, as in the above example. It's common to want to log a message that may have been received from an adaptor. This can be made more readable in the log file using json.dumps() with an indent, as in this example: [block:code] { "codes": [ { "code": "self.cbLog(\"debug\", \"onadaptorData, message: \" + str(json.dumps(message, indent=4)))", "language": "python" } ] } [/block] Now that this is all in place, you can run your app. Having added it in the portal, remember to press “Update” to download the configuration to the bridge (this requirement will go in a future version). Then press “Restart” to restart cbridge with your app. We tend to debug by tailing the log file and also the shell.log file in a separate shell: [block:code] { "codes": [ { "code": "cd /var/log\ntail -f cbridge.log cbshell.log", "language": "shell" } ] } [/block] All logging messages appear in cbridge.log. If your app crashes then the traceback information that Python would normally write to the screen is written to cbshell.log. Cbridge uses rotational log files. The maximum size of cbridge.log is limtied to 1 MB, after which it will be renamed to cbridge.log.1. In all, five log files of this form are kept before the oldest one is deleted. Various environment variables can be set in /opt/cbridge/thisbridge/thisbridge.sh. We've already looked at CB_LOG_ENVIRONMENT. Here are the others that you can set. The file also contains various other variables (such as the key for accessing the bridge controller), which you must not change. [block:parameters] { "data": { "h-0": "Variable", "h-1": "Allowed Values", "h-2": "Description", "0-0": "CB_DEV_BRIDGE", "0-1": "True, False", "0-2": "f true, this is a development bridge. Apps and adaptors can be located in the apps_dev and adaptors_dev directories in the user's home directory.", "1-0": "CB_DEV_APPS", "1-1": "String", "1-2": "A list of app names separated by commas. Eg: 'app1, app2'. These are the apps that the bridge will look for in apps_dev.", "2-0": "CB_DEV_ADAPTORS", "2-1": "String", "2-2": "A list of adaptor names separated by commas. Eg: 'adaptor 1, adaptor2'. Behaves as CB_DEV_APPS.", "3-0": "CB_USERNAME", "3-2": "The name of the user where apps_dev and adaptors_dev is located. If you are thce default “pi” user, you should set this to pi.", "3-1": "String", "4-0": "CB_ZWAVE_BRIDGE", "4-1": "True, False", "4-2": "This is set to True if a Razberry Z-wave board and associated software are included on the bridge." }, "cols": 3, "rows": 5 } [/block] Set each of these as an environment variable using an export statement, as in the debug example, above. [block:api-header] { "type": "basic", "title": "Deploying apps" } [/block] You can copy an app to the apps_dev directories on as many Raspberry Pies as you like and use them in development mode, but if you want to distribute it widely you will probably want to put it in the ContinuumBridge App Market. It can then be found by anyone with a bridge by clicking on the “Download Apps” button on their user portal. Currently, all bridge-apps are deployed via Github and the process is as follows. A basic familiarity with git and GitHub is assumed. Firstly, ensure that the code you want to deploy is in Github and tagged as a release. Eg: v1.0.0. If you're new to GitHub and writing a simple app, push your code to GitHub using the following commands (for an app called "mylovelyapp"): [block:code] { "codes": [ { "code": "cd ~/apps_dev/mylovelyapp\ngit add .\ngit commit -m \"A helpful comment\"\ngit push", "language": "shell" } ] } [/block] Once you've pushed your code to GitHub, you can tag it as follows: [block:code] { "codes": [ { "code": "git tag -a v1.0.0. -m \"The first version of my lovely app\"\ngit push --tags", "language": "shell" } ] } [/block] Navigate to the release in Github and copy the link address of the tar.gz file for the release. This will be of the form: https://github.com/ContinuumBridge/mylovelyapp/archive/v1.0.0.tar.gz Next, you need to create a JSON configuration file in the home directory of your app. For the example we used, the following text would be put in the file: ~/apps_dev/demo_switch_app/config.json [block:code] { "codes": [ { "code": "{\n \"name\": \"Demo Switch App\",\n \"url\": \"https://github.com/ContinuumBridge/demo_switch_app/archive/v1.0.0.tar.gz\",\n \"exe\": \"demo_switch_app.py\",\n \"description\": \"Controls a switch using binary sensors\",\n \"provider\": \"ContinuumBridge\",\n \"version\": \"1.0.0\"\n}\n", "language": "json" } ] } [/block] The keys have the following meanings: [block:parameters] { "data": { "0-0": "\"name\"", "0-1": "The name of your app. This appears on the user portal and should be a human-friendly name.", "1-0": "\"url\"", "1-1": "This is the link to the GitHub release, as described above.", "2-0": "\"exe\"", "2-1": "The app executable that the bridge manager should run when it starts your app.", "3-0": "\"description\"", "3-1": "This can be as long as you like and tells a user what your app does.", "4-0": "\"provider\"", "4-1": "Your name or the name or your organisation.", "5-0": "\"version\"", "5-1": "This should correspond to the release tag." }, "cols": 2, "rows": 6 } [/block] Next, for this example, you would go into the app's home directory and initialzse the app, as follows: [block:code] { "codes": [ { "code": "cd ~/apps_dev/demo_switch_app\ncb --app post config.json --user <user name> --password <password>", "language": "shell" } ] } [/block] If you leave out the user name or password you will be prompted for them (and you can type the password without it being visible). If you get any error or warning messages, then make any corrections necessary, otherwise you should find your app on the portal. The cb --app command alters the config.json file. It's a good idea to add, commit and push this to GitHib, so that everything is up to date. You can check that your app has been successfully deployed by typing: [block:code] { "codes": [ { "code": "cb --app get config.json --user <user name> --password <password>", "language": "shell" } ] } [/block] You will also see your bridge-app in the portal, but you'll need to refresh the tab of your browser first. [block:callout] { "type": "info", "body": "A full list of cb commands can be found here: [The cb Command](doc:the-cb-command)", "title": "The cb command" } [/block] To check that the deployed app works on your development bridge, you can switch your Raspberry Pi back from being a development bridge to a standard bridge by removing the line that says export CB_DEV_BRIDGE='True' from /opt/cbridge/thisbridge/thisbridge.sh or by setting the value to 'False'. You'll then need to restart cbridge by typing: [block:code] { "codes": [ { "code": "sudo service cbridge restart", "language": "shell" } ] } [/block] You can also use the commands "start" and "stop" instead of "restart" with the above. Then go to the portal and press Update (note: not Upgrade), followed by Restart. When you press Update, you should see a message saying that your app has been updated. Congratulations! [block:api-header] { "type": "basic", "title": "A simple development process" } [/block] With a simple app, as you make releases, you'll probably find it easiest to adopt a process like this: [block:code] { "codes": [ { "code": "cd ~/apps/mylovelyapp\n# To make sure you have the latest code:\ngit pull", "language": "shell" } ] } [/block] Edit and debug your code Edit config.json and change the url and version values. Eg: from v1.0.0 to v1.1.0 [block:code] { "codes": [ { "code": "# Note you use patch rather than post after the first time:\ncb --app patch config.json\ngit add .\ngit commit -m \"Added some wonderful new features\"\ngit push\ngit tag -a v1.1.0 -m \"Added some wonderful new features\"\ngit push --tags", "language": "shell" } ] } [/block] [Next ...](doc:the-bridge-app-api)