智能家居远程控灯智慧工厂设备监控Java物联网技术实战案例与应用场景解析
为什么我们要聊物联网
你有没有想过,有一天出门忘了关灯,在办公室能顺手关掉?或者在工厂里,设备温度异常了,手机立马就能收到警报?这些不再是科幻电影里的场景,而是正在发生的现实。
物联网,简单说就是把各种设备连上网,让它们能”说话”。想象一下,你的灯泡能告诉你它的亮度、能耗,你的工厂设备能汇报温度、振动、运行状态——这就是物联网的魅力。
今天,我们就用Java语言,从零开始搭建一套物联网系统,帮你理解智能家居远程控灯和智慧工厂设备监控的具体实现方式。
系统架构:物联网的三层模型
在动手写代码之前,先理解物联网的基本架构。一个典型的物联网系统通常分为三层:
感知层——这是物联网的”眼睛和耳朵”。负责采集数据,比如温度传感器、光照传感器、开关状态等。在智能家居里,这就是智能灯泡、智能开关;在工厂里,这就是各种工业传感器。
网络层——这是物联网的”神经”。负责把数据传到服务器,常见的协议有MQTT、HTTP、CoAP等。MQTT尤其适合物联网场景,因为它轻量、可靠、支持发布订阅模式。
应用层——这是物联网的”大脑”。负责处理数据、做出决策、提供用户界面。比如你的APP能显示设备状态、远程控制设备、接收告警通知。
理解了架构后,我们来看具体的代码实现。
智能家居远程控灯:Java + MQTT实战
先搭建通信基础
MQTT是物联网最常用的通信协议之一,它采用发布/订阅模式,设备之间通过主题进行消息传递。我们先来搭建一个MQTT Broker,可以用Eclipse Mosquitto,或者用Java直接实现一个简单的服务器。
不过,在真实项目中,我们更多是连接现成的Broker,比如阿里云物联网平台、EMQX等。这里我们以本地部署EMQX为例。
// MQTT连接配置类
public class MqttConfig {
private static final String BROKER_URL = "tcp://localhost:1883";
private static final String CLIENT_ID = "smart-home-controller";
private static final String USERNAME = "admin";
private static final String PASSWORD = "public";
// MQTT连接选项
public MqttConnectOptions getConnectOptions() {
MqttConnectOptions options = new MqttConnectOptions();
options.setServerURIs(new String[]{BROKER_URL});
options.setUserName(USERNAME);
options.setPassword(PASSWORD.toCharArray());
options.setCleanSession(true);
options.setKeepAliveInterval(60);
options.setAutomaticReconnect(true);
return options;
}
}
智能灯泡的设备端实现
在智能家居场景中,每个灯泡就是一个MQTT客户端,它能接收控制指令,也能上报状态。
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 智能灯泡设备端实现
* 模拟一个WiFi智能灯泡,能接收远程控制指令
*/
public class SmartBulb {
private static final String DEVICE_ID = "bulb-001";
private static final String TOPIC_COMMAND = "home/livingroom/" + DEVICE_ID + "/command";
private static final String TOPIC_STATUS = "home/livingroom/" + DEVICE_ID + "/status";
private MqttClient client;
private ObjectMapper objectMapper = new ObjectMapper();
// 灯泡状态
private boolean isOn = false;
private int brightness = 50; // 0-100
private int colorTemperature = 4000; // 色温,单位K
// 操作计数器,用于模拟设备日志
private AtomicInteger commandCount = new AtomicInteger(0);
public SmartBulb(String brokerUrl) {
try {
MemoryPersistence persistence = new MemoryPersistence();
client = new MqttClient(brokerUrl, DEVICE_ID, persistence);
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(false);
options.setAutomaticReconnect(true);
options.setKeepAliveInterval(30);
// 设置消息回调
client.setCallback(new MqttCallbackExtended() {
@Override
public void connectComplete(boolean reconnect, String serverURI) {
System.out.println("[" + DEVICE_ID + "] 连接成功, reconnect=" + reconnect);
// 订阅命令主题
try {
client.subscribe(TOPIC_COMMAND, 1);
} catch (MqttException e) {
e.printStackTrace();
}
}
@Override
public void connectionLost(Throwable cause) {
System.out.println("[" + DEVICE_ID + "] 连接中断: " + cause.getMessage());
}
@Override
public void messageArrived(String topic, MqttMessage message) {
handleCommand(topic, message);
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
// 消息发送完成回调
}
});
client.connect(options);
} catch (Exception e) {
throw new RuntimeException("初始化智能灯泡失败", e);
}
}
/**
* 处理接收到的控制命令
*/
private void handleCommand(String topic, MqttMessage message) {
String payload = new String(message.getPayload());
commandCount.incrementAndGet();
System.out.println("[" + DEVICE_ID + "] 收到命令 #" + commandCount.get() + ": " + payload);
try {
BulbCommand command = objectMapper.readValue(payload, BulbCommand.class);
switch (command.getAction()) {
case "turn_on":
turnOn();
break;
case "turn_off":
turnOff();
break;
case "set_brightness":
setBrightness(command.getBrightness());
break;
case "set_color":
setColorTemperature(command.getColorTemperature());
break;
default:
System.out.println("[" + DEVICE_ID + "] 未知命令: " + command.getAction());
}
// 发布状态更新
publishStatus();
} catch (Exception e) {
System.err.println("[" + DEVICE_ID + "] 解析命令失败: " + e.getMessage());
}
}
private void turnOn() {
isOn = true;
System.out.println("[" + DEVICE_ID + "] 灯泡已开启, 亮度: " + brightness + "%");
}
private void turnOff() {
isOn = false;
System.out.println("[" + DEVICE_ID + "] 灯泡已关闭");
}
private void setBrightness(int brightness) {
if (brightness < 0) brightness = 0;
if (brightness > 100) brightness = 100;
this.brightness = brightness;
System.out.println("[" + DEVICE_ID + "] 亮度调节至: " + brightness + "%");
}
private void setColorTemperature(int colorTemperature) {
this.colorTemperature = colorTemperature;
System.out.println("[" + DEVICE_ID + "] 色温调节至: " + colorTemperature + "K");
}
/**
* 上报设备状态到云端
*/
private void publishStatus() {
try {
BulbStatus status = new BulbStatus(
DEVICE_ID,
isOn,
brightness,
colorTemperature,
System.currentTimeMillis()
);
String json = objectMapper.writeValueAsString(status);
MqttMessage message = new MqttMessage(json.getBytes());
message.setQos(1);
message.setRetained(false);
client.publish(TOPIC_STATUS, message);
System.out.println("[" + DEVICE_ID + "] 状态已上报: " + json);
} catch (Exception e) {
e.printStackTrace();
}
}
// 内部数据模型
static class BulbCommand {
private String action;
private Integer brightness;
private Integer colorTemperature;
public String getAction() { return action; }
public void setAction(String action) { this.action = action; }
public Integer getBrightness() { return brightness; }
public void setBrightness(Integer brightness) { this.brightness = brightness; }
public Integer getColorTemperature() { return colorTemperature; }
public void setColorTemperature(Integer colorTemperature) { this.colorTemperature = colorTemperature; }
}
static class BulbStatus {
private String deviceId;
private boolean isOn;
private int brightness;
private int colorTemperature;
private long timestamp;
public BulbStatus(String deviceId, boolean isOn, int brightness,
int colorTemperature, long timestamp) {
this.deviceId = deviceId;
this.isOn = isOn;
this.brightness = brightness;
this.colorTemperature = colorTemperature;
this.timestamp = timestamp;
}
public String getDeviceId() { return deviceId; }
public boolean isOn() { return isOn; }
public int getBrightness() { return brightness; }
public int getColorTemperature() { return colorTemperature; }
public long getTimestamp() { return timestamp; }
}
}
远程控制中心:Web API实现
有了设备端,我们还需要一个控制中心,让用户能远程控制灯泡。这里用Spring Boot搭建REST API。
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.eclipse.paho.client.mqttv3.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 智能家居远程控灯控制器
* 提供HTTP API供前端APP调用
*/
@RestController
@RequestMapping("/api/smart-home")
public class SmartHomeController {
private static final String BROKER_URL = "tcp://localhost:1883";
private final Map<String, MqttClient> deviceClients = new ConcurrentHashMap<>();
/**
* 控制指定灯泡
* POST /api/smart-home/bulbs/{deviceId}/control
*/
@PostMapping("/bulbs/{deviceId}/control")
public ResponseEntity<?> controlBulb(
@PathVariable String deviceId,
@RequestBody Map<String, Object> params
) {
String action = (String) params.get("action");
Integer brightness = params.get("brightness") != null
? (Integer) params.get("brightness") : null;
Integer colorTemp = params.get("colorTemperature") != null
? (Integer) params.get("colorTemperature") : null;
if (action == null) {
return ResponseEntity.badRequest().body("缺少action参数");
}
try {
MqttClient client = getOrCreateClient(deviceId);
// 构建命令JSON
StringBuilder json = new StringBuilder("{");
json.append("\"action\":\"").append(action).append("\"");
if (brightness != null) {
json.append(",\"brightness\":").append(brightness);
}
if (colorTemp != null) {
json.append(",\"colorTemperature\":").append(colorTemp);
}
json.append("}");
// 发送MQTT消息
String topic = "home/livingroom/" + deviceId + "/command";
MqttMessage message = new MqttMessage(json.toString().getBytes());
message.setQos(1);
client.publish(topic, message);
return ResponseEntity.ok(Map.of(
"success", true,
"deviceId", deviceId,
"action", action,
"message", "命令已发送"
));
} catch (Exception e) {
return ResponseEntity.internalServerError().body(
Map.of("success", false, "error", e.getMessage())
);
}
}
/**
* 查询设备状态
* GET /api/smart-home/bulbs/{deviceId}/status
*/
@GetMapping("/bulbs/{deviceId}/status")
public ResponseEntity<?> getDeviceStatus(@PathVariable String deviceId) {
// 在实际项目中,这里应该从数据库或缓存中查询设备状态
// 这里简化为返回模拟数据
return ResponseEntity.ok(Map.of(
"deviceId", deviceId,
"isOn", false,
"brightness", 50,
"colorTemperature", 4000,
"lastUpdate", System.currentTimeMillis()
));
}
/**
* 批量控制多个设备
* POST /api/smart-home/scene/execute
*/
@PostMapping("/scene/execute")
public ResponseEntity<?> executeScene(@RequestBody Map<String, Object> params) {
String scene = (String) params.get("scene");
// 预设场景控制逻辑
switch (scene) {
case "home":
// 回家模式:客厅灯开,亮度80%
controlBulb("bulb-001", Map.of("action", "turn_on", "brightness", 80));
controlBulb("bulb-002", Map.of("action", "turn_on", "brightness", 80));
break;
case "movie":
// 观影模式:客厅灯关,卧室灯开,亮度20%
controlBulb("bulb-001", Map.of("action", "turn_off"));
controlBulb("bulb-002", Map.of("action", "turn_on", "brightness", 20));
break;
case "sleep":
// 睡眠模式:所有灯关
controlBulb("bulb-001", Map.of("action", "turn_off"));
controlBulb("bulb-002", Map.of("action", "turn_off"));
break;
default:
return ResponseEntity.badRequest().body("未知场景: " + scene);
}
return ResponseEntity.ok(Map.of("success", true, "scene", scene));
}
private MqttClient getOrCreateClient(String deviceId) throws MqttException {
return deviceClients.computeIfAbsent(deviceId, id -> {
try {
MqttClient client = new MqttClient(
BROKER_URL,
"controller-" + id,
new MemoryPersistence()
);
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName("admin");
options.setPassword("public".toCharArray());
client.connect(options);
return client;
} catch (Exception e) {
throw new RuntimeException("连接MQTT失败", e);
}
});
}
}
前端APP的交互体验
想象一下,用户打开APP,看到的界面是什么样的。首页是房间概览,显示客厅、卧室、厨房的灯光状态。点击房间,进入设备列表,可以看到每个灯泡的开关、亮度调节、色温调节。
这个APP如何与后端通信?很简单:
// 前端APP调用远程控制API
async function controlLight(deviceId, action, brightness) {
const response = await fetch(`/api/smart-home/bulbs/${deviceId}/control`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: action,
brightness: brightness
})
});
return await response.json();
}
// 使用示例
controlLight('bulb-001', 'turn_on', 80);
智慧工厂设备监控:从数据采集到告警
工厂场景比家庭复杂得多。一个中型工厂可能有几百台设备,每台设备产生多种数据:温度、振动、转速、能耗、运行状态等。我们需要一个能处理海量数据的系统。
工业设备数据采集模块
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
/**
* 工业设备数据采集器
* 模拟从PLC、传感器采集数据
*/
public class IndustrialDeviceCollector {
private static final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(4);
// 模拟设备列表
private final Map<String, IndustrialDevice> devices = new ConcurrentHashMap<>();
/**
* 注册设备
*/
public void registerDevice(IndustrialDevice device) {
devices.put(device.getDeviceId(), device);
System.out.println("[工厂] 设备注册: " + device.getDeviceId()
+ " - " + device.getName());
}
/**
* 启动所有设备的数据采集
*/
public void startCollection() {
devices.forEach((id, device) -> {
scheduler.scheduleAtFixedRate(() -> {
collectDeviceData(device);
}, 0, device.getSampleInterval(), TimeUnit.SECONDS);
});
System.out.println("[工厂] 数据采集系统已启动,设备数: " + devices.size());
}
private void collectDeviceData(IndustrialDevice device) {
// 模拟数据采集
Map<String, Object> readings = device.simulateReadings();
device.addReading(readings);
// 实时告警检测
if (device.checkAnomaly(readings)) {
alarmService.sendAlarm(device, readings);
}
}
// 告警服务(简化实现)
private final AlarmService alarmService = new AlarmService();
}
/**
* 工业设备抽象类
*/
abstract class IndustrialDevice {
private final String deviceId;
private final String name;
private final double sampleInterval;
private final Queue<Map<String, Object>> history = new ArrayDeque<>(100);
// 阈值配置
private final Map<String, Double> thresholds = new HashMap<>();
public IndustrialDevice(String deviceId, String name, double sampleInterval) {
this.deviceId = deviceId;
this.name = name;
this.sampleInterval = sampleInterval;
}
public String getDeviceId() { return deviceId; }
public String getName() { return name; }
public double getSampleInterval() { return sampleInterval; }
public void addReading(Map<String, Object> readings) {
history.offer(readings);
if (history.size() > 100) {
history.poll();
}
}
public void setThreshold(String metric, double value) {
thresholds.put(metric, value);
}
/**
* 子类实现数据采集逻辑
*/
public abstract Map<String, Object> simulateReadings();
/**
* 检测异常
*/
public boolean checkAnomaly(Map<String, Object> readings) {
for (Map.Entry<String, Double> entry : thresholds.entrySet()) {
Object value = readings.get(entry.getKey());
if (value instanceof Number) {
double numValue = ((Number) value).doubleValue();
if (numValue > entry.getValue()) {
System.out.println("[" + deviceId + "] 告警: "
+ entry.getKey() + " = " + numValue
+ " (阈值: " + entry.getValue() + ")");
return true;
}
}
}
return false;
}
}
/**
* CNC机床设备
*/
class CncMachine extends IndustrialDevice {
private final Random random = new Random();
private boolean running = false;
public CncMachine(String deviceId, String name) {
super(deviceId, name, 2.0); // 每2秒采样一次
// 设置告警阈值
setThreshold("temperature", 85.0); // 温度超过85度告警
setThreshold("vibration", 5.0); // 振动超过5mm/s告警
setThreshold("spindle_speed", 12000); // 主轴转速超过12000告警
}
@Override
public Map<String, Object> simulateReadings() {
Map<String, Object> data = new HashMap<>();
if (running) {
data.put("temperature", 60 + random.nextDouble() * 30); // 60-90度
data.put("vibration", 1.0 + random.nextDouble() * 5); // 1-6mm/s
data.put("spindle_speed", 8000 + random.nextInt(4000)); // 8000-12000
data.put("power_consumption", 15 + random.nextDouble() * 10); // 15-25kW
data.put("status", "running");
} else {
data.put("temperature", 25 + random.nextDouble() * 5); // 待机温度
data.put("vibration", 0.1 + random.nextDouble() * 0.5);
data.put("spindle_speed", 0);
data.put("power_consumption", 2 + random.nextDouble() * 2);
data.put("status", "idle");
}
data.put("timestamp", System.currentTimeMillis());
return data;
}
public void start() { running = true; }
public void stop() { running = false; }
}
/**
* 温度监控设备
*/
class TempSensor extends IndustrialDevice {
private final Random random = new Random();
public TempSensor(String deviceId, String name) {
super(deviceId, name, 5.0); // 每5秒采样
setThreshold("temperature", 40.0);
setThreshold("humidity", 80.0);
}
@Override
public Map<String, Object> simulateReadings() {
Map<String, Object> data = new HashMap<>();
data.put("temperature", 22 + random.nextDouble() * 25); // 22-47度
data.put("humidity", 40 + random.nextDouble() * 40); // 40-80%
data.put("timestamp", System.currentTimeMillis());
return data;
}
}
数据可视化与实时监控
工厂里的监控大屏需要实时显示设备状态。我们用WebSocket向前端推送数据。
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* WebSocket实时数据推送处理器
*/
@Component
public class DeviceDataWebSocketHandler extends TextWebSocketHandler {
private final CopyOnWriteArraySet<WebSocketSession> sessions =
new CopyOnWriteArraySet<>();
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public void afterConnectionEstablished(WebSocketSession session) {
sessions.add(session);
System.out.println("[WebSocket] 新连接: " + session.getId()
+ ", 当前连接数: " + sessions.size());
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
// 处理前端请求,比如请求特定设备的数据
}
@Override
public void afterConnectionClosed(WebSocketSession session, org.springframework.web.socket.CloseStatus status) {
sessions.remove(session);
System.out.println("[WebSocket] 连接关闭: " + session.getId()
+ ", 剩余连接数: " + sessions.size());
}
/**
* 推送设备数据到所有前端
*/
public void broadcastDeviceData(String deviceId, Map<String, Object> data) {
String json = null;
try {
json = objectMapper.writeValueAsString(data);
} catch (Exception e) {
e.printStackTrace();
return;
}
TextMessage message = new TextMessage(json);
sessions.forEach(session -> {
try {
if (session.isOpen()) {
session.sendMessage(message);
}
} catch (IOException e) {
System.err.println("推送失败: " + e.getMessage());
}
});
}
public int getConnectedCount() {
return sessions.size();
}
}
告警通知系统
工厂设备异常不能只在大屏上显示,还要能及时通知相关人员。
import java.util.*;
import java.util.concurrent.*;
/**
* 多级告警通知服务
*/
public class AlarmService {
private final List<AlarmListener> listeners = new CopyOnWriteArrayList<>();
private final BlockingQueue<AlarmMessage> alarmQueue = new LinkedBlockingQueue<>();
/**
* 发送告警
*/
public void sendAlarm(IndustrialDevice device, Map<String, Object> readings) {
AlarmMessage alarm = new AlarmMessage(
device.getDeviceId(),
device.getName(),
readings,
System.currentTimeMillis()
);
alarmQueue.offer(alarm);
// 通知所有监听者
listeners.forEach(listener -> listener.onAlarm(alarm));
System.out.println("[" + alarm.getLevel() + "] 告警已生成: " + alarm);
}
/**
* 注册告警通知渠道
*/
public void registerListener(AlarmListener listener) {
listeners.add(listener);
}
/**
* 告警监听器接口
*/
public interface AlarmListener {
void onAlarm(AlarmMessage alarm);
}
// 告警消息模型
static class AlarmMessage {
private final String deviceId;
private final String deviceName;
private final Map<String, Object> readings;
private final long timestamp;
private final AlarmLevel level;
public AlarmMessage(String deviceId, String deviceName,
Map<String, Object> readings, long timestamp) {
this.deviceId = deviceId;
this.deviceName = deviceName;
this.readings = readings;
this.timestamp = timestamp;
this.level = determineLevel(readings);
}
private AlarmLevel determineLevel(Map<String, Object> readings) {
// 根据异常程度确定告警级别
double temp = (double) readings.getOrDefault("temperature", 0.0);
if (temp > 90) return AlarmLevel.CRITICAL;
if (temp > 85) return AlarmLevel.WARNING;
return AlarmLevel.INFO;
}
public String getDeviceId() { return deviceId; }
public String getDeviceName() { return deviceName; }
public Map<String, Object> getReadings() { return readings; }
public long getTimestamp() { return timestamp; }
public AlarmLevel getLevel() { return level; }
@Override
public String toString() {
return String.format("[%s] %s: temp=%.1f", level, deviceName,
readings.getOrDefault("temperature", 0.0));
}
}
enum AlarmLevel {
INFO, WARNING, CRITICAL
}
}
告警通知的实际接入
在真实项目中,告警通知会通过多种方式触达相关人员:
/**
* 短信告警通知(模拟)
*/
class SmsAlarmNotifier implements AlarmService.AlarmListener {
@Override
public void onAlarm(AlarmMessage alarm) {
if (alarm.getLevel() == AlarmLevel.CRITICAL) {
System.out.println("[短信告警] 发送给运维人员: " + alarm);
// 实际项目中调用短信API,如阿里云短信服务
// SmsClient.send("13800138000", alarm.toString());
}
}
}
/**
* 企业微信/钉钉机器人告警
*/
class WebhookAlarmNotifier implements AlarmService.AlarmListener {
@Override
public void onAlarm(AlarmMessage alarm) {
System.out.println("[企业微信] 发送告警: " + alarm);
// 实际项目中调用Webhook API
// WebhookClient.post("https://qyapi.weixin.qq.com/...", alarm.toString());
}
}
/**
* 声音告警(工厂现场)
*/
class SoundAlarmNotifier implements AlarmService.AlarmListener {
@Override
public void onAlarm(AlarmMessage alarm) {
if (alarm.getLevel() == AlarmLevel.CRITICAL) {
System.out.println("[现场报警] 触发声光报警: " + alarm.getDeviceName());
// 实际项目中控制现场声光报警器
}
}
}
完整系统集成:让智能家居和工厂监控协同工作
实际场景中,智能家居和工厂设备监控往往是同一个物联网平台的不同应用。我们来看一个整合的系统。
import java.util.*;
import java.util.concurrent.*;
/**
* 统一物联网平台核心服务
*/
public class IoTRuntime {
private final MqttBroker broker;
private final DeviceRegistry deviceRegistry;
private final AlarmService alarmService;
private final DataStorage dataStorage;
public IoTRuntime() {
this.broker = new MqttBroker("tcp://localhost:1883");
this.deviceRegistry = new DeviceRegistry();
this.alarmService = new AlarmService();
this.dataStorage = new DataStorage();
// 注册告警通知
alarmService.registerListener(new SmsAlarmNotifier());
alarmService.registerListener(new WebhookAlarmNotifier());
alarmService.registerListener(new SoundAlarmNotifier());
}
/**
* 启动整个系统
*/
public void start() {
// 启动MQTT Broker
broker.start();
// 注册智能家居设备
SmartBulb bulb1 = new SmartBulb(broker.getBrokerUrl());
SmartBulb bulb2 = new SmartBulb(broker.getBrokerUrl());
deviceRegistry.register(bulb1);
deviceRegistry.register(bulb2);
// 注册工厂设备
CncMachine cnc1 = new CncMachine("cnc-001", "1号CNC机床");
CncMachine cnc2 = new CncMachine("cnc-002", "2号CNC机床");
TempSensor sensor1 = new TempSensor("temp-001", "车间温度传感器");
deviceRegistry.register(cnc1);
deviceRegistry.register(cnc2);
deviceRegistry.register(sensor1);
// 启动数据采集
IndustrialDeviceCollector collector = new IndustrialDeviceCollector();
collector.registerDevice(cnc1);
collector.registerDevice(cnc2);
collector.registerDevice(sensor1);
collector.start();
System.out.println("=".repeat(60));
System.out.println("物联网平台已启动");
System.out.println("智能家居设备: 2个");
System.out.println("工厂监控设备: 3个");
System.out.println("告警通知: 已接入");
System.out.println("=".repeat(60));
}
/**
* 远程控灯示例
*/
public void demoRemoteControl() throws Exception {
System.out.println("\n--- 智能家居远程控制演示 ---");
// 通过HTTP API控制灯泡
SmartHomeController controller = new SmartHomeController();
// 打开客厅灯
controller.controlBulb("bulb-001", Map.of("action", "turn_on", "brightness", 80));
Thread.sleep(500);
// 执行"回家"场景
controller.executeScene(Map.of("scene", "home"));
Thread.sleep(500);
// 执行"观影"场景
controller.executeScene(Map.of("scene", "movie"));
Thread.sleep(500);
System.out.println("--- 演示结束 ---\n");
}
public static void main(String[] args) throws Exception {
IoTRuntime runtime = new IoTRuntime();
runtime.start();
runtime.demoRemoteControl();
// 保持运行
Thread.sleep(TimeUnit.HOURS.toMillis(24));
}
}
技术选型建议:不同场景怎么选
实际项目中,技术选型要根据具体需求来定。下面是一份对比表:
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 智能家居小规模 | MQTT + Spring Boot | 轻量、实时性好 |
| 智能家居大规模 | 阿里云IoT平台 | 免运维、高可用 |
| 工厂设备监控 | MQTT + InfluxDB + Grafana | 时序数据存储+可视化 |
| 工业实时控制 | OPC UA + Java | 工业标准协议 |
| 低功耗传感器 | CoAP + Redis | 节省带宽和电量 |
MQTT相比HTTP的优势在于:支持订阅发布、消息持久化、QoS级别、遗嘱消息等物联网特有功能。对于工厂场景,每秒可能有上千条数据需要处理,MQTT的消息队列机制能更好地应对这种负载。
真实案例:某制造业工厂的物联网改造
让我讲一个真实发生过的案例。
一家中型汽车零部件制造商,厂房里有50台CNC机床、20台注塑机、以及若干环境传感器。改造前,设备状态全靠工人手动记录,设备故障往往是发现问题时已经停机,损失惨重。
改造方案:
- 每台设备加装振动传感器和温度传感器
- 通过工业网关采集数据,用MQTT协议上传到云端
- 云端用Java服务处理数据,存储到时序数据库
- 告警规则:温度超过阈值、振动异常、设备运行时间过长
- 运维人员通过手机APP实时查看设备状态
实施后,设备故障平均响应时间从2小时缩短到15分钟,年度停机损失减少了约40%。这个案例说明,物联网技术不是概念,而是能实实在在带来经济效益的工具。
项目部署:从代码到生产
开发完成后,如何部署到生产环境?
Docker容器化部署:
FROM openjdk:17-slim
WORKDIR /app
COPY target/iot-platform.jar app.jar
EXPOSE 8080 1883
ENTRYPOINT ["java", "-jar", "app.jar"]
docker-compose编排:
version: '3.8'
services:
mqtt-broker:
image: emqx/emqx:latest
ports:
- "1883:1883"
- "9001:9001"
iot-platform:
build: .
ports:
- "8080:8080"
depends_on:
- mqtt-broker
environment:
- MQTT_BROKER_URL=tcp://mqtt-broker:1883
influxdb:
image: influxdb:latest
ports:
- "8086:8086"
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
depends_on:
- influxdb
结语:物联网的未来
从智能家居到智慧工厂,物联网技术的核心逻辑是一致的:连接、采集、分析、控制。Java作为企业级开发的首选语言,在物联网领域有着不可替代的地位——它稳定、生态完善、跨平台,特别适合构建可靠的工业级系统。
当你理解了这套架构,再去面对各种具体的物联网项目,就会发现万变不离其宗。关键是先把基础打牢,然后根据自己的需求去扩展和定制。
