otto

package module
v0.0.11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 1, 2025 License: Apache-2.0 Imports: 6 Imported by: 0

README

OttO - IoT Device Framework

OttO is a Go framework for building IoT applications with clean separation between hardware device interaction and messaging infrastructure. It provides a flexible, testable architecture for sensor stations, garden automation, and other IoT projects.

Recent Architectural Improvements ✨

🏗️ Clean Device/Messaging Architecture
  • Separation of Concerns: Device layer focuses purely on hardware interaction, Otto handles IoT messaging infrastructure
  • ManagedDevice Wrapper: Bridges any simple device with messaging capabilities (MQTT pub/sub, event handling)
  • Type-Safe Device Management: Re-enabled Station device management with proper interfaces
  • Reusable Components: Any device from the devices package can be easily wrapped with messaging
🌐 Flexible Messaging Options
  • Local Messaging: Internal pub/sub for testing and development (no external dependencies)
  • MQTT with Fallback: Attempts MQTT connection, gracefully falls back to local messaging
  • Public MQTT Support: Default integration with test.mosquitto.org for easy testing
  • Custom MQTT Brokers: Configurable broker URLs for production deployments
Production Ready Features
  • Mock Mode: Complete hardware abstraction for development and testing
  • Web Interface: Full-featured UI for monitoring and control
  • RESTful API: Standard HTTP endpoints for integration
  • Robust Error Handling: Graceful degradation when hardware/network unavailable

Quick Start

Development/Testing (Mock Mode)
# Local messaging, no hardware required
./your-app -mock -local

# MQTT with public test broker
./your-app -mock

# Custom MQTT broker
./your-app -mock -mqtt-broker your.broker.com
Hardware Deployment
# Production mode with real sensors
./your-app

# With custom MQTT broker
./your-app -mqtt-broker your.production.broker.com

Usage Examples

Garden Station Implementation

The garden-station project demonstrates the full architecture:

  • Sensors: BME280 (temperature/humidity/pressure), VH400 (soil moisture)
  • Actuators: Water pump, LED indicators, OLED display
  • Controls: Physical buttons for manual override
  • Automation: Automatic watering based on soil moisture thresholds
  • Web UI: Real-time monitoring and manual controls at http://localhost:8011
Command Line Options
  • -mock: Enable hardware mocking for development
  • -local: Force local messaging (no MQTT)
  • -mqtt-broker string: Custom MQTT broker address

Architecture Overview

Device Layer (devices package)
// Simple, focused device interfaces
type Device[T any] interface {
    ID() string
    Type() Type
    Open() error
    Close() error
    Get() (T, error)
    Set(v T) error
}
Messaging Layer (otto package)
// ManagedDevice wraps devices with messaging
type ManagedDevice struct {
    Name   string
    Device any
    Topic  string
    messanger.Messanger
}

Messaging Infrastructure

MQTT Broker
  • Run MQTT broker, e.g. mosquitto

  • Base topic "ss//data/"

Example: ss/00:95:fb:3f:34:95/data/tempc 25.00

Web Sockets

We sockets or HTTP/2 will be used to send data to and from the IOTe device (otto) in our case.

Subscribe to Topics
  • announce/station - announces stations that control or collect

  • announce/hub - announces hubs, typ

  • data/tempc/ - data can have option /index at the end

  • data/humidity

  • control/relay/idx - control can have option /index at the end

REST API

  • GET /api/config

  • PUT /api/config data => { config: id, ... }

  • GET /api/data

  • GET /api/stations

Station Manager

  • Collection of stations
  • Stations can age out
Stations
  • ID (name, IP and mac address)
  • Capabilities
    • sensors
    • relay

Data

Data can be optimized and we expect we will want to optimize different data for all kinds of reasons and we won't preclude that from happening, we'll give applications the flexibility to handle data elements as they see fit (can optimize).

We will take an memory expensive approach, every data point can be handled on it's own. The data structure will be:

struct Data
    Source ID
    Type
    Timestamp
    Value

User Interface

Build

Download Pre-built Binaries

The easiest way to get started is to download a pre-built binary for your platform from the Releases page.

Available platforms:

  • Linux x86_64
  • Linux ARM (Raspberry Pi)
  • Linux ARM64 (Raspberry Pi 4+)
  • macOS (Intel and Apple Silicon)
  • Windows

Build from Source

  1. Install Go 1.23 or later
  2. Clone the repository: git clone https://github.com/rustyeddy/otto
  3. Build: cd otto && make build

This will create the otto binary in the current directory.

Build Commands
make build      # Build otto binary
make test       # Run tests
make fmt        # Format code
make ci         # Run full CI checks (fmt, vet, test, build)

See CI/CD Documentation for more details on building for specific platforms.

Deploy

  1. Install and run an MQTT broker on the sensors host (e.g. mosquitto).

  2. Start the sensors program ensuring the sensor station has connected to a wifi network.

  3. Put batteries in sensors and let the network build itself.

Testing & Development

Mock Mode Testing
# Complete hardware abstraction - no GPIO/I2C devices needed
./garden-station -mock -local

# Test with public MQTT broker
./garden-station -mock

# Web interface available at http://localhost:8011
curl http://localhost:8011/
Integration Testing
  • Local Messaging: Zero external dependencies, instant startup
  • MQTT Testing: Uses test.mosquitto.org by default
  • Device Mocking: All hardware interactions simulated
  • Web UI Testing: Full-featured interface for manual testing

Current Status ✅

Completed Features:
  • Clean device/messaging architecture implemented
  • ManagedDevice wrapper for any device type
  • Flexible messaging (local + MQTT with fallback)
  • Complete hardware mocking support
  • Web interface fully functional
  • MQTT connectivity with public/custom brokers
  • Type-safe device management
  • Garden station reference implementation
🚀 Ready For:
  1. Hardware Deployment: Remove -mock flag and connect real sensors
  2. Production MQTT: Connect to existing MQTT infrastructure
  3. Custom Applications: Use as framework for new IoT projects
  4. Scaling: Add more device types and stations
📊 Testing Results:
  • Mock mode: ✅ All GPIO/I2C errors eliminated
  • Web interface: ✅ Full garden station UI functional
  • MQTT connectivity: ✅ Successfully connects to test.mosquitto.org
  • Local messaging: ✅ Clean fallback when MQTT unavailable
  • Device abstraction: ✅ Hardware interactions properly mocked

Building & Deployment

Prerequisites
  • Go 1.21+
  • For hardware: Linux with GPIO/I2C support (Raspberry Pi recommended)
Build
git clone https://github.com/rustyeddy/otto
cd otto
go mod tidy
go build ./...
Deploy
# Development
./your-app -mock -local

# Production  
./your-app -mqtt-broker your.broker.com

Documentation

Overview

OttO is a set of Go packages (framework) that help build IoT applications. The goal is to decouple the IoT sensors, actuators, etc. from the framework hardware interfaces such as GPIO, I2C, serial ports, etc.

Features include

Device level abstraction. Each device has a name that translates into a path that can be used by MQTT and HTTP REST interface for communication with other systems.

Device manager that keeps track of all application devices, configuration and status. This interface attempts to be agnostic to the underlying drivers, including gpiocdev, I2C, periph.io, etc.

Message based architecture abstracting all communications into a standard message format. With functionality that can save messages for later replay or diagnostics.

MQTT messaging built into all devices and components according to functionality and need

HTTP Rest interface and corresponding API for all components of the framework.

Drivers for a few different breakout boards meant to run on the Raspberry Pi.

Station module to represent a single application on a given device or a series of stations for a networked controller.

Messanger (not to be confused with messages) implements a Pub/Sub (MQTT or other) interface between components of your application

HTTP REST Server for data gathering and configuration

