From 7885cede659f3255be56f77c1eef2ada7387d6f1 Mon Sep 17 00:00:00 2001
From: chenyc <501753378@qq.com>
Date: 星期日, 22 三月 2026 16:23:21 +0800
Subject: [PATCH] 初始化项目
---
src/aliyunClient.js | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 158 insertions(+), 0 deletions(-)
diff --git a/src/aliyunClient.js b/src/aliyunClient.js
new file mode 100644
index 0000000..af6f19c
--- /dev/null
+++ b/src/aliyunClient.js
@@ -0,0 +1,158 @@
+const aliyunIot = require("aliyun-iot-device-sdk");
+const logger = require("./logger");
+const config = require("./config");
+const { getAliyunDeviceSecret } = require("./api");
+
+// 阿里云物联网对接管理器:按设备号获取三元组、建立 iotDevice,并在每次收到数据时上报属性
+function createAliyunManager({ propertyMapper }) {
+ if (!config.aliyun || !config.aliyun.enabled) {
+ logger.info("Aliyun IoT is disabled by config");
+ return {
+ reportDeviceData: () => {},
+ closeAll: () => {}
+ };
+ }
+
+ // 设备号 -> { iotDevice, productKey, deviceName }
+ const deviceMap = new Map();
+
+ async function ensureIotDevice(deviceNumber) {
+ let entry = deviceMap.get(deviceNumber);
+ if (entry && entry.iotDevice) {
+ return entry;
+ }
+
+ try {
+ logger.info("Request Aliyun device secret", { deviceNumber });
+ // 复用旧项目的 api.js 约定:第一个参数是相对路径
+ const resp = await getAliyunDeviceSecret(
+ "device/info/getAliyunDeviceSecret",
+ deviceNumber
+ );
+ const body = resp && resp.data ? resp.data : null;
+ if (!body || !body.data) {
+ logger.warn("Aliyun device secret response invalid", {
+ deviceNumber,
+ body
+ });
+ return null;
+ }
+ const data = body.data;
+ if (!data.productKey || !data.deviceName || !data.deviceSecret) {
+ logger.warn("Aliyun device secret missing fields", {
+ deviceNumber,
+ data
+ });
+ return null;
+ }
+
+ const productKey = data.productKey;
+ const deviceName = data.deviceName;
+ const deviceSecret = data.deviceSecret;
+
+ logger.info("Creating Aliyun IoT device", {
+ deviceNumber,
+ productKey,
+ deviceName
+ });
+
+ const iotDevice = aliyunIot.device({
+ ProductKey: productKey,
+ DeviceName: deviceName,
+ DeviceSecret: deviceSecret
+ });
+
+ iotDevice.on("connect", () => {
+ logger.info("Aliyun IoT connected", { deviceNumber, productKey, deviceName });
+ });
+
+ iotDevice.on("error", (err) => {
+ logger.error("Aliyun IoT error", {
+ deviceNumber,
+ error: err.message || err
+ });
+ });
+
+ iotDevice.on("close", () => {
+ logger.warn("Aliyun IoT connection closed", { deviceNumber });
+ });
+
+ entry = { iotDevice, productKey, deviceName };
+ deviceMap.set(deviceNumber, entry);
+ return entry;
+ } catch (err) {
+ logger.error("ensureIotDevice error", {
+ deviceNumber,
+ error: err.message || err
+ });
+ return null;
+ }
+ }
+
+ async function reportDeviceData(deviceNumber, rawData) {
+ try {
+ const entry = await ensureIotDevice(deviceNumber);
+ if (!entry || !entry.iotDevice) {
+ return;
+ }
+
+ // 使用 PropertyMapper 将内部字段转换为阿里云物模型属性对象
+ let props = rawData;
+ if (propertyMapper && typeof propertyMapper.transformForAliyun === "function") {
+ try {
+ props = propertyMapper.transformForAliyun(rawData);
+ } catch (e) {
+ logger.error("transformForAliyun error", {
+ deviceNumber,
+ error: e.message || e
+ });
+ props = rawData;
+ }
+ }
+
+ // 记录准备上报到阿里云的物模型数据,便于和设备原始数据对照
+ logger.info("Aliyun postProps payload", {
+ deviceNumber,
+ productKey: entry.productKey,
+ deviceName: entry.deviceName,
+ props
+ });
+
+ entry.iotDevice.postProps(props, (res) => {
+ if (res && res.message === "success") {
+ logger.info("Aliyun postProps success", { deviceNumber });
+ } else {
+ logger.error("Aliyun postProps failed", { deviceNumber, res });
+ }
+ });
+ } catch (err) {
+ logger.error("reportDeviceData error", {
+ deviceNumber,
+ error: err.message || err
+ });
+ }
+ }
+
+ function closeAll() {
+ for (const [deviceNumber, entry] of deviceMap.entries()) {
+ try {
+ if (entry.iotDevice && typeof entry.iotDevice.end === "function") {
+ entry.iotDevice.end();
+ }
+ } catch (err) {
+ logger.error("Close Aliyun device error", {
+ deviceNumber,
+ error: err.message || err
+ });
+ }
+ deviceMap.delete(deviceNumber);
+ }
+ }
+
+ return {
+ reportDeviceData,
+ closeAll
+ };
+}
+
+module.exports = createAliyunManager;
--
Gitblit v1.8.0