From 7885cede659f3255be56f77c1eef2ada7387d6f1 Mon Sep 17 00:00:00 2001
From: chenyc <501753378@qq.com>
Date: 星期日, 22 三月 2026 16:23:21 +0800
Subject: [PATCH] 初始化项目

---
 src/propertyMapper.js |   74 +++++++++++++++++++++++++++++++++++++
 1 files changed, 74 insertions(+), 0 deletions(-)

diff --git a/src/propertyMapper.js b/src/propertyMapper.js
new file mode 100644
index 0000000..98d5692
--- /dev/null
+++ b/src/propertyMapper.js
@@ -0,0 +1,74 @@
+const fs = require("fs");
+const path = require("path");
+const logger = require("./logger");
+
+class PropertyMapper {
+  constructor() {
+    this.map = new Map(); // identifier -> { identifier, name, ... }
+    this.loadSchema();
+  }
+
+  loadSchema() {
+    try {
+      // 在普通 Node 环境下,schema.json 位于项目根目录;
+      // 使用 pkg 打包后,优先从可执行文件同级目录读取 schema.json,便于现场替换。
+      const appRoot = process.pkg
+        ? path.dirname(process.execPath)
+        : path.join(__dirname, "..");
+      const schemaPath = path.join(appRoot, "schema.json");
+      const raw = fs.readFileSync(schemaPath, "utf8");
+      const json = JSON.parse(raw);
+      if (Array.isArray(json.properties)) {
+        for (const prop of json.properties) {
+          if (prop.identifier) {
+            this.map.set(prop.identifier, prop);
+          }
+        }
+      }
+      logger.info("Property schema loaded", { count: this.map.size });
+    } catch (err) {
+      logger.warn("Failed to load schema.json, using empty mapping", err.message || err);
+    }
+  }
+
+  mapData(rawData) {
+    const result = [];
+    if (!rawData || typeof rawData !== "object") return result;
+    for (const [key, value] of Object.entries(rawData)) {
+      const def = this.map.get(key) || { identifier: key, name: key };
+      result.push({
+        identifier: def.identifier,
+        name: def.name,
+        value
+      });
+    }
+    return result;
+  }
+
+  transformForHTTP(rawData, deviceNumber) {
+    return {
+      deviceNumber,
+      properties: this.mapData(rawData)
+    };
+  }
+
+  transformForMQTT(rawData, deviceNumber) {
+    return {
+      deviceNumber,
+      timestamp: Date.now(),
+      properties: this.mapData(rawData)
+    };
+  }
+
+  transformForAliyun(rawData) {
+    // 阿里云物模型上报通常直接使用 identifier -> value
+    const result = {};
+    if (!rawData || typeof rawData !== "object") return result;
+    for (const [key, value] of Object.entries(rawData)) {
+      result[key] = value;
+    }
+    return result;
+  }
+}
+
+module.exports = PropertyMapper;

--
Gitblit v1.8.0