跳转至

OEM Template

这是一个针对OEM 单机设备的 FTOptix 项目模板,预置多个功能组件。后台集成WebServer,为使用系统提供Web扩展功能,包括:Charts,3D Model,3D架构图,表单管理,手写签名

1.功能特性

  • RA Library: 集成 RA的 Device Library内的面板,包括:Machine Builder,Power Device,IO Device,Network Device,等...
  • UI Component: 包括单机HMI常用的UI组件/控件 : 文件管理,数据库管理,用户管理,配方管理,集合控件,树形控件,Svg图表,多页标签
  • Report Pro: 这是一个工具集,实现复杂的图表 Report,并以PDF方式输出。图表库可使用 ECharts Library
  • WebServer: 使用TCP/IP协议栈实现的Web服务,包括:Http,Websocket
  • Charts(图表服务) : 支持 ECharts、Apex 图表库,使用 ajax方式更新数据
  • 3D Model(三维模型展示服务):提供3D web应用的后台管理功能,并提供标准通讯协议栈,用以控制3D场景切换,相机控制,实时数据更新,用户操作反馈
  • FormIO(表单服务):集成Form.IO的前端部分,Optix提供后台管理,包括表达的创建,存储,录入,数据保存等。
  • Signature(手写签名):在画布上手写内容,并保存为图像,可用作用户验证或数据审批的补充手段。
  • 3D architecture diagrams(三维架构图) : 前端渲染iCraft的3D文件,并数据的实时交互。

2.项目架构

  • UI
  • Screens
  • StyleSheets:项目内的样式文件
  • Widgets: 自定义的控件
  • Components: 自定义的组件及相关依赖的控件
  • Windows:项目主窗口
  • Layouts:UI布局框架
  • Pages:项目中所有的实体界面
  • Dialogs:对话框窗口
  • Template:基础页面的模板
  • RA Library:RA Device Library
  • Device Settings Widget:Optix Panel / EEC 硬件性能参数的查看UI
  • NetLogic 包括基础组件的初始化工作,以及一个数值模拟生成的功能
  • WebServer 项目所有 WebServer实例节点,每个服务分开,可单独设置及控制







3.组件介绍

WebServer 与 Optix 的结构

通过 TCP Protocol协议栈,实现WebServer,以线程方式生存在Optix进程中。WebServer实现以下协议: - HTTP: - WebSocket

功能包括:Static File 访问,function 路由, GET/POST 方法

基本路由 template :

{http/https}://{host}:{port}/{controller}/{action}?{query}
  • host : web server 开放的 ip
  • port : web server 开放的 port
  • controller : 自定义的控制器类,继承于 HttpController
  • action : 自定义的 api function 名称

