IT数采配置
IoT边缘服务针对具体行业场景的设备/系统数据采集,提供了丰富的行业插件能力,对接IT数据的系统。
IT数采模板管理
数据源模板描述了数据源配置项的元数据,用户在配置数据源之前,需要先导入数据源模板。IoT边缘服务当前已经预置通用数据源模板,可以直接使用,系统也支持用户自定义导入模板。
本实验演示IT&OT融合场景实践操作,配置数据源模板时,直接选用系统预置的数据源模板。
查看数据源模板
- 进入IoT边缘控制台,选择左侧导航栏“IoTEdge_子系统数采BCP演示-0118”,单击节点进入详情页。 进入页面,选择之前创建的边缘节点
- 选择 ,查看系统预置的数据源模板。
数据源管理
数据源在边缘节点下唯一,是数据源模板的实例化,提供IT数据的系统有SRM、ERP、MES、数据库等。
本实验演示IT&OT融合场景实践操作,将添加两个数据源。
创建数据源
- 进入IoT边缘控制台,选择左侧导航栏“IoTEdge_子系统数采BCP演示-0118”,单击节点进入详情页。 进入页面,选择之前创建的边缘节点
- 选择“保存并下发”,平台将新增的数据源下发到MES子系统。
,添加第一个数据源ERP-API,单击
- 数据源标识:ERP-API
- 数据源名称:ERP-API
- 数据源模板:选择“通用数据源-API”
- 服务URL:http://120.46.132.171:9000
- 添加第二个数据源MES-API,单击“保存并下发”,平台将新增的数据源下发到边缘侧。
- 数据源标识:MES-API
- 数据源名称:MES-API
- 数据源模板:选择“通用数据源-API”
- 服务URL:https://dlp-uatbe.mgm-iot.com
选择“保存并下发”时,平台将新增的数据源下发到边缘侧。
选择“确认”时,此时配置的数据源仅存在云平台,未下发到边侧,后续下发操作可以在数据源列表找到该数据源完成。
集成配置
集成配置模板是描述特定IT系统对接的集成配置,在进行集成配置前,用户需先导入集成配置模板。
本实验演示IT&OT融合场景实践操作,将导入本地准备好的集成配置模板。
创建集成配置
- 进入IoT边缘控制台,选择左侧导航栏“IoTEdge_子系统数采BCP演示-0118”,单击节点进入详情页。 进入页面,选择之前创建的边缘节点
- 选择“保存并下发”平台将数据同步下发到MES子系统。 ,配置完毕后,单击
- 集成配置标识:MES-ERP-WorkPlan
- 上传模板配置:直接将ERP-MES-template.json示例中的代码复制到本地的笔记本中保存为.json格式,上传至集成配置
- MES-华为演示(YZ):MES-API
- ERP-华为演示:ERP-API
- YZtoken请求头:默认值
- 产品同步周期(分钟):默认值
- 同步周期(分钟):默认值
- 修改工作列表:默认项
{ "config_values": [ { "crypted": false, "name": "YZtoken请求头", "value": "{\"Authorization\":\"Basic aUZ2QTExRndVWlRzdGVJZXFRVzYzTm1XeUxhdlVvYk06alNZTkc5VVBzUXJwQ2hqRjE0QnJyUlRDYm15SXI4dnQ=\",\"Content-Type\":\"application/x-www-form-urlencoded\"}", "key": "YZtoken请求头" }, { "crypted": false, "name": "产品同步周期(分钟)", "value": "14400", "key": "产品同步周期(分钟)" }, { "crypted": false, "name": "同步周期(分钟)", "value": "14400", "key": "同步周期(分钟)" }], "jobs": [ { "cron": "0/20 * * * * ?", "output": { "scriptContent": "importClass(com.bsi.utils.HttpUtils);\nimportClass(com.bsi.utils.JSONUtils);\nimportClass(com.bsi.md.agent.datasource.AgDatasourceContainer);\n/**\n * @description 输出节点默认执行函数\n * @param context\n * context.env:参数信息map,获取参数名称为name的数据示例:context.evn.get(\"name\")\n * @param data 需要保存的数据\n */\nfunction output(context, data) {\n log.info(\"输出端数据:{}\", data);\n var headerMap = context.getParams().get(\"YZtoken请求头\");\n var host = context.outputConf().host;\n var token = getToken(host, headerMap, null);\n if (token == null) {\n log.error(\"getToken()为空,获取token失败\");\n return null;\n }\n\n var headerMaps = {\n \"Content-Type\": \"application/json;charset=UTF-8\",\n \"Authorization\": \"bearer \" + token\n }\n var path = context.outputConf().path;\n //var dataArray = JSONUtils.parseArray(data);\n var allSuccess = true;\n var successNum = 0;\n var errorNum = 0;\n data.forEach(\n function (o) {\n log.info(\"o:{}\",JSON.stringify(o))\n var httpResults = HttpUtils.request('POST', path, headerMaps, JSONUtils.toJson(o));\n var resultStr = httpResults.getResult();\n var resCode = httpResults.getCode();\n if (resCode != 200) {\n log.error(\"获取token失败,请检查token接口及调用参数\");\n allSuccess = false;\n errorNum++;\n }else{\n successNum++;\n }\n log.info(\"result:{}\", resultStr);\n }\n )\n log.info(\"任务执行完毕,任务执行情况:{},成功次数:{},失败次数:{},成功率:{}%\",allSuccess,successNum,errorNum,(successNum*100)/(successNum+errorNum));\n}\n\nfunction getToken(host, headerMap, body) {\n if (host == null) {\n log.error(\"host为空,请检查数据源是否下发成功或数据源是否正确\")\n return null;\n }\n var url = host + \"/oauth/token?grant_type=client_credentials\";\n var httpResult = HttpUtils.request('POST', url, JSONUtils.toMap(headerMap), JSONUtils.toJson(body));\n var resultStr = httpResult.getResult();\n var result = JSONUtils.parseObject(resultStr);\n var resCode = httpResult.getCode();\n log.info(\"httpResult::{}\",httpResult)\n if (resCode != 200) {\n log.error(\"获取token失败,请检查token接口及调用参数\");\n return null;\n }\n var token = result.getString(\"access_token\");\n log.info(\"token:{},result:{}\", token, result);\n return token;\n}", "classify": "out", "path": "/opendata/v1/erp/roduction/plan", "ds_key": "266", "id": 2665, "type": "apiCall" }, "input": { "scriptContent": "/**\n * @description 输入节点默认执行函数\n * @param context\n * context.env:参数信息map,获取参数名称为name的数据示例:context.evn.get(\"name\")\n * @return 返回需要的数据\n */\nimportClass(com.bsi.utils.DBUtils);\nimportClass(com.bsi.utils.JSONUtils);\nimportClass(com.bsi.utils.HttpUtils);//#\nimportClass(com.bsi.utils.DateUtils)\nfunction input(context){\n log.info(\"MES(YZ)-生产计划/工单【输入】 start\")\n var globalConfig = context.getParams()\n var repairObj = globalConfig.get(\"repairParam\")\n if(repairObj == null){\n repairObj = {}\n }\n var startTime = repairObj['startTime']\n var preTime = context.getParams().get(\"生产计划同步周期(分钟)\");\n if(preTime==null){\n preTime = 0 ;\n }\n var timeType = \"yyyy-MM-dd HH:mm:ss\";\n\n if(startTime == null){\n startTime = DateUtils.preMinuteForNow(preTime,timeType);\n }\n var endTime = repairObj['endTime']\n if(endTime == null){\n endTime = DateUtils.nowDate(timeType);\n }\n var param = {\n \n }\n\n var path = context.inputConf().path\n\n log.info(\"调用源端接口,path:{},body:{}\",path,null)\n var httpRes = HttpUtils.request(\"POST\",path,null,null)\n log.info(\"---httpRes:{}\",httpRes)\n log.info(\"调用源端接口返回code:{},返回值{}\",httpRes.code,httpRes.result)\n\n var resObj = JSON.parse( httpRes.result )\n log.info(\"调用源端接口查询数据结果:{}\",JSON.stringify(resObj.data))\n log.info(\"MES(YZ)-生产计划/工单【输入】 end\")\n return resObj.code==200?resObj.data:null\n\n}", "classify": "in", "path": "/workingPlan20", "ds_key": "267", "id": 2664, "type": "apiQuery" }, "transform": { "scriptContent": "/**\n * @description 转换节点默认执行函数\n * @param context\n * context.env:参数信息map,获取参数名称为name的数据示例:context.evn.get(\"name\")\n * @param data 需要转换的数据\n */\nimportClass(com.bsi.utils.JSONUtils);\nimportClass(com.bsi.utils.XmlUtils);\nfunction transform(context, data){\n log.info(\"MES(YZ)-生产计划/工单【转换】 start\")\n var arr=[]\n JSON.parse(data).forEach(function(v) {\n var head = {\n //\"thirdId\":\"thirdId-909\",\n //\"thirdProductId\":\"thirdId-209\",\n //\"orderNumber\":\"20210709005\",\n //\"startDate\":\"2021-01-16\",\n //\"endDate\":\"2021-02-23\",\n //\"comments\":\"bz\"\n\n \"thirdId\": v.thirdid,\n \"thirdProductId\": v.thirdproductid,\n \"orderNumber\": v.ordernumber,\n \"startDate\": v.startdate,\n \"plannedCount\":v.plannedcount,\n \"endDate\": v.enddate,\n \"comments\": v.comments\n\n \n\n }\n arr.push(head)\n })\n\n\n\n log.info(\"arr:{}\",JSON.stringify(arr))\n log.info(\"MES(YZ)-生产计划/工单【转换】 end\")\n return arr;\n}", "classify": "transform", "id": 2666, "type": "scriptChange" }, "name": "MES-生产计划-API", "id": 2664 }], "name": "MES-ERP", "id": 208, "data_sources": [ { "name": "MES-华为演示(YZ)", "key": "266" }, { "name": "ERP-华为演示", "key": "267" }] }