Metadata-Version: 2.4
Name: labrat_project
Version: 0.5.1
Summary: 
License-File: LICENSE
Author: Mike Parkes
Author-email: michael.parkes@ucl.ac.uk
Requires-Python: >=3.12
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: flask (==3.1.2)
Requires-Dist: flask-wtf (>=1.2.2,<2.0.0)
Requires-Dist: jsonschema (>=4.26.0,<5.0.0)
Requires-Dist: paho-mqtt (==2.1.0)
Requires-Dist: pillow (>=12.2.0,<13.0.0)
Requires-Dist: pyserial (==3.5)
Requires-Dist: toml (==0.10.2)
Description-Content-Type: text/markdown

# 🐀 Labrat Sensor Logger

Connect sensors and log data to a database, file, or both.

Current connection modes available:

| Connection          | Description                        |
|---------------|------------------------------------|
| `MQTT`        | Subscribe to an MQTT broker        |
| `serial`      | Read from a wired serial port      |
| `http`       | Receive data via a Flask API       |

## Table of Contents

- [Quick Start](#quick-start)
- [All Options](#all-options)
- [Setup & First Run](#setup--first-run)
  - [1. Create a Secrets File](#1-create-a-secrets-file)
  - [2. Set Up Database Contents](#2-set-up-a-database)
  - [3. Run](#3-run)
- [Running as a Daemon](#running-as-a-daemon)

---

## Quick Start

Not sure where to begin? [Create a Secrets File](#1-create-a-secrets-file).
The minimum secrets file is:

```toml
[CONNECTIONS]

   [CONNECTIONS.FLASK]
   "KEY" = "" # this can be filled with anything for this step.
       [CONNECTIONS.FLASK.SETUP]
       "ROUTE" = "/setup"
```
  then run the setup wizard.
```bash
python labrat_log.py -secrets "mypath/secrets.toml" -quick_start
```
This will open a browser window in which you can give a name for the database and add inator devices
---
## All Options

```
usage: labrat_log.py [-h] [-sql SQL] [-secrets SECRETS] [-quick_start]
```

| Flag                  | Description                                                                 |
|-----------------------|-----------------------------------------------------------------------------|
| `-secrets SECRETS`    | Path to the TOML secrets file (logins, broker details, etc.)                |
| `-quick_start`        | Run the quick start wizard 🧙     |


---

## Setup & First Run

### 1. Create a Secrets File

Create a `.toml` file with your credentials and connection details:
This has the following main sections which have their own sub-sections
```toml
[LOGGING] # Options to control logging
[CONNECTIONS] # Options to control the connections
```
These sections are then further broken up
```toml
[LOGGING]
    [LOGGING.SQLITE] # Settings for logging to SQLite database 
    "FILE" = "" # The path to sql database file
    "CREATE" = false # Whether to create the DB or not (true for quick set up)

    [LOGGING.FILE]  # Settings for logging to a text file
    "FILE" = "" # Path for the file
    "CREATE" = false # Whether to create the file or append

    [LOGGING.ELN] #Settings for connecting to an Electronic Laboratory notebook
    "NAME" = "RSpace" # Name of the ELN
    "KEY" = ""  # If required a key to logging to the ELN

[CONNECTIONS]
    [CONNECTIONS.MQTT] # MQTT connection details
        [CONNECTIONS.MQTT.NAME] # Details of a MQTT connection NAME should be changed and be unique
            "USERNAME" = "" # Any user names needed by broker
            "KEY" = ""  # Key needed to connect to broker
            "BROKER" = "" # Address of the broker
            "PORT" = 1883 # The port number of the broker, 8883 is traditional
            "TOPIC" = ""  # The Topic to subscribe to, adding # is normally useful
            "TLS" = true  # Whether the MQTT broker is using a TLS connection, i.e is encrypted. true or false
    
    [CONNECTIONS.SERIAL]  # Serial connection details
        [CONNECTIONS.SERIAL.NAME] # Details of a Serial connection NAME should be changed and be unique
            "PORT" = "" # The name of the serial port
            "BAUD" = "" # The baud rate for the port

   [CONNECTIONS.FLASK]  # Flask server connection details
   # Due to its nature Flask is treated differently to other connections, only one server per route
   "KEY" = "" # The key to connect to http logging
   "LOCAL_ON" = true  # Whether to run the routes through Flask, only safe on a local network
       [CONNECTIONS.FLASK.HTTP] # Route information for the HTTP server
       "ROUTE" = "/datalog" # The route to the HTTP logging server
   
       [CONNECTIONS.FLASK.DASH] # Route information for the display dashboard 
       "ROUTE" = "/dash"  # The route to the display dashboard

       [CONNECTIONS.FLASK.SETUP]  # Route information for the quick set up page
       "ROUTE" = "/setup" # The route to the quick setup page

```
All connections methods can run in parallel

### 2. Set Up Database Contents

<!-- If logging to SQLite, initialise the database with your device configuration:

```bash
# Create a new DB and load device info from a JSON file
python labrat_log.py -secrets "secrets.toml" -sql "/abs/path/to/data.db" \
    -setupsql --createdb --dev_file "/abs/path/to/devices.json" mqtt
```

> Omit `--createdb` if the database already exists. -->

Add devices to the database.

The device file must conform to the [Inator DB schema](https://inator-project.org/Protocols/pro_database.html).
This can be done using the quick start page

<details>
<summary><strong>Device file JSON schema</strong></summary>

```json
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "devices": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "device_name":     { "type": "string" },
          "device_guid":     { "type": "string" },
          "num_sensors":     { "type": "integer" },
          "device_info":     { "type": "string" },
          "device_type":     { "type": "string" },
          "device_location": { "type": "string" },
          "device_active":   { "type": "integer" },
          "connection": {
            "type": "string",
            "enum": ["Serial", "MQTT", "Other"]
          },
          "sensors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "sens_name": { "type": "string" },
                "measures":  { "type": "string" },
                "returns":   { "type": "string" },
                "calib":     { "type": "string" },
                "range":     { "type": "string" },
                "info":      { "type": "string" },
                "comments":  { "type": "string" }
              },
              "required": ["sens_name", "measures", "returns", "calib", "range", "info", "comments"]
            }
          }
        },
        "required": [
          "device_name", "device_guid", "num_sensors", "device_info",
          "device_type", "device_location", "device_active", "connection", "sensors"
        ]
      }
    }
  },
  "required": ["devices"]
}
```

</details>

### 3. Run

To run file in the options in the settings/secrets file for what you want to do
Then depending on your installationn method run using

```bash
python labrat_log.py -secrets path/to/secrets.toml
```
or
```bash
poetry run python labrat_log.py -secrets path/to/secrets.toml
```

---

## Running as a Daemon

Run the logger as a persistent background service using [Supervisor](http://supervisord.org/).

### 1. Install

```bash
sudo apt update && sudo apt install supervisor
```

### 2. Configure

Edit the provided `supervisord.conf` file, updating these fields:

| Field             | What to set                                                   |
|-------------------|---------------------------------------------------------------|
| `command=`        | Full command with all required paths and flags                |
| `user=`           | System user to run the process as                             |
| `stdout_logfile=` | Absolute path and filename for log output                     |
| `directory=`      | Working directory (home directory for MQTT)                   |

### 3. Start

```bash
supervisord -c /path/to/supervisord.conf
```

### 4. Monitor & Control

Use [`supervisorctl`](https://supervisord.org/running.html#running-supervisorctl) to manage the process:

```bash
supervisorctl status          # check if running
supervisorctl restart labrat  # restart the service
supervisorctl stop labrat     # stop the service
```
