{"id":22468501,"url":"https://github.com/projectweekend/pi-control-service","last_synced_at":"2025-12-16T23:31:38.789Z","repository":{"id":24709557,"uuid":"28121184","full_name":"projectweekend/Pi-Control-Service","owner":"projectweekend","description":"Control a Raspberry Pi from anywhere with RabbitMQ \u0026 Python","archived":false,"fork":false,"pushed_at":"2015-02-21T22:53:16.000Z","size":516,"stargazers_count":18,"open_issues_count":1,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-08T08:08:21.663Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/projectweekend.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.txt","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":"2014-12-17T04:35:04.000Z","updated_at":"2021-02-07T21:17:03.000Z","dependencies_parsed_at":"2022-08-17T17:05:09.336Z","dependency_job_id":null,"html_url":"https://github.com/projectweekend/Pi-Control-Service","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/projectweekend%2FPi-Control-Service","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectweekend%2FPi-Control-Service/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectweekend%2FPi-Control-Service/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/projectweekend%2FPi-Control-Service/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/projectweekend","download_url":"https://codeload.github.com/projectweekend/Pi-Control-Service/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228453982,"owners_count":17922585,"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":[],"created_at":"2024-12-06T11:17:00.113Z","updated_at":"2025-12-16T23:31:38.725Z","avatar_url":"https://github.com/projectweekend.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"**Why I made this**\n\nThis project started because I had an external web server and I wanted it to get some data from sensors on a Raspberry Pi in my apartment. I didn't want to mess with a bunch of stupid networking, so that the two could talk to each other. Instead, I decided to take advantage of [RabbitMQ](https://www.rabbitmq.com/). Messaging queues, like RabbitMQ, are a common tactic for letting separate application components communicate in a simple, scalable way. It's also a great fit for controlling the Raspberry Pi in many [Internet of Things](http://en.wikipedia.org/wiki/Internet_of_Things) type projects.\n\n**What it does**\n\nUsing the GPIO service (`pi_control_service.GPIOControlService`) you have access to the Raspberry Pi's digital GPIO pins. You can turn pins on and off as well as read their values. Using the custom action service (`pi_control_service.CustomActionControlService`) you can call methods on an \"actions\" class you implement. This allows you to do just about anything, like: access [I2C](http://en.wikipedia.org/wiki/I%C2%B2C), [SPI](http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus), or the serial port, and issue system commands.\n\n\n## Install it\n\n```\npip install Pi-Control-Service\n```\n\n## GPIO control service\n\nThe GPIO service (`pi_control_service.GPIOControlService`) exposes access to the Raspberry Pi's digital GPIO pins. Using it you can turn pins on and off as well as read their values. The next two sections cover specifics of its configuration and usage.\n\n### Configuring the GPIO control service\n\nA config file, written in [YAML](http://en.wikipedia.org/wiki/YAML), is used to define the initial pin setup. If a pin is not defined here it will not be available to **Pi-Control-Service**. You can save this file anywhere. You will provide a path to the file in your code. The following snippet shows an example configuration file:\n\n```yaml\n18:\n  mode: OUT\n  initial: HIGH\n23:\n  mode: OUT\n  initial: LOW\n```\n\n* Add a numbered element for each pin to enable\n* `mode` - This controls whether the pin will be used for input or output. Accepted values are: `IN`, `OUT`. (Required)\n* `initial` - This controls the starting value of the pin. Accepted values are: `LOW`, `HIGH`. (Optional - defaults to `LOW`)\n\n### Starting the GPIO service\n\nThis part runs on your Raspberry Pi. It initializes the desired GPIO pins, connects to RabbitMQ and starts listening for messages.\n\n```python\nfrom pi_control_service import GPIOControlService\n\n\n# The RabbitMQ connection string\nRABBIT_URL='some_actual_connection_string'\n\n# A unique string you make up to identify a single Raspberry Pi\nDEVICE_KEY='my_awesome_raspberry_pi'\n\n# Path to the config file referenced in the section above\nPIN_CONFIG = '/path/to/config/file.yml'\n\ngpio_service = GPIOControlService(\n    rabbit_url=RABBIT_URL,\n    device_key=DEVICE_KEY,\n    pin_config=PIN_CONFIG)\n\ngpio_service.start()\n```\n\n**Note:**\nIn addition to the example above, the `GPIOControlService` class takes an optional argument `reconnect_attempts`. This is in integer represneting the number of times to attempt reconnection with RabbitMQ. These attempts will be made if the connection to RabbitMQ is interrupted after the `start()` method is called.\n\n\n### Using the GPIO service\n\nFor convenience there is a [client library](https://github.com/projectweekend/Pi-Control-Client) you can install and use on the computer that will be remotely controlling a Raspberry Pi. The same `RABBIT_URL` and `DEVICE_KEY` values referenced in the section above are also used to connect the client.\n\n#### Installing the client\n\n```\npip install Pi-Control-Client\n```\n\n#### Using the client\n\n```python\nfrom pi_control_client import GPIOClient\n\n# The RabbitMQ connection string (must match the one used when starting the service)\nRABBIT_URL='some_actual_connection_string'\n\n# A unique string you make up to identify a single Raspberry Pi (must match the one used when starting the service)\nDEVICE_KEY='my_awesome_raspberry_pi'\n\npins_client = GPIOClient(rabbit_url=RABBIT_URL)\n\n# Get all pins config\nresult = pins_client.read_config(DEVICE_KEY)\n\n# Get a pin config\nresult = pins_client.read_config(DEVICE_KEY, 18)\n\n# Turn a pin on\npins_client.on(DEVICE_KEY, 18)\n\n# Turn a pin off\npins_client.off(DEVICE_KEY, 18)\n\n# Read a pin value\nresult = pins_client.read_value(DEVICE_KEY, 18)\n```\n\nIf you are already familar with RabbitMQ, you can implement your own client using any language. Things to know:\n\n* The exchange name is: `gpio_control`\n* The `DEVICE_KEY` value is the routing key\n* The JSON messages sent to the broker should be formatted like the following examples:\n\n\n#### Turn a pin on\n```json\n{\n    \"pin\": 18,\n    \"action\": \"on\"\n}\n```\n\n\n#### Turn a pin off\n```json\n{\n    \"pin\": 18,\n    \"action\": \"off\"\n}\n```\n\n\n#### Read a pin value\n```json\n{\n    \"pin\": 18,\n    \"action\": \"read\"\n}\n```\n\n\n#### Read config for all pins\n```json\n{\n    \"action\": \"get_config\"\n}\n```\n\n\n#### Read config for one pin\n```json\n{\n    \"pin\": 18,\n    \"action\": \"get_config\"\n}\n```\n\n\n## Custom action service\n\nThe custom action service (`pi_control_service.CustomActionControlService`) allows you to call methods on a special \"actions\" class that you define. Using it, the possibilities are almost limitless.\n\n\n### Starting the custom action service\n\nThis part runs on your Raspberry Pi. It connects to RabbitMQ and starts listening for messages.\n\n```python\nimport subprocess\n\nfrom pi_control_service import CustomActionControlService\n\n\n# The RabbitMQ connection string\nRABBIT_URL='some_actual_connection_string'\n\n# A unique string you make up to identify a single Raspberry Pi\nDEVICE_KEY='my_awesome_raspberry_pi'\n\n# This class contains all the custom actions that the service will expose\nclass Actions(object):\n\n    def hello_world(self):\n        return {'message': \"I do what I want!\"}\n\n    def cpu_temp(self):\n        return subprocess.check_output([\"/opt/vc/bin/vcgencmd\", \"measure_temp\"])\n\n\ncustom_actions = CustomActionControlService(\n    rabbit_url=RABBIT_URL,\n    device_key=DEVICE_KEY,\n    actions=Actions())\n\ncustom_actions.start()\n```\n\n### Using the custom action service\n\nFor convenience there is a [client library](https://github.com/projectweekend/Pi-Control-Client) you can install and use on the computer that will be remotely controlling a Raspberry Pi. The same `RABBIT_URL` and `DEVICE_KEY` values referenced in the section above are also used to connect the client.\n\n\n#### Installing the client\n\n```\npip install Pi-Control-Client\n```\n\n\n#### Using the client\n\n```python\nfrom pi_control_client import CustomActionClient\n\n# The RabbitMQ connection string (must match the one used when starting the service)\nRABBIT_URL='some_actual_connection_string'\n\n# A unique string you make up to identify a single Raspberry Pi (must match the one used when starting the service)\nDEVICE_KEY='my_awesome_raspberry_pi'\n\nactions_client = CustomActionClient(rabbit_url=RABBIT_URL)\n\n# Call a custom action\nresult = actions_client.call(DEVICE_KEY, 'name_of_action_method')\n```\n\nIf you are already familar with RabbitMQ, you can implement your own client using any language. Things to know:\n\n* The exchange name is: `custom_action_control`\n* The `DEVICE_KEY` value is the routing key\n* The JSON messages sent to the broker should be formatted like the following examples:\n\n\n#### Call an action\n```json\n{\n    \"action\": \"name_of_action_method\"\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprojectweekend%2Fpi-control-service","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprojectweekend%2Fpi-control-service","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprojectweekend%2Fpi-control-service/lists"}