Overview
Industry: Manufacturing A factory floor monitoring system running on a Raspberry Pi Pico W. The device reads vibration and temperature sensors, provides an emergency stop command, and fires triggers when anomalies are detected. Commands:read_vibration— Read vibration amplitude from an accelerometerread_temperature— Read bearing temperatureemergency_stop— Trigger the emergency stop relay
vibration_anomaly— Fires when vibration exceeds safe threshold
Device Client (MicroPython)
import network
import machine
import time
# -- WiFi --
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("FACTORY_WIFI", "secure_password_here")
while not wlan.isconnected():
time.sleep(0.5)
print("WiFi connected:", wlan.ifconfig()[0])
# -- Hardware setup --
# Onboard LED for status indication
status_led = machine.Pin("LED", machine.Pin.OUT)
# ADC for vibration sensor (analog accelerometer on GP26)
vibration_adc = machine.ADC(machine.Pin(26))
# DS18B20 or analog temp sensor on GP27
temp_adc = machine.ADC(machine.Pin(27))
# Emergency stop relay on GP16
estop_relay = machine.Pin(16, machine.Pin.OUT, value=0)
# -- Device --
from lua_device import LuaDevice
device = LuaDevice(
agent_id="your-agent-id",
api_key="your-api-key",
device_name="cnc-monitor-01",
server="mqtt.heylua.ai",
group="factory-floor",
)
@device.command("read_vibration")
def read_vibration(payload):
# Read ADC value and convert to g-force (simplified)
raw = vibration_adc.read_u16()
amplitude_g = (raw / 65535.0) * 4.0 # 0-4g range
return {
"amplitude_g": round(amplitude_g, 3),
"raw_adc": raw,
"status": "warning" if amplitude_g > 2.5 else "normal",
}
@device.command("read_temperature")
def read_temperature(payload):
raw = temp_adc.read_u16()
# Convert to celsius (simplified linear conversion)
temp_c = (raw / 65535.0) * 150.0 # 0-150C range for bearing temp
return {
"temperature": round(temp_c, 1),
"unit": "celsius",
"status": "critical" if temp_c > 80 else "warning" if temp_c > 60 else "normal",
}
@device.command("emergency_stop")
def emergency_stop(payload):
estop_relay.on() # Activate relay (normally open -> closed)
status_led.on() # Visual indicator
reason = payload.get("reason", "manual trigger")
print("[ESTOP] Emergency stop activated:", reason)
return {
"activated": True,
"reason": reason,
"timestamp": str(time.time()),
}
# -- Connect and run --
device.connect()
status_led.on() # LED on = connected
print("Factory monitor online")
# -- Main loop with anomaly detection --
VIBRATION_THRESHOLD = 3.0 # g-force
last_check = time.time()
check_interval = 10 # seconds
while True:
try:
device._client.check_msg()
now = time.time()
# Heartbeat
if now - device._last_heartbeat >= device._heartbeat_interval:
device._client.publish(device._topic_prefix + "heartbeat", b"", qos=0)
device._last_heartbeat = now
# Periodic vibration check
if now - last_check >= check_interval:
raw = vibration_adc.read_u16()
amplitude = (raw / 65535.0) * 4.0
if amplitude > VIBRATION_THRESHOLD:
device.trigger("vibration_anomaly", {
"amplitude_g": round(amplitude, 3),
"threshold_g": VIBRATION_THRESHOLD,
"machine": "CNC-Mill-04",
"location": "bay-3",
})
# Blink LED rapidly to indicate alert
for _ in range(5):
status_led.toggle()
time.sleep_ms(100)
status_led.on()
last_check = now
# Clean dedup cache
if len(device._seen_ids) > 100:
device._clean_dedup()
time.sleep_ms(100)
except OSError as e:
print("Connection lost:", e)
status_led.off()
device._reconnect()
status_led.on()
except Exception as e:
print("Error:", e)
time.sleep(1)
Agent-Side Trigger Handler
// src/triggers/vibration-anomaly.ts
import { defineDeviceTrigger } from 'lua-cli';
import { z } from 'zod';
export const vibrationAnomaly = defineDeviceTrigger({
name: 'vibration-anomaly',
description: 'Fired when a factory machine vibration reading exceeds the safe threshold',
payloadSchema: z.object({
amplitude_g: z.number(),
threshold_g: z.number(),
machine: z.string(),
location: z.string(),
}),
execute: async (payload, { agent, device }) => {
const severity = payload.amplitude_g > payload.threshold_g * 1.5 ? 'CRITICAL' : 'WARNING';
await agent.chat(
`${severity} VIBRATION ALERT from ${device.name}: ` +
`Machine "${payload.machine}" in ${payload.location} ` +
`reading ${payload.amplitude_g}g (threshold: ${payload.threshold_g}g). ` +
(severity === 'CRITICAL'
? 'This is significantly above threshold. Consider activating emergency stop.'
: 'Monitor closely and schedule maintenance if readings persist.')
);
},
});
Agent Configuration
// src/index.ts
import { LuaAgent, LuaSkill } from 'lua-cli';
import { vibrationAnomaly } from './triggers/vibration-anomaly';
const factorySkill = new LuaSkill({
name: 'factory-monitoring',
description: 'Industrial equipment monitoring and control',
context: `
You monitor factory equipment through connected sensors.
Device tools:
- read_vibration: Check machine vibration levels. Normal < 2.5g, warning < 3.0g, critical > 3.0g.
- read_temperature: Check bearing temperature. Normal < 60C, warning < 80C, critical > 80C.
- emergency_stop: CRITICAL COMMAND. Only use when explicitly requested or when readings indicate
imminent equipment failure. Always confirm with the operator first unless automated shutdown
is triggered.
When receiving vibration anomaly triggers:
1. Read the current vibration and temperature
2. Assess combined risk
3. Recommend maintenance or emergency stop based on severity
`,
tools: [],
});
export const agent = new LuaAgent({
name: 'factory-monitor',
persona: `You are a factory floor monitoring assistant. You help operators keep equipment
running safely. Be precise with readings. Escalate critical situations immediately.
Never hesitate to recommend an emergency stop if readings indicate danger.`,
skills: [factorySkill],
deviceTriggers: [vibrationAnomaly],
});
Next Steps
Pico W Setup
Step-by-step hardware setup guide
MicroPython Client
Full MicroPython client reference
Warehouse Scanner
Node.js logistics example
Triggers
How triggers flow from device to agent

