Przeglądaj źródła

feature 消息转换脚本-添加脚本类型js,graaljs

(cherry picked from commit bca93a25e7ffa32213d058b53d6db3bfb35b4e96)
jay 2 lat temu
rodzic
commit
26f8570ea7

+ 6 - 0
iot-components/iot-component-converter/src/main/java/cc/iotkit/converter/IScriptConvertFactory.java

@@ -0,0 +1,6 @@
+package cc.iotkit.converter;
+
+public interface IScriptConvertFactory {
+
+    IConverter getCovert(String name);
+}

+ 16 - 0
iot-components/iot-component-converter/src/main/java/cc/iotkit/converter/ScriptConvertFactory.java

@@ -0,0 +1,16 @@
+package cc.iotkit.converter;
+
+public class ScriptConvertFactory implements IScriptConvertFactory{
+
+    @Override
+    public IConverter getCovert(String name) {
+        if (name.endsWith("graaljs")){
+            return new GraalJsScriptConverter();
+        }
+
+        // 默认是NashornScript js实现方式
+        return new ScriptConverter();
+    }
+
+
+}

+ 24 - 14
iot-components/iot-component-server/src/main/java/cc/iotkit/comps/DeviceComponentManager.java

@@ -20,13 +20,11 @@ import cc.iotkit.comp.IDeviceComponent;
 import cc.iotkit.comps.config.CacheKey;
 import cc.iotkit.comps.config.ComponentConfig;
 import cc.iotkit.comps.service.DeviceBehaviourService;
-import cc.iotkit.converter.Device;
-import cc.iotkit.converter.DeviceMessage;
-import cc.iotkit.converter.GraalJsScriptConverter;
-import cc.iotkit.converter.IConverter;
+import cc.iotkit.converter.*;
 import cc.iotkit.data.IDeviceInfoData;
 import cc.iotkit.data.IProductData;
 import cc.iotkit.data.IProtocolComponentData;
+import cc.iotkit.data.IProtocolConverterData;
 import cc.iotkit.model.device.DeviceInfo;
 import cc.iotkit.model.device.message.ThingModelMessage;
 import cc.iotkit.model.product.Product;
@@ -72,10 +70,13 @@ public class DeviceComponentManager {
     @Autowired
     private DeviceRouter deviceRouter;
 
-    private final IConverter scriptConverter;
+    @Autowired
+    private IProtocolConverterData protocolConverterData;
+
+    private final IScriptConvertFactory scriptConverterFactory;
 
-    public DeviceComponentManager(IConverter converter) {
-        this.scriptConverter = converter;
+    public DeviceComponentManager(IScriptConvertFactory scriptConverterFactory) {
+        this.scriptConverterFactory = scriptConverterFactory;
     }
 
     @PostConstruct
@@ -109,13 +110,7 @@ public class DeviceComponentManager {
         componentInstance.create(new CompConfig(300, component.getConfig()));
 
         try {
-            Path converterPath = componentConfig.getConverterFilePath(component.getConverter());
-            String converterScript = FileUtils.readFileToString(converterPath.
-                    resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile(), "UTF-8");
-
-            scriptConverter.setScript(converterScript);
-            scriptConverter.putScriptEnv("component", componentInstance);
-            componentInstance.setConverter(scriptConverter);
+            setScriptConvert(component, componentInstance);
 
             String componentScript = FileUtils.readFileToString(path.
                     resolve(ProtocolComponent.SCRIPT_FILE_NAME).toFile(), "UTF-8");
@@ -127,6 +122,21 @@ public class DeviceComponentManager {
         }
     }
 
+    private void setScriptConvert(ProtocolComponent component, IDeviceComponent componentInstance) throws IOException {
+        ProtocolConverter protocolConvert = protocolConverterData.findById(component.getConverter());
+
+        IConverter scriptConverter = scriptConverterFactory.getCovert(protocolConvert.getTyp());
+
+        Path converterPath = componentConfig.getConverterFilePath(component.getConverter());
+        String converterScript = FileUtils.readFileToString(converterPath.
+                resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile(), "UTF-8");
+
+//        scriptConverter.setScript(protocolConvert.getScript());
+        scriptConverter.setScript(converterScript);
+        scriptConverter.putScriptEnv("component", componentInstance);
+        componentInstance.setConverter(scriptConverter);
+    }
+
     public void register(String id, IDeviceComponent component) {
         components.put(id, component);
         states.put(id, false);

+ 4 - 2
iot-components/iot-component-server/src/main/java/cc/iotkit/comps/config/ComponentConfig.java

@@ -2,6 +2,8 @@ package cc.iotkit.comps.config;
 
 import cc.iotkit.converter.GraalJsScriptConverter;
 import cc.iotkit.converter.IConverter;
+import cc.iotkit.converter.IScriptConvertFactory;
+import cc.iotkit.converter.ScriptConvertFactory;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import lombok.Data;
@@ -39,8 +41,8 @@ public class ComponentConfig {
 
 
     @Bean
-    public IConverter scriptConverter(){
-        return new GraalJsScriptConverter();
+    public IScriptConvertFactory scriptConverterFactory(){
+        return new ScriptConvertFactory();
     }
 
 }

+ 173 - 0
iot-components/iot-mqtt-component/src/main/resources/convert.js

@@ -0,0 +1,173 @@
+
+var mid=1;
+
+function getMid(){
+    mid++;
+    if(mid>10000){
+        mid=1;
+    }
+    return mid+"";
+}
+
+this.decode = function (msg) {
+    //对msg进行解析,并返回物模型数据
+    var content=msg.content;
+    var topic = content.topic;
+    var payload = content.payload;
+    var identifier = topic.substring(topic.lastIndexOf("/") + 1);
+
+    //透传上报
+    if(topic.endsWith("/event/rawReport")){
+        var rst= component.transparentDecode(payload.params);
+        if(!rst){
+            return null;
+        }
+        rst.occur=new Date().getTime();
+        rst.time=new Date().getTime();
+        return rst;
+    }
+
+    if (topic.endsWith("/property/post")) {
+        //属性上报
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type:"property",
+            identifier: "report", //属性上报
+            occur: new Date().getTime(), //时间戳,设备上的事件或数据产生的本地时间
+            time: new Date().getTime(), //时间戳,消息上报时间
+            data: payload.params,
+        };
+    } else if (topic.indexOf("/event/") > 0) {
+        //事件上报
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type:"event",
+            identifier: identifier,
+            occur: new Date().getTime(),
+            time: new Date().getTime(),
+            data: payload.params,
+        };
+    }else if(topic.endsWith("/service/property/set_reply")){
+        //属性设置回复
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type:"property",
+            identifier: identifier,
+            occur: new Date().getTime(),
+            time: new Date().getTime(),
+            code: payload.code
+        };
+    }else if(topic.endsWith("/config/set_reply")){
+        //设备配置设置回复
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type:"config",
+            identifier: "set_reply",
+            occur: new Date().getTime(),
+            time: new Date().getTime(),
+            code: payload.code
+        };
+    }else if(topic.endsWith("/config/get")){
+        //设备配置获取
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type:"config",
+            identifier: "get",
+            occur: new Date().getTime(),
+            time: new Date().getTime(),
+            data: {},
+        };
+    } else if (topic.endsWith("_reply")) {
+        //服务回复
+        return {
+            mid: msg.mid,
+            productKey: msg.productKey,
+            deviceName: msg.deviceName,
+            type:"service",
+            identifier: identifier,
+            occur: new Date().getTime(),
+            time: new Date().getTime(),
+            code: payload.code,
+            data: payload.data,
+        };
+    }
+    return null;
+};
+
+this.encode = function (service,device) {
+    var deviceMid=getMid();
+    var method="thing.service.";
+    var topic="/sys/"+service.productKey+"/"+service.deviceName+"/c/service/";
+    var params={};
+
+    //透传下发
+    if(device.transparent){
+        var rst=component.transparentEncode(service,device);
+        topic="/sys/"+rst.productKey+"/"+rst.deviceName+"/c/service/rawSend";
+        params.model=rst.content.model;
+        params.deviceName=rst.content.deviceName;
+        params.data=rst.content.data;
+
+        return {
+            productKey:rst.productKey,
+            deviceName:rst.deviceName,
+            mid:rst.mid,
+            content:{
+                topic:topic,
+                payload:JSON.stringify({
+                    id:rst.mid,
+                    method:method+"rawSend",
+                    params:params
+                })
+            }
+        }
+
+    }
+
+    var type=service.type;
+    var identifier=service.identifier;
+
+    if(type=="property"){
+        method+="property."+identifier;
+        topic+="property/"+identifier;
+    }else if(type=="service"){
+        method+=identifier;
+        topic+=identifier;
+    }else if(type=="config"){
+        //设备配置下发
+        method+=identifier;
+        topic="/sys/"+service.productKey+"/"+service.deviceName+"/c/config/"+identifier;
+    }else if(type="lifetime"){
+        //子设备注销下发
+        method+=identifier;
+        topic="/sys/"+service.productKey+"/"+service.deviceName+"/c/deregister";
+    }
+
+    for(var p in service.params){
+        params[p]=service.params[p];
+    }
+
+    return {
+        productKey:service.productKey,
+        deviceName:service.deviceName,
+        mid:deviceMid,
+        content:{
+            topic:topic,
+            payload:JSON.stringify({
+                id:deviceMid,
+                method:method,
+                params:params
+            })
+        }
+    }
+};

+ 4 - 1
iot-data/iot-model/src/main/java/cc/iotkit/model/protocol/ProtocolConverter.java

@@ -31,5 +31,8 @@ public class ProtocolConverter implements Owned<String> {
     private Long createAt;
 
     // 脚本类型
-    private String type;
+    private String typ;
+
+    // 脚本内容
+    private String script;
 }

+ 6 - 0
iot-data/iot-rdb-data-service/src/main/java/cc/iotkit/data/model/TbProtocolConverter.java

@@ -36,4 +36,10 @@ public class TbProtocolConverter {
 
     private Long createAt;
 
+
+    private String typ;
+
+    // 脚本内容
+    private String script;
+
 }

+ 23 - 11
iot-standalone/src/main/java/cc/iotkit/manager/controller/ProtocolController.java

@@ -248,28 +248,40 @@ public class ProtocolController {
     }
 
     @GetMapping("/getConverterScript/{id}")
-    public String getConverterScript(@PathVariable("id") String id) {
-        getAndCheckConverter(id);
-        try {
-            Path path = componentConfig.getConverterFilePath(id);
-            File file = path.resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile();
-            return FileUtils.readFileToString(file, "UTF-8");
-        } catch (Throwable e) {
-            log.error("read converter script file error", e);
-            return "";
+    public ProtocolConverter getConverterScript(@PathVariable("id") String id) {
+        ProtocolConverter converter = getAndCheckConverter(id);
+        String script = converter.getScript();
+        // 如果数据库里不存在,则从文件中读取脚本
+        if(StringUtils.hasText(script)){
+            try {
+                Path path = componentConfig.getConverterFilePath(id);
+                File file = path.resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile();
+                script = FileUtils.readFileToString(file, "UTF-8");
+            } catch (Throwable e) {
+                log.error("read converter script file error", e);
+                script = "";
+            }
+            converter.setScript(script);
         }
+        return converter;
+
     }
 
     @PostMapping("/saveConverterScript/{id}")
     public void saveConverterScript(
             @PathVariable("id") String id,
-            @RequestBody String script) {
+            @RequestBody ProtocolConverter converter) {
         getAndCheckConverter(id);
         try {
+            // 先存文件
             Path path = componentConfig.getConverterFilePath(id);
             File file = path.resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile();
-            script = JsonUtil.parse(script, String.class);
+            String script = converter.getScript();
             FileUtils.writeStringToFile(file, script, "UTF-8", false);
+
+            // 再存数据库
+            protocolConverterData.save(converter);
+
         } catch (Throwable e) {
             throw new BizException("save protocol converter script error", e);
         }