/remote-monitor

Primary LanguagePythonMIT LicenseMIT

Contributors Forks Stargazers Issues MIT License

About The Project

Note 1: See my write-up on IoT with Balena Cloud. Here you can find a brief write-up about my projects based on Balena Cloud and my general experience with this IoT platform.

Note 2: If you are already familiar with my Base Application, you will notice a similar structure here but since this application is rooted in Balena images, it needs to carry a few of its own functions like the supervisor configuration. Although this project carries some duplication of functionality factored out from my other projects, the relative simplicity of this project to support Balena provides some justification.

This is a Python project designed specifically to interface with the Raspberry Pi GPIO interface with both an attached analog-to-digital converter (ADC) and I/O expander board to which output signals are sent. The purpose of this configuration is to be able to sense inputs on the ADC, process these inputs elsewhere and then support sending output signals on the I/O channels. The blog post above provides context behind this setup. The other feature of this project is that it is configured for deployment to the device via Balena Cloud, a web service that makes it easy to link git actions to deployment actions.

(back to top)

Built With

Technologies that help make this project useful:

1Password RabbitMQ Raspberry Pi Poetry Python Sentry ZeroMQ

Also:

(back to top)

Getting Started

Here is some detail about the intended use of this package.

Prerequisites

Beyond the Python dependencies defined in the Poetry configuration, the package init carries hardcoded dependencies on Sentry and 1Password in order to function in order to function. Unless you want these you're likely better off forking this package and cutting out what you do not need.

This project is structured as is for use with Balena Cloud and requires the Fleet service variables listed below to be set in order for the application to start properly.

💡 It is best to configure these at the level of the Balena Fleet as opposed to the device because all device variables are local to each device and are deleted with the device when you decommission broken devices.

Since this project uses additional remotes for Git submodule usage, a push to the Balena remote is insufficient to include all artifacts for the build. For this, you need to use the balena push command supplied by the balena CLI. Be sure to use the correct Balena application name when using balena push because the tool will not perform validation of the local context against the build deployed to the device and so you could run the risk of deploying the wrong code to a fleet.

Assuming that you have registered your device with Balena Cloud, the Balena CLI tool is then used to push your project to the Balena builder. To do this, fetch either the fleet or device ID using either balena fleets or balena devices. Then use balena push to push the project including the git-submodule to the builder. If successful, the device will automatically begin downloading the image delta generated for the new release revision.

Basic Functions

This project showcases a variety of common functionality borrowed from one of my common libraries and so is relatively compact for what it does.

  • A 1Password CredsConfig instance is created to support Sentry and Cronitor monitoring (for thread death).
  • pylib.rabbit has plenty of exception handling and so some Rabbit loggers need to be ignored in order to avoid needless Sentry tickets for issues typically triggered by network conditions. Of course, there's always a risk of masking other unchecked issues so use this sparingly.
  • This project uses ZeroMQ for inter-thread IPC for which these inproc URLs are defined.
  • Relay abstracts a physical electronic relay. Upon receipt of a message, will send an output signal on the associated address.
  • RelayControl is aware of how many relays are configured on the shield outputs and addresses them by label.
  • The main application loop is responsible for sampling from the ADC inputs, translating and applying thresholds the sampled input values, determining outlier values and then ultimately dispatching a message to the RabbitMQ bus for further processing.

Installation

🛑 This project uses 1Password Secrets Automation to store both application key-value pairs as well as runtime secrets. It is assumed that the connect server containers are already running on your environment. If you do not want to use this, then you'll need to fork this package and make the changes as appropriate. It's actually very easy to set up, but note that 1Password is a paid product with a free-tier for secrets automation. An example of the items fetched from 1Password can be found here.

Here is the list of Balena Fleet variables used by this application:

  • APP_NAME: Used for referencing the application's actual name for the logger. This project uses remote_monitor.
  • AWS_CONFIG_FILE: Standard local location of the AWS configuration file. This project uses /home/app/.aws/config. Used previously for some AWS SWF integration but is required for build until I trim this out.
  • AWS_DEFAULT_REGION: As above used previously. Set to anything valid like us-east-1.
  • CRONITOR_MONITOR_KEY: Token to enable additional health checks presented in Cronitor. This tracks thread count and overall health.
  • OP_CONNECT_HOST, OP_CONNECT_TOKEN, OP_CONNECT_VAULT: Used to specify the URL of the 1Password connect server with associated client token and Vault ID. See 1Password for more.
  • HC_PING_URL: Healthchecks URL of this application's current health check status.
  • INPUT_*, OUTPUT_*: Used as label substitutions in the application configuration.
  • RABBITMQ_DEVICE_TOPIC: Input and output messages to another application for decision making. This project uses ioboard.
  • RABBITMQ_EXCHANGE: RabbitMQ has a configured exchange on which topics are registered. This project uses home_automation.
  • RABBITMQ_SERVER_ADDRESS: IP address of the RabbitMQ server.
  • RSYSLOG_SERVER: IP address of the desired rsyslog server.

With these configured, you are now able to build the application.

  1. Clone the repo
    git clone https://github.com/tailucas/remote-monitor.git
    cd remote-monitor
  2. Verify that the git submodule is present.
    git submodule init
    git submodule update
  3. Retrieve the Balena Fleet or Device ID using the Balena CLI.
    balena fleets
    balena devices
  4. Push to Balena Cloud which triggers a build and automatic device download.
    balena push $FLEET_ID

(back to top)

Usage

If your device is properly registered with Balena Cloud by downloading your device-specific operating system image, it should be visible in the management interface. Thereafter a successful build of your project via balena push should be enough to download and start your application.

(back to top)

License

Distributed under the MIT License. See LICENSE for more information.

(back to top)

Acknowledgments

(back to top)

Hits