Skip to main content

Overview

Industry: Facilities Management A smart office system where the AI agent acts as a facilities concierge. It checks meeting room availability, adjusts climate controls, monitors desk occupancy, and sends notifications to office displays. Commands:
  • check_meeting_rooms — Query occupancy sensors in all meeting rooms
  • adjust_thermostat — Set target temperature for a zone
  • desk_occupancy — Get desk utilization for a floor
  • send_notification — Display a message on an office screen

Device Client (Node.js)

import { DeviceClient } from '@lua-ai/device-client';

// Simulated office hardware
const meetingRooms = [
  { name: 'Atlas', floor: 3, capacity: 8, occupied: true, bookedUntil: '14:30' },
  { name: 'Everest', floor: 3, capacity: 12, occupied: false, bookedUntil: null },
  { name: 'Summit', floor: 4, capacity: 6, occupied: true, bookedUntil: '15:00' },
  { name: 'Pinnacle', floor: 4, capacity: 20, occupied: false, bookedUntil: null },
];

const zones: Record<string, { currentTemp: number; targetTemp: number; mode: string }> = {
  'floor-3': { currentTemp: 23.2, targetTemp: 22, mode: 'cooling' },
  'floor-4': { currentTemp: 21.8, targetTemp: 22, mode: 'idle' },
};

const desks: Record<string, { total: number; occupied: number }> = {
  'floor-3': { total: 48, occupied: 31 },
  'floor-4': { total: 52, occupied: 18 },
};

const device = new DeviceClient({
  agentId: process.env.LUA_AGENT_ID!,
  apiKey: process.env.LUA_API_KEY!,
  deviceName: 'office-controller',
  group: 'building-systems',
  commands: [
    {
      name: 'check_meeting_rooms',
      description: 'Check availability and occupancy of all meeting rooms. Returns room name, floor, capacity, and whether currently occupied.',
      inputSchema: {
        type: 'object',
        properties: {
          floor: { type: 'number', description: 'Filter by floor number (optional)' },
          minCapacity: { type: 'number', description: 'Minimum room capacity (optional)' },
        },
      },
    },
    {
      name: 'adjust_thermostat',
      description: 'Adjust the target temperature for a building zone. Zones are identified by floor (e.g., floor-3, floor-4).',
      inputSchema: {
        type: 'object',
        properties: {
          zone: { type: 'string', description: 'Zone identifier (e.g., floor-3)' },
          targetTemperature: { type: 'number', minimum: 18, maximum: 28, description: 'Target temperature in celsius' },
        },
        required: ['zone', 'targetTemperature'],
      },
    },
    {
      name: 'desk_occupancy',
      description: 'Get desk occupancy statistics for a given floor. Returns total desks, occupied desks, and utilization percentage.',
      inputSchema: {
        type: 'object',
        properties: {
          floor: { type: 'number', description: 'Floor number to check' },
        },
        required: ['floor'],
      },
    },
    {
      name: 'send_notification',
      description: 'Display a notification message on the office lobby or floor display screens',
      inputSchema: {
        type: 'object',
        properties: {
          message: { type: 'string', description: 'Message text to display' },
          screen: { type: 'string', enum: ['lobby', 'floor-3', 'floor-4', 'all'], description: 'Target screen' },
          priority: { type: 'string', enum: ['info', 'warning', 'urgent'], default: 'info' },
        },
        required: ['message', 'screen'],
      },
    },
  ],
});

device.onCommand('check_meeting_rooms', async (payload) => {
  let rooms = meetingRooms;
  if (payload?.floor) {
    rooms = rooms.filter(r => r.floor === payload.floor);
  }
  if (payload?.minCapacity) {
    rooms = rooms.filter(r => r.capacity >= payload.minCapacity);
  }
  return {
    rooms: rooms.map(r => ({
      ...r,
      available: !r.occupied,
    })),
    timestamp: new Date().toISOString(),
  };
});

device.onCommand('adjust_thermostat', async (payload) => {
  const zone = zones[payload.zone];
  if (!zone) {
    throw new Error(`Unknown zone: ${payload.zone}`);
  }
  zone.targetTemp = payload.targetTemperature;
  zone.mode = zone.currentTemp > payload.targetTemperature ? 'cooling' : 'heating';
  return {
    zone: payload.zone,
    currentTemperature: zone.currentTemp,
    targetTemperature: zone.targetTemp,
    mode: zone.mode,
  };
});

device.onCommand('desk_occupancy', async (payload) => {
  const floorKey = `floor-${payload.floor}`;
  const floor = desks[floorKey];
  if (!floor) {
    throw new Error(`No data for floor ${payload.floor}`);
  }
  return {
    floor: payload.floor,
    totalDesks: floor.total,
    occupiedDesks: floor.occupied,
    availableDesks: floor.total - floor.occupied,
    utilization: Math.round((floor.occupied / floor.total) * 100),
  };
});

device.onCommand('send_notification', async (payload) => {
  console.log(`[DISPLAY ${payload.screen}] ${payload.priority?.toUpperCase() || 'INFO'}: ${payload.message}`);
  return {
    sent: true,
    screen: payload.screen,
    message: payload.message,
    timestamp: new Date().toISOString(),
  };
});

async function main() {
  await device.connect();
  console.log('Office controller online');
}

main().catch(console.error);

Agent Configuration

// src/index.ts
import { LuaAgent, LuaSkill } from 'lua-cli';

const facilitiesSkill = new LuaSkill({
  name: 'facilities-concierge',
  description: 'Smart office management',
  context: `
    You manage office facilities through connected devices.

    Device tools:
    - check_meeting_rooms: Use when someone needs a meeting room. Filter by floor or capacity.
    - adjust_thermostat: Use when someone reports temperature issues. Range: 18-28C.
    - desk_occupancy: Use to report floor utilization.
    - send_notification: Use to broadcast messages to office screens.

    Guidelines:
    - When someone needs a room, check availability and suggest the best match
    - For temperature complaints, check current temp first, then adjust
    - Only send urgent notifications for actual emergencies
    - Be friendly and helpful -- you are the office concierge
  `,
  tools: [],
});

export const agent = new LuaAgent({
  name: 'office-concierge',
  persona: `You are a friendly office concierge. You help employees find meeting rooms,
    manage comfort settings, and stay informed about office status. Be warm and helpful.`,
  skills: [facilitiesSkill],
});

Next Steps

Warehouse Scanner

Logistics and inventory management

Industrial Sensor

Factory monitoring on Pico W

Retail Kiosk

Customer-facing kiosk with NFC and receipts

Self-Describing Commands

How to write effective command definitions