LynxJS Workshop: สร้าง IoT Applications แบบมืออาชีพ
LynxJS Workshop: สร้าง IoT Applications แบบมืออาชีพ
ในบทความที่แล้ว เราได้เรียนรู้พื้นฐานของ LynxJS แล้ว ตอนนี้มาลองสร้าง IoT Application ที่ซับซ้อนขึ้นกัน! 🚀
🎯 สิ่งที่จะได้เรียนรู้
- 🔌 การต่อ Sensors หลายตัวพร้อมกัน
- 📊 การเก็บและจัดการข้อมูลแบบ real-time
- 🤖 การสร้าง automation rules
- 📱 การสร้าง Dashboard สำหรับ monitoring
🔌 Project: Smart Greenhouse Monitor
เราจะสร้างระบบ Smart Greenhouse Monitor ที่มี features:
- วัดอุณหภูมิและความชื้น
- วัดความชื้นในดิน
- วัดแสง
- ควบคุมระบบรดน้ำอัตโนมัติ
- แสดงผลบน Dashboard
Hardware ที่ต้องใช้
- Raspberry Pi หรือ ESP32
- DHT22 (Temperature & Humidity)
- Soil Moisture Sensor
- Light Sensor (LDR)
- Relay Module (สำหรับควบคุมปั้มน้ำ)
- LCD 16x2 หรือ OLED
📁 โครงสร้างโปรเจกต์
```text smart-greenhouse/ ├── src/ │ ├── sensors/ │ │ ├── dht22.ts │ │ ├── soil-moisture.ts │ │ └── light-sensor.ts │ ├── actuators/ │ │ └── water-pump.ts │ ├── controllers/ │ │ ├── greenhouse-controller.ts │ │ └── automation-rules.ts │ ├── api/ │ │ └── routes.ts │ └── main.ts ├── dashboard/ │ └── index.html ├── config/ │ └── sensors.json └── package.json ```
🔧 Implementation
1. Sensors Layer
```typescript // src/sensors/dht22.ts import { DHT22 } from ‘@lynxjs/sensors’;
export class TemperatureHumiditySensor { private sensor = new DHT22(4);
async read() { const temp = await this.sensor.temperature(); const humidity = await this.sensor.humidity();
return {
temperature: temp,
humidity: humidity,
timestamp: Date.now()
};
} }
// src/sensors/soil-moisture.ts export class SoilMoistureSensor { constructor(private pin: string) {}
async read(): Promise
// src/sensors/light-sensor.ts export class LightSensor { constructor(private pin: string) {}
async read(): Promise
2. Actuators Layer
```typescript // src/actuators/water-pump.ts import { Relay } from ‘@lynxjs/actuators’;
export class WaterPump { private relay = new Relay(5);
on() { this.relay.close(); console.log(’💧 Water pump ON’); }
off() { this.relay.open(); console.log(’💧 Water pump OFF’); }
isOn(): boolean { return this.relay.isClosed(); } } ```
3. Automation Rules
```typescript
// src/controllers/automation-rules.ts
export interface AutomationRule {
name: string;
condition: () => Promise
export class AutomationEngine { private rules: AutomationRule[] = []; private lastExecuted: Map<string, number> = new Map();
addRule(rule: AutomationRule) { this.rules.push(rule); }
async runAll() { for (const rule of this.rules) { const shouldExecute = await rule.condition(); const lastRun = this.lastExecuted.get(rule.name) || 0; const now = Date.now();
if (shouldExecute) {
if (!rule.cooldown || (now - lastRun) > rule.cooldown) {
await rule.action();
this.lastExecuted.set(rule.name, now);
}
}
}
} } ```
4. Main Controller
```typescript // src/controllers/greenhouse-controller.ts import { TemperatureHumiditySensor } from ’../sensors/dht22’; import { SoilMoistureSensor } from ’../sensors/soil-moisture’; import { LightSensor } from ’../sensors/light-sensor’; import { WaterPump } from ’../actuators/water-pump’; import { AutomationEngine, AutomationRule } from ’./automation-rules’; import { InfluxDB } from ‘@lynxjs/storage’;
export class GreenhouseController { private tempHumidity = new TemperatureHumiditySensor(); private soilMoisture = new SoilMoistureSensor(‘A0’); private light = new LightSensor(‘A1’); private pump = new WaterPump(); private automation = new AutomationEngine(); private influx = new InfluxDB({ host: ‘localhost’, database: ‘greenhouse’ });
async init() { // ตั้งค่า automation rules this.setupAutomationRules();
// เริ่มอ่าน sensors ทุก 10 วินาที
setInterval(() => this.collectData(), 10000);
// รัน automation ทุก 30 วินาที
setInterval(() => this.automation.runAll(), 30000);
console.log('🌱 Greenhouse Controller initialized');
}
private setupAutomationRules() { // Rule 1: รดน้ำอัตโนมัติถ้าดินแห้ง this.automation.addRule({ name: ‘auto-water’, condition: async () => { const moisture = await this.soilMoisture.read(); return moisture < 30; // ถ้าความชื้นน้อยกว่า 30% }, action: async () => { console.log(’🚿 Auto-watering triggered’); this.pump.on(); await sleep(10000); // รดน้ำ 10 วินาที this.pump.off(); }, cooldown: 300000 // 5 นาที });
// Rule 2: เตือนถ้าอุณหภูมิสูงเกินไป
this.automation.addRule({
name: 'temp-warning',
condition: async () => {
const { temperature } = await this.tempHumidity.read();
return temperature > 35;
},
action: async () => {
console.log('⚠️ Temperature too high!');
// ส่ง notification
await this.sendAlert('Temperature exceeds 35°C');
},
cooldown: 600000 // 10 นาที
});
}
private async collectData() { const { temperature, humidity } = await this.tempHumidity.read(); const moisture = await this.soilMoisture.read(); const light = await this.light.read();
const data = {
temperature,
humidity,
moisture,
light,
timestamp: Date.now()
};
// เก็บข้อมูลใน database
await this.saveToDatabase(data);
console.log('📊 Data collected:', data);
}
private async saveToDatabase(data: any) { await this.influx.writePoints([ { measurement: ‘temperature’, fields: { value: data.temperature } }, { measurement: ‘humidity’, fields: { value: data.humidity } }, { measurement: ‘moisture’, fields: { value: data.moisture } }, { measurement: ‘light’, fields: { value: data.light } } ]); }
private async sendAlert(message: string) { // ส่ง alert ผ่าน MQTT หรือ webhook console.log(’📢 Alert:’, message); } } ```
📊 Dashboard
สร้าง Dashboard ง่ายๆ ด้วย HTML + JavaScript:
```html
🌱 Smart Greenhouse Monitor
Temperature
--°C
Humidity
--%
Soil Moisture
--%
Light
-- lux
🎓 สรุป
ในบทความนี้เราได้เรียนรู้:
✅ การต่อ sensors หลายตัวพร้อมกัน ✅ การสร้าง automation rules ✅ การเก็บข้อมูลใน time-series database ✅ การสร้าง Dashboard สำหรับ monitoring
🔗 Links:
Happy Building! 🌱