UI framework

This commit is contained in:
Mikkeli Matlock
2026-01-24 12:24:26 +09:00
parent 2f5894cda8
commit 0d9c5eb359
8 changed files with 291 additions and 0 deletions

10
arduino/hello.ino Normal file
View File

@@ -0,0 +1,10 @@
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(10);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}

63
pi/ui/lib/main.dart Normal file
View File

@@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
void main() {
runApp(const SmartSerowApp());
}
class SmartSerowApp extends StatelessWidget {
const SmartSerowApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Smart Serow',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.teal,
brightness: Brightness.dark,
),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.terrain,
size: 120,
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(height: 24),
Text(
'Smart Serow',
style: Theme.of(context).textTheme.headlineLarge?.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(
'System Ready',
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Colors.grey,
),
),
],
),
),
);
}
}

19
pi/ui/pubspec.yaml Normal file
View File

@@ -0,0 +1,19 @@
name: smartserow_ui
description: Smart Serow embedded UI for Raspberry Pi Zero 2W
publish_to: 'none'
version: 0.1.0
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^3.0.0
flutter:
uses-material-design: true

35
scripts/build.sh Normal file
View File

@@ -0,0 +1,35 @@
#!/bin/bash
# Build script for Smart Serow Flutter UI
# Run this in WSL2 with flutter-elinux installed
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
UI_DIR="$PROJECT_ROOT/pi/ui"
echo "=== Smart Serow Build ==="
echo "Project: $UI_DIR"
cd "$UI_DIR"
# Clean previous build (optional, comment out for faster incremental builds)
# flutter-elinux clean
echo "Fetching dependencies..."
flutter-elinux pub get
echo "Building for ARM64 (elinux)..."
flutter-elinux build elinux --target-arch=arm64 --release
BUILD_OUTPUT="$UI_DIR/build/elinux/arm64/release/bundle"
if [ -d "$BUILD_OUTPUT" ]; then
echo ""
echo "=== Build Complete ==="
echo "Output: $BUILD_OUTPUT"
ls -lh "$BUILD_OUTPUT"
else
echo "ERROR: Build output not found at $BUILD_OUTPUT"
exit 1
fi

53
scripts/deploy.sh Normal file
View File

@@ -0,0 +1,53 @@
#!/bin/bash
# Deploy script for Smart Serow Flutter UI
# Pushes build bundle to Pi and optionally restarts service
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
CONFIG_FILE="$SCRIPT_DIR/deploy_target.json"
# Parse config
if [ ! -f "$CONFIG_FILE" ]; then
echo "ERROR: Config file not found: $CONFIG_FILE"
exit 1
fi
HOST=$(jq -r '.host' "$CONFIG_FILE")
REMOTE_PATH=$(jq -r '.remote_path' "$CONFIG_FILE")
SERVICE_NAME=$(jq -r '.service_name' "$CONFIG_FILE")
BUILD_DIR="$PROJECT_ROOT/pi/ui/build/elinux/arm64/release/bundle"
echo "=== Smart Serow Deploy ==="
echo "Target: $HOST:$REMOTE_PATH"
echo "Source: $BUILD_DIR"
if [ ! -d "$BUILD_DIR" ]; then
echo "ERROR: Build directory not found. Run build.sh first."
exit 1
fi
# Sync build to Pi
echo ""
echo "Syncing files..."
rsync -avz --delete \
"$BUILD_DIR/" \
"$HOST:$REMOTE_PATH/bundle/"
# Restart service if requested
RESTART="${1:-}"
if [ "$RESTART" = "--restart" ] || [ "$RESTART" = "-r" ]; then
echo ""
echo "Restarting service: $SERVICE_NAME"
ssh "$HOST" "sudo systemctl restart $SERVICE_NAME"
sleep 2
ssh "$HOST" "systemctl status $SERVICE_NAME --no-pager"
else
echo ""
echo "Deploy complete. To restart service, run:"
echo " ssh $HOST 'sudo systemctl restart $SERVICE_NAME'"
echo ""
echo "Or run this script with --restart flag"
fi

View File

@@ -0,0 +1,5 @@
{
"host": "pi@smartserow.local",
"remote_path": "/opt/smartserow",
"service_name": "smartserow-ui"
}

76
scripts/pi_setup.sh Normal file
View File

@@ -0,0 +1,76 @@
#!/bin/bash
# One-time setup script for Smart Serow on Raspberry Pi
# Run this ON the Pi itself
set -e
echo "=== Smart Serow Pi Setup ==="
# Check if running on Pi (arm architecture)
ARCH=$(uname -m)
if [[ "$ARCH" != "aarch64" && "$ARCH" != "armv7l" ]]; then
echo "WARNING: This doesn't look like a Pi (arch: $ARCH)"
echo "Continuing anyway..."
fi
APP_DIR="/opt/smartserow"
SERVICE_FILE="/etc/systemd/system/smartserow-ui.service"
# Create app directory
echo "Creating app directory: $APP_DIR"
sudo mkdir -p "$APP_DIR/bundle"
sudo chown -R pi:pi "$APP_DIR"
# Install runtime dependencies for flutter-elinux
echo "Installing runtime dependencies..."
sudo apt-get update
sudo apt-get install -y \
libgl1-mesa-dri \
libgles2-mesa \
libegl1-mesa \
libdrm2 \
libgbm1 \
libinput10 \
libudev1 \
fonts-noto
# For X11 debug mode (optional but useful)
sudo apt-get install -y \
xorg \
xinit \
libx11-6 \
libxkbcommon-x11-0
# Copy systemd service
echo "Installing systemd service..."
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -f "$SCRIPT_DIR/smartserow-ui.service" ]; then
sudo cp "$SCRIPT_DIR/smartserow-ui.service" "$SERVICE_FILE"
else
echo "WARNING: Service file not found at $SCRIPT_DIR/smartserow-ui.service"
echo "Copy it manually to $SERVICE_FILE"
fi
# Enable service
echo "Enabling service..."
sudo systemctl daemon-reload
sudo systemctl enable smartserow-ui
# Add pi user to required groups for DRM/KMS access
echo "Setting up permissions..."
sudo usermod -aG video pi
sudo usermod -aG input pi
sudo usermod -aG render pi 2>/dev/null || true
echo ""
echo "=== Setup Complete ==="
echo ""
echo "Next steps:"
echo "1. Deploy the app: run deploy.sh from your dev machine"
echo "2. Start service: sudo systemctl start smartserow-ui"
echo "3. Or reboot: sudo reboot"
echo ""
echo "Useful commands:"
echo " systemctl status smartserow-ui # Check status"
echo " journalctl -u smartserow-ui -f # View logs"
echo ""

View File

@@ -0,0 +1,30 @@
[Unit]
Description=Smart Serow UI
After=multi-user.target
Wants=multi-user.target
[Service]
Type=simple
User=pi
Group=pi
WorkingDirectory=/opt/smartserow/bundle
# DRM/KMS backend for direct framebuffer (no X11 needed)
ExecStart=/opt/smartserow/bundle/smartserow_ui -b drm
# Restart on crash
Restart=always
RestartSec=3
# Environment for DRM/KMS access
Environment=XDG_RUNTIME_DIR=/run/user/1000
Environment=HOME=/home/pi
# Give time for GPU to initialize on boot
ExecStartPre=/bin/sleep 2
# Ensure clean shutdown
TimeoutStopSec=10
[Install]
WantedBy=multi-user.target