Skip to content

Commit

Permalink
Merge pull request #9 from FarmBot-Labs/file-reorg
Browse files Browse the repository at this point in the history
File reorganization
  • Loading branch information
roryaronson authored Aug 21, 2024
2 parents 19605c3 + 08f0495 commit 636234d
Show file tree
Hide file tree
Showing 24 changed files with 1,676 additions and 1,272 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
318 changes: 203 additions & 115 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
# sidecar-starter-pack

Authentication and communication utilities for FarmBot sidecars

## 📖 Contents

* [Installation](#-installation-mac-os)
* [Getting Started](#-getting-started)
* [Functions](#-functions)
* [Setup](#setup)
* [Information](#information)
* [Messaging](#messaging)
* [Basic Commands](#basic-commands)
* [Movement](#movement)
* [Peripherals](#peripherals)
* [Broker Commands](#broker-commands)
* [Developer Info](#-developer-info)
* [api_connect.py](#api_connectpy)
* [broker_connect.py](#broker_connectpy)

## 💻 Installation (Mac OS)
[![Test Status](https://github.com/FarmBot-Labs/sidecar-starter-pack/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/FarmBot-Labs/sidecar-starter-pack/actions?query=branch%3Amain)
[![Coverage Status](https://coveralls.io/repos/github/FarmBot-Labs/sidecar-starter-pack/badge.svg?branch=main)](https://coveralls.io/github/FarmBot-Labs/sidecar-starter-pack?branch=main)

## :book: Contents

* [Installation](#computer-installation-mac-os)
* [Getting Started](#seedling-getting-started)
* [Get your authentication token](#get-your-authentication-token)
* [Configure function output verbosity](#configure-function-output-verbosity)
* [Functions](#compass-functions)
* [authentication.py](#authenticationpy)
* [basic_commands.py](#basic_commandspy)
* [broker.py](#brokerpy)
* [camera.py](#camerapy)
* [information.py](#informationpy)
* [jobs.py](#jobspy)
* [messages.py](#messagespy)
* [movements.py](#movementspy)
* [peripherals.py](#peripheralspy)
* [resources.py](#resourcespy)
* [tools.py](#toolspy)
* [Developer Info](#toolbox-developer-info)
* [Formatting message broker messages](#formatting-message-broker-messages)

## :computer: Installation (Mac OS)

To set up the project locally, follow these steps:

(1) Clone the repository.
Expand Down Expand Up @@ -46,124 +56,202 @@ python3 -m pip install requests
python3 -m pip install paho-mqtt
```

## 🌱 Getting Started
To generate your authorization token and get started:
## :seedling: Getting Started

(1) Import `main.py` and create an instance.
Import `main.py` and create an instance of the Farmbot class:
```
from farmbot_utilities import Farmbot
from main.py import Farmbot
bot = Farmbot()
```

(2) Generate your authorization token.
The server is https://my.farm.bot by default.
```
bot.get_token('email', 'password', 'server')
```
### Get your authentication token

(3.1) To interact with your Farmbot via the API, try getting your device info:
Use the same login credentials associated with the web app account you are interacting with. The server is "https://my.farm.bot" by default.
```
bot.get_info('device')
bot.get_token("email", "password")
```

(3.2) Try editing your device name:
```
bot.edit_info('device', 'name', 'Carrot Commander')
```
> [!NOTE]
> To interact with your Farmbot via the message broker, you must first establish a connection. Publishing single messages without establishing a connection may trigger your device rate limit.
### Configure function output verbosity

(4.1) Connect to the message broker:
Set the level of verbosity of function outputs to change the level of information shown when functions are called.
```
bot.connect_broker()
bot.set_verbosity(2)
```

(4.2) Try sending a new log message:
```
bot.send_message('Hello from the message broker!', 'success')
```
| Verbosity | Example using `e_stop()` |
| :--- | :--- |
| `0` The function will return with no output. | No output. |
| `1` The name of the function will be output. | `e_stop called` |
| `2` The name of the function will be output with additional information about the return value. | `Triggered device emergency stop at: 2024-08-21 11:16:18.547813` |

(4.3) Try sending a movement command:
```
bot.move(30,40,10)
```
## :compass: Functions

(4.5) After sending messages, don't forget to disconnect from the message broker:
```
bot.disconnect_broker()
sidecar-starter-pack/
├── functions/
│ ├── __init_.py
│ ├── authentication.py
│ ├── basic_commands.py
│ ├── broker.py
│ ├── camera.py
│ ├── imports.py
│ ├── information.py
│ ├── jobs.py
│ ├── messages.py
│ ├── movements.py
│ ├── peripherals.py
│ ├── resources.py
│ └── tools.py
├── tests/
│ ├── __init_.py
│ └── tests_main.py
├── __init_.py
├── imports.py
├── main.py
└── README.md
```

## 🧭 Functions

### Setup

`get_token()` generates user authentication token; call before any other function
`connect_broker()` establishes persistent connect to message broker
`disconnect_broker()` disconnects from the message broker
`listen_broker()` displays messages sent to/from message broker

### Information

`get_info()` returns information about a specific endpoint
`set_info()` edits information belonging to preexisting endpoint
env()
group()
curve()
read_status()
read_sensor()
safe_z()
garden_size()

### Messaging

`log()` sends a new log message via the API
`message()` sends a new log message via the message broker
`debug()` sends a log message of type 'debug' via the message broker
`toast()` sends a log message of type 'toast' via the message broker
### authentication.py

### Basic Commands

wait()
e_stop()
unlock()
reboot()
shutdown()

### Movement

move()
set_home()
find_home()
axis_length()

### Peripherals

control_peripheral()
toggle_peripheral()
on()
off()

### Broker Commands

calibrate_camera()
control_servo()
take_photo()
soil_height()
detect_weeds()

## 🧰 Developer Info

### api_connect.py
Background: https://developer.farm.bot/v15/docs/web-app/rest-api

Formatting: functions in `api_functions.py` and `main.py` which interact with the API require an endpoint, which is truncated onto the HTTP request.

List of endpoints: https://developer.farm.bot/v15/docs/web-app/api-docs
> [!CAUTION]
> Store your authorization token securely. It grants full access and control over your FarmBot and your FarmBot Web App account.
| class `Authentication()` | Description |
| :--- | :--- |
| `get_token()` | Get FarmBot authorization token. Server is "https://my.farm.bot" by default. |
| `check_token()` | Ensure the token persists throughout sidecar. |
| `request_handling()` | Handle errors associated with different endpoint errors. |
| `request()` | Make requests to API endpoints using different methods. |

### basic_commands.py

| class `BasicCommands()` | Description |
| :--- | :--- |
| `wait()` | Pauses execution for a certain number of milliseconds. |
| `e_stop()` | Emergency locks (E-stops) the Farmduino microcontroller and resets peripheral pins to OFF. |
| `unlock()` | Unlocks a locked (E-stopped) device. |
| `reboot()` | Reboots the FarmBot OS and reinitializes the device. |
| `shutdown()` | Shuts down the FarmBot OS, turning the device off. |

### broker.py

| class `BrokerConnect()` | Description |
| :--- | :--- |
| `connect()` | Establish persistent connection to send messages via message broker. |
| `disconnect()` | Disconnect from the message broker. |
| `publish()` | Publish messages containing CeleryScript via the message broker. |
| `on_connect()` | Callback function triggered when a connection to the message broker is successfully established. |
| `on_message()` | Callback function triggered when a message is received from the message broker. |
| `start_listen()` | Establish persistent subscription to message broker channels. |
| `stop_listen()` | End subscription to all message broker channels. |

### camera.py

| class `Camera()` | Description |
| :--- | :--- |
| `calibrate_camera()` | Performs camera calibration. This action will reset camera calibration settings. |
| `take_photo()` | Takes a photo using the device camera and uploads it to the web app. |
<!--- | `photo_grid()` | Returns metadata object about point grid required to perform a scan of the full garden. | --->

### information.py

> [!CAUTION]
> Making requests other than GET to the API will permanently alter the data in your account. DELETE and POST requests may destroy data that cannot be recovered. Altering data through the API may cause account instability.
> Making requests other than `GET` to the API will permanently alter the data in your account. `DELETE` and `POST` requests may destroy data that cannot be recovered. Altering data through the API may cause account instability.
> [!NOTE]
> Not sure which endpoint to access? [Find the list here](https://developer.farm.bot/v15/docs/web-app/api-docs).
| class `Information()` | Description |
| :--- | :--- |
| `get_info()` | Get information about a specific endpoint. |
| `set_info()` | Change information contained within an endpoint. |
| `safe_z()` | Returns the highest safe point along the z-axis. |
| `garden_size()` | Returns x-axis length, y-axis length, and area of garden bed. |
| `group()` | Returns all group info or single by id. |
| `curve()` | Returns all curve info or single by id. |
| `soil_height()` | Use the camera to determine soil height at the current location. |
| `read_status()` | Returns the FarmBot status tree. |
| `read_sensor()` | Reads the given pin by id. |

### jobs.py

| class `JobHandling()` | Description |
| :--- | :--- |
| `get_job()` | Retrieves the status or details of the specified job. |
| `set_job()` | Initiates or modifies job with given parameters. |
| `complete_job()` | Marks job as completed and triggers any associated actions. |

### messages.py

| class `MessageHandling()` | Description |
| :--- | :--- |
| `log()` | Sends new log message via the API. Requires the page to be refreshed before appearing. |
| `message()` | Sends new log message via the message broker. |
| `debug()` | Sends debug message used for developer information or troubleshooting. |
| `toast()` | Sends a message that pops up on the user interface briefly. |

### movements.py

| class `MovementControls()` | Description |
| :--- | :--- |
| `move()` | Moves to the specified (x, y, z) coordinate. |
| `set_home()` | Sets the current position as the home position for a specific axis. |
| `find_home()` | Moves the device to the home position for a specified axis. |
| `axis_length()` | Returns the length of a specified axis. |
| `get_xyz()` | Returns the current (x, y, z) coordinates of the FarmBot. |
| `check_position()` | Verifies position of the FarmBot within specified tolerance range. |

### peripherals.py

| class `Peripherals()` | Description |
| :--- | :--- |
| `control_servo()` | Set servo angle between 0-100 degrees. |
| `control_peripheral()` | Set peripheral value (ON/OFF or slider value from 0-255) and mode (digital or analog). |
| `toggle_peripheral()` | Toggles the state of a specific peripheral between 'on' (100%) and 'off' (0%). |
| `on()` | Turns specified peripheral 'on' (100%). |
| `off()` | Turns specified peripheral 'off' (0%). |

### resources.py

| class `Resources()` | Description |
| :--- | :--- |
| `mark_coord()` | Marks (x, y, z) coordinate with specified label. |
| `sequence()` | Executes a predefined sequence. |
| `get_seed_tray_cell()` | Identifies and returns the location of specified cell in the seed tray. |
| `detect_weeds()` | Scans the garden to detect weeds. |
| `lua()` | Executes custom Lua code snippets to perform complex tasks or automations. |
| `if_statement()` | Performs conditional check and executes actions based on the outcome. |
| `assertion()` | Evaluates an expression. |
<!--- | `sort_points()` | Sorts list of points (e.g., plants, weeds) based on specified criteria. | --->

### tools.py

| class `ToolControls()` | Description |
| :--- | :--- |
| `mount_tool()` | Mounts the given tool and pulls it out of assigned slot. |
| `dismount_tool()` | Dismounts the currently mounted tool into assigned slot. |
| `water()` | Moves to and waters plant based on age and assigned watering curve. |
| `dispense()` | Dispenses user-defined amount of liquid in milliliters. |
<!--- | `verify_tool()` | Verifies if tool is mounted to UTM via tool verification pin and MOUNTED TOOL field in FarmBot’s state tree. | --->

## :toolbox: Developer Info

### Formatting message broker messages

### broker_connect.py
Background: https://developer.farm.bot/v15/docs/message-broker
> [!NOTE]
> Messages sent via the message broker contain [CeleryScript nodes](https://developer.farm.bot/v15/docs/celery-script/nodes.html) which require special formatting.
Formatting: functions in `broker_functions.py` and `main.py` which interact with the message broker send a message containing CeleryScript. The messages require the pre-formatted `RPC_request` included in `broker_functions.py` as the first line of the message.
```
message = {
"kind": "rpc_request",
"args": {
"label": # node,
"priority": # number
},
"body": [
{
# instructions
}
]
}
```
3 changes: 3 additions & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
Initialization for main module.
"""
Loading

0 comments on commit 636234d

Please sign in to comment.