Server 实现的示例


    public class ChartController : HttpController
    {

        private readonly ChartEnvironment env;

        private readonly string indexHtml;

        //构造函数
        public ChartController(ChartEnvironment env)
        {

            this.env = env;

            var filepath = Path.Combine(env.WebRootPath, "apex_chart.html");
            if (File.Exists(filepath))
            {
                var content = File.ReadAllText(filepath);
                indexHtml = content;
            }
            else
            {
                indexHtml = string.Empty;
            }

        }


        //GET {controller}/home
        //return html file
        [HttpMethod(HttpMethodType.GET)]
        public DotNetWebServer.IResult Home()
        {

            if (!string.IsNullOrWhiteSpace(indexHtml))
            {
                return new DotNetWebServer.TextResult(indexHtml, "text/html");
            }
            else
            {
                return new DotNetWebServer.TextResult("content not found", "text/html");
            }

        }

        //POST {controller}/getoption
        //return chart option 
        [HttpMethod(HttpMethodType.POST)]
        public DotNetWebServer.IResult GetOption()
        {
            var dto = JsonConvert.DeserializeObject<ChartRequestDto>(Request.Body);
            if (dto != null)
            {
                var chartname = dto.Chart;
                if (chartname.StartsWith("refid_"))
                {

                    var guid = chartname.Substring("refid_".Length);

                    var guidString = guid.Replace('_', '-');
                    NodeId nodeId = NodeId.Of(9, Guid.Parse(guidString));

                    var node = InformationModel.Get(nodeId);
                    if (node == null)
                    {

                        Log.Warning("chart server", $"not found");
                    }

                    var logic = node.GetByType<NetLogicObject>();
                    logic.ExecuteMethod("GetChartOption", new object[] { }, out var outputArgs);
                    return new DotNetWebServer.TextResult(outputArgs[0] as string, "text/html");

                }
                else
                {

                    var filepath = Path.Combine(env.TemplateRootPath, chartname + ".json");
                    if (File.Exists(filepath))
                    {
                        var tpl = File.ReadAllText(filepath);
                        return new DotNetWebServer.TextResult(tpl, "text/html");

                    }
                    else
                    {
                        filepath = Path.Combine(env.TemplateRootPath, "demo.json");
                        var tpl = File.ReadAllText(filepath);
                        return new DotNetWebServer.TextResult(tpl, "text/html");
                    }
                }


            }
            else
            {
                var filepath = Path.Combine(env.TemplateRootPath, "demo.json");
                var tpl = File.ReadAllText(filepath);
                return new DotNetWebServer.TextResult(tpl, "text/html");
            }
        }

        //POST {controller}/getdata
        //return chart data
        [HttpMethod(HttpMethodType.POST)]
        public DotNetWebServer.IResult GetData()
        {
            var rsp = new ChartResponseDto();
            var dto = JsonConvert.DeserializeObject<ChartRequestDto>(Request.Body);
            if (dto != null)
            {
                var chartname = dto.Chart;

                if (chartname.StartsWith("refid_"))
                {
                    var guid = chartname.Substring("refid_".Length);

                    var guidString = guid.Replace('_', '-');
                    NodeId nodeId = NodeId.Of(9, Guid.Parse(guidString));

                    var node = InformationModel.Get(nodeId);
                    if (node == null)
                    {

                        Log.Warning("chart server", $"not found");
                    }

                    var logic = node.GetByType<NetLogicObject>();
                    logic.ExecuteMethod("GetChartData", new object[] { dto.Query }, out var outputArgs);

                    return new DotNetWebServer.TextResult(outputArgs[0] as string, "application/json");
                }

            }

            return new DotNetWebServer.JsonResult(rsp);
        }






    }


系统结构:

配置项:

参数 数据类型 作用
Port int web服务的端口 max:65535
WebRoot string web 主目录

Chart Server / Chart Browser

图表服务:提供前端浏览器提交的图表数据服务,包括html,css,js等资源响应,GET/POST HttpMothod,可保留所有前端库的功能.

时序图:

sequenceDiagram participant B as 浏览器 participant S as 服务 participant O as Optix B ->> S : [Get]:url with paramter and nodeid activate B S -->> B : Return HTML deactivate B B ->> S : [Post]:GetChartOption (NodeId) activate B S ->> O : 根据NodeID,Invoke对应的处理程序 O ->> S : 返回配置,计算数据 S -->> B: Return Option S -->> B: Return Data deactivate B loop 周期定时 B ->> S : [Post]:GetChartData(query and nodeid) activate B S ->> O : 根据NodeID,Invoke对应的处理程序 O ->> S : 返回计算数据 S -->> B: Return Data deactivate B end

Chart Browser

配置参数:

名称 数据类型 说明
lib string 使用的图表库 apex / echarts
background string 背景色 ,默认 :ffffff
autofresh bool 是否自动刷新
period int 自动刷新周期,单位秒
option string 图表的option

实例化:

UI : ChartBrowser (Type)

需要在ChartBrowser下层,新建NetLogic。基类修改为:ChartHandleLogic。 重载函数 GetChartData