Websockets for realtime bidirectional communication with a UI

High performance Web server built in to serve interactive UI's and modern API's

Station manager to manage the stations that make up an entire sensor network

Data Manager for temporary data caching and interfaces to update your favorite cloud based timeseries database

Message library for standardized messages built to be communicate events and information between pacakges.

The primary communication model for OttO is a messaging system based on the Pub/Sub model defaulting to MQTT. oTTo is also heavily invested in HTTP to implement user interfaces and REST/Graph APIs.

Messaging and HTTP use paths to specify the subject of interest. These paths can be generically reduced to an ordered collection of strings seperated by slashes '/'. Both MQTT topics, http URI's and UNIX filesystems use this same schema which we use the generalize the identity of the elements we are addressing.

In other words we can generalize the following identities:

For example:

    File: /home/rusty/data/hb/temperature
	HTTP: /api/data/hb/temperature
	MQTT: ss/station/hb/temperature

The data within the highest level topic temperature can be represented say by JSON `{ farenhiet: 100.07 }`

### Meta Data (Station Information)

For example when a station comes alive it can provide some information about itself using the topic:

```ss/m/be:ef:ca:fe:02/station```

The station will announce itself along with some meta information and it's capabilities. The body of the message might look something like this:

```json

{
	"id": "be:ef:ca:fe:02",
	"ip": "10.11.24.24",
    "sensors": [
		"tempc",
		"humidity",
		"light"
	],
	"relays": [
		"heater",
		"light"
	],
}

```

### Sensor Data

Sensor data takes on the form:

```ss/d/<station>/<sensor>/<index>```

Where the source is the Station ID publishing the respective data. The sensor is the type of data being produced (temp, humidity, lidar, GPS).

The index is useful in application where there is more than one device, such as sensors, motors, etc.

The value published by the sensors is typically going to be floating point, however these values may also be integers, strings or byte arrays.

### Control Data

```ss/c/<source>/<device>/<index>```

This is essentially the same as the sensor except that control commands are used to have a particular device change, for example turning a relay on or off.

Index

Constants

This section is empty.

Variables

View Source
var (
	Version     string
	Interactive bool
)

global variables and structures

Functions

This section is empty.

Types

type Config added in v0.0.11

type Config struct {
	messanger.Config
}

type Controller

type Controller interface {
	Init()
	Start() error
	Stop()
	MsgHandler(m *messanger.Msg)
}

Controller is a message handler that oversees all interactions with the application.

type OttO

type OttO struct {
	Name string

	*station.Station
	*station.StationManager
	*server.Server
	messanger.Messanger

	Mock       bool
	MQTTBroker string // MQTT broker URL, defaults to test.mosquitto.org
	UseLocal   bool   // Force use of local messaging
	// contains filtered or unexported fields
}

OttO is a large wrapper around the Station, Server, DataManager and Messanger, including some convenience functions.

func (*OttO) AddManagedDevice added in v0.0.10

func (o *OttO) AddManagedDevice(name string, device any, topic string) *station.ManagedDevice

AddManagedDevice creates a managed device wrapper and adds it to the station

func (*OttO) Done

func (o *OttO) Done() chan any

func (*OttO) GetManagedDevice added in v0.0.10

func (o *OttO) GetManagedDevice(name string) *station.ManagedDevice

GetManagedDevice retrieves a managed device by name

func (*OttO) Init

func (o *OttO) Init()

OttO is a convinience function starting the MQTT and HTTP servers, the station manager and other stuff.

func (*OttO) Start

func (o *OttO) Start()

func (*OttO) Stop

func (o *OttO) Stop()

Directories

Path Synopsis
cmd
otto command
Demo program showing the new flexible logging configuration
Demo program showing the new flexible logging configuration
Package messanger provides a unified interface for publish-subscribe messaging in the Otto IoT framework.
Package messanger provides a unified interface for publish-subscribe messaging in the Otto IoT framework.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL