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.
- 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
devicespackage can be easily wrapped with messaging
- 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.orgfor easy testing - Custom MQTT Brokers: Configurable broker URLs for production deployments
- 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
# 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# Production mode with real sensors
./your-app
# With custom MQTT broker
./your-app -mqtt-broker your.production.broker.comThe 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
-mock: Enable hardware mocking for development-local: Force local messaging (no MQTT)-mqtt-broker string: Custom MQTT broker address
// Simple, focused device interfaces
type Device[T any] interface {
ID() string
Type() Type
Open() error
Close() error
Get() (T, error)
Set(v T) error
}// ManagedDevice wraps devices with messaging
type ManagedDevice struct {
Name string
Device any
Topic string
messanger.Messanger
}-
Run MQTT broker, e.g. mosquitto
-
Base topic "ss//data/"
Example: ss/00:95:fb:3f:34:95/data/tempc 25.00
We sockets or HTTP/2 will be used to send data to and from the IOTe device (otto) in our case.
-
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
-
GET /api/config
-
PUT /api/config data => { config: id, ... }
-
GET /api/data
-
GET /api/stations
- Collection of stations
- Stations can age out
- ID (name, IP and mac address)
- Capabilities
- sensors
- relay
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
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
- Install Go 1.23 or later
- Clone the repository:
git clone https://github.com/rustyeddy/otto - Build:
cd otto && make build
This will create the otto binary in the current directory.
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.
-
Install and run an MQTT broker on the sensors host (e.g. mosquitto).
-
Start the sensors program ensuring the sensor station has connected to a wifi network.
-
Put batteries in sensors and let the network build itself.
# 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/- Local Messaging: Zero external dependencies, instant startup
- MQTT Testing: Uses
test.mosquitto.orgby default - Device Mocking: All hardware interactions simulated
- Web UI Testing: Full-featured interface for manual testing
- 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
- Hardware Deployment: Remove
-mockflag and connect real sensors - Production MQTT: Connect to existing MQTT infrastructure
- Custom Applications: Use as framework for new IoT projects
- Scaling: Add more device types and stations
- 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
- Go 1.21+
- For hardware: Linux with GPIO/I2C support (Raspberry Pi recommended)
git clone https://github.com/rustyeddy/otto
cd otto
go mod tidy
go build ./...# Development
./your-app -mock -local
# Production
./your-app -mqtt-broker your.broker.com