示例:

public class PageProduct_chart1_RuntimeNetLogic : ChartHandleLogic
{
    public override void Start()
    {
        // Insert code to be executed when the user-defined logic is started
        base.Init();
    }

    public override void Stop()
    {
        // Insert code to be executed when the user-defined logic is stopped

    }
    [ExportMethod]
    public override void GetChartData(string query, out string data)
    {
        //base.GetChartData(query, out data);
        var rnd = new Random(DateTime.Now.Second);
        var data1 = new List<float>();

        for (int i = 0; i < 5; i++)
        {
            data1.Add(rnd.NextSingle()*4 + 6.0f);

        }

        var rsp = new ChartResponseDto();
        rsp.updateSeries = new object[] { new {data = data1}};
        data = JsonConvert.SerializeObject(rsp);

    }

}


Collection控件

以数据模型的方式,自动呈现N个UI组件,免去手动创建UI。在UI容器中,根据Model节点内的子节点,及节点的类型的对应关系,自动化创建对应的UI组件,并进行关联。

配置参数:

名称 数据类型 说明
Model Alias 需要呈现的Model节点
UITypeConverter Alias UI Type 与数据Type的对应关系的节点

UITypeConverter:

Type:Object

每个元素是 Alias,Name是 数据类型的名称,Alias指向对应的 UI Type。 如果需要在UI实例化时进行别名赋值,需要把对应 UI的Alias Name 设置

样例:


Tree 控件

为了呈现一些结构化数据,比如 设备拓扑,配方/参数,菜单导航,需要树形控件。 此控件可根据 Model节点的结构,使用 Optix原生控件生成树形内容,并支持折叠/展开,选中

UI组件:

  • TreeView : 主控件
  • TreeNode_Accordion : 可折叠的TreeItem组件
  • TreeLeafNode_1 : TreeItem 组件

Model 结构:

  • Tree根节点
  • V1 [Leaf]
  • V2 [Leat]
  • Node1 [Node]
    • V1 [Leaf]
    • V2 [Leat]
    • Node1_1 [Node]
    • Node1_2 [Node]
  • Node2 [Node]

User And Group 管理

新建,删除,编辑用户,用户移入/移出 用户组

配置参数:

名称 数据类型 说明
Users Node Pointer Users Folder
Groups Node Pointer Groups Folder
ExUser string 不显示的用户
ExGroups string 不显示用户组
Indent 10

Sqlite Database 管理

备份数据库,删除数据库,清空数据库

配置参数:

名称 数据类型 说明
BackupDirectory string 备份数据库目录
Store Node Pointer sqlite store

Report Pro

使用 FTOptix原生 Report组件功能,生成 带 图表的 报表。图表可使用原生控件 ,ECharts, 1D/2D条码。 外部图表内容需使用脚本 生成 svg,再用 图片控件 Image引用并显示。

功能逻辑图

graph LR A[触发] B[数据计算 NetLogic] C[图表生成并写入本地] D[调用报表生成 .PDF] E[webBrowser显示PDF] A --> B --> C --> D --> E
graph TD A[触发 传入查询条件] B[数据计算 NetLogic] C[图表生成并写入本地] D[调用报表生成 .PDF] E[webBrowser显示PDF] A --> B --> C --> D --> E

FTViewer

这是一个基于 E3D进行3D可视化设计的模块,在设备仿真验证后,对场景模型进行再利用。 支持的动画类型及功能: - 平移 X Y Z - 旋转 X Y Z - 颜色变换 ColorMapper - 3D物体的点击,并把物体信息反馈给Optix

设置方法共三步:

1.在optix中,建立 Model 用来对动画变量的组织

2.运行 E3D plugin FTViewer,进行模型动画的绑定,并导出文件 [xxx.json]

3.E3D 场景导出为 FBX, [xxx.fbx]

运行效率:

  • CPU : 50%
  • Temp. : 65%

实机效果: