大型通用电子制造执行系统(MES)

 简介:

        系统参考西门子MOM智能制造Opcenter工业软件制造执行系统Camstar电子套件人机料法环数据建模业务对象和车间生产执行事务逻辑,采用面向对象分层设计与C#编程开发:包含电子制造企业人机料法环业务数据建模实体对象,数据实体持久化映射,数据工厂会话配置,车间生产服务抽象业务逻辑,Web数据建模代理服务,API数据建模业务集成,DB更新升级工具,可配置建模数据控件;业务建模对象字段信息查询,数据建模表单实例筛选过滤,数据建模实例审核追踪,在制品状态跟踪筛选查询,生产历史数据追溯和导出等应用功能;  用户客户端建模实例读取,新增,修改、复制、删除、建模审核履历和引用操作功能;支持数据建模实例版本修改一致性检查,支持可配置表达式动态实时计算,建模主数据和生产历史数据分库存储(读写分离,支持分产品线分库存储);支持产品标签在线设计和模拟打印预览功能。

        系统比较完整保留Camstar MES业务建模对象和车间生产服务的执行逻辑,开发者只需关注业务设计而实现业务功能逻辑只需通过对人机料法环业务建模对象进行简单编程即可; 编程时获取对象即得到该对象数据库对应数据实例,操作对象即操作数据实例,无需通过查询得到该实例操作;制定数据建模和生产执行业务功能代码逻辑顺序和事务提交/回滚机制,面向生产服务编程支持单一/组合/复合的生产业务逻辑可继承、可复用、可重写、可自定义扩展并保持事务一致性;生产服务执行成功后开启新的Session提交保存历史数据,每个生产服务执行产生的历史数据可进行分库存储设定(仅主库/仅历史库/主库和历史库),可根据需求将AP服务设置不同产品线生产历史分库存储业务。支持模拟(Simulation)服务执行完成并回滚事务,通过获取数据进行调试分析(例如模拟标签打印参数表达式计算,模拟设备自动化下发参数计算数据等).

        适用中/大型离散生产制造企业(高科技电子,汽车零部件等),通过使用人机料法环可配置数据建模管理在制品生产业务功能变更;系统开箱即用,满足多工厂数据建模管理,多机种产品柔性生产工艺流程管理和生产控制;满足工厂->车间->产线->工序->机台->工具等多维度业务功能定制需求,采用低代码面向制造业务对象建模和生产服务逻辑开发,支持单服务/复合服务生产业务逻辑统一事务执行,业务逻辑方法可复用可定制和高扩展性,分布式数据代理和应用集群服务,开发门槛低成本低和高可维护性,弱化数据库设计和开发(保留支持数据库存储过程和函数执行),支持.net平台组件和开源库功能应用开发及测试,C#高阶编程方便实现业务功能需求,二次开发敏捷高效。人机料法环业务功能模块可扩展定制开发;支持范式通用Api库,WebApi等接口技术/.net程序库等组件与企业上下游相关业务系统(SAP,APS,QMS,PDM,WMS,AGV,EAP/SCADA,OA,AI)进行数据建模和业务集成;

 

编辑

一. 数据字典

​ mdb数据字典分析 编辑

二. 系统表单

        运用ORM将建模实体生成数据库表和字段类型;分为WIP和History数据库,其中History库用于存储测试历史和明细数据,WIP和History数据库保持同步更新;History库仅保留生产历史明细数据,主数据不做同步. 所有实例表单包含主键字段,NDO实例名字段唯一索引,RDO名+版本字段非聚集唯一索引,保留引用子集合NamedSubentity实例字段外键约束,除主键字段外其余字段不做非空限制;

​ 数据表单 编辑
​ 业务表结构 编辑

三. 系统项目 

              包括Designer建模工具、Comm工具类库、Client建模界面、ID生成规则、ORM数据持久化、Entites建模实体库、Modeling数据建模、ShopFloor生产服务、UIControls建模控件、Api数据集成、WebApi数据代理、App后台集成服务、DB更新工具等; 

​ 系统项目 编辑
​ 部分建模实体 编辑
​ 实体 编辑
​ ER图 编辑

 

​ 车间抽象服务 编辑
​ 在制品抽象服务 编辑
​ Container数据控件 编辑
​ 数据建模控件 编辑

 

​ Container实体信息 编辑
​ ShopFloor实体信息 编辑
​ AP应用服务 编辑
​ DB升级 编辑

四. 数据建模

        系统支持Client界面建模操作,使用鼠标拖拽数据控件至UI界面,配置CDOName和Field以及Label相关属性(默认使用Field读取语言字典显示Caption),系统将建模数据装载\过滤和显示到数据控件;第二种建模方式采用Api进行建模Field对象赋值操作,通过调用WCF服务提交数据建模:读取实例(Load)、新增实例(new)、新增带版本实例(NewRev)、更新实例(Update)、删除实例(Delete)和删除所有版本实例(DeleteAll)服务接口.

​ UI建模设计 编辑

1. 客户端建模

        包含物理建模,制造建模,质量建模,执行建模用户维护功能界面;包含人机料法环数据建模功能界面,支持建模引用和审核追踪查询,Modeling建模角色权限设定,SessionValues设定,Container在制品筛选查询,User菜单配置维护,工作流程(workflow)可视化配置等,支持用户多语言配置和显示, 产品SOP手册文档上传和在线查看操作;

​ 客户端建模操作 编辑
​ 用户多语言 编辑
​ 数据审核查询 编辑
​ 实例引用查询 编辑
​ 生产流程建模 编辑
​ 工步路径选择器设置 编辑

 

​ 用户厂别工序设定 编辑

 

​ 建模标签语言 编辑
​ 建模菜单设置 编辑
​ 数据建模角色权限 编辑
​ 操作手册上传 编辑

2. API数据建模

        发布MESApplicationLib.dll接口库, 通过部署App应用服务来处理C/S或B/S端的数据建模请求,使用ApiClient接口注册约定建模方法或HttpClient代理服务接口提交数据建模功能服务;

public static class Modeling
{public static void EmployeeMaint(this INamedObjectMaint service){var name = "Employee_" + DateTime.Now.ToString("yyyymmddHHmmss");var SessionValues = new Subentity{DataFields = new List<DataField>{SetField.setDataField("Client",123),},NamedObjects = new List<NamedObject>{SetField.setNamedObjectByName("WorkCenter","电子车间"),SetField.setNamedObjectByName("Operation","Inspection"),SetField.setNamedObjectByName("Resource","Feeder 1")}};var inputDatas = new Dictionary<string, BaseField>();inputDatas.Add("Name", SetField.setDataField(name));inputDatas.Add("Description", SetField.setDataField("employee 123"));inputDatas.Add("CanLogin", SetField.setDataField(false));inputDatas.Add("FullName", SetField.setDataField("xxxxxxxx"));inputDatas.Add("SessionValues", SessionValues);IDictionary<string, BaseField> result = new Dictionary<string, BaseField>();var select = service.RequestSelectionValuesEx("", out DataTable data);var load = service.Load("12345", ref result);var update = service.Update("12345", inputDatas);var add = service.New(name, inputDatas);var delete = service.Delete(name);}public static void ResourceGroupMaint(this INamedObjectMaint service){var name = "ResourceGroup_" + DateTime.Now.ToString("yyyymmddHHmmss");var Entries = new SetField<NamedObject>();Entries.setListData = new List<NamedObject>{Entries.addNamedObjectByName("资源2"),Entries.addNamedObjectByName("Feeder 2"),//Entries.deleteNamedObject(1),//Entries.changeNamedObject(0,"资源3")};var inputDatas = new Dictionary<string, BaseField>();//inputDatas.Add("Name", SetField.setDataField("Test"));inputDatas.Add("Description", SetField.setDataField("ResourceGroup 123"));inputDatas.Add("Entries", Entries.getListData);IDictionary<string, BaseField> result = new Dictionary<string, BaseField>();var select = service.RequestSelectionValuesEx("", out DataTable data);var load = service.Load("资源组1", ref result);var update = service.Update("资源组1", inputDatas);var add = service.New(name, inputDatas);var delete = service.Delete(name);}public static void BillOfProcessMaint(this IRevisionedObjectMaint service){var name = "BillOfProcess_" + DateTime.Now.ToString("yyyymmddHHmmss");var revision = "1A";var labelTxnMap = new SetField<Subentity>();var txnMap = new SetField<Subentity>();var BillOfProcessOverrides = new SetField<NamedSubentity>();BillOfProcessOverrides.setListData = new List<NamedSubentity>{BillOfProcessOverrides.addNamedSubentity(null,new BaseField[]{SetField.setNamedObjectByName("ResourceGroup","资源组2"),SetField.setNamedObjectByName("TrainingReqGroup","要求组1"),SetField.setRevisionedObject("Spec","Packing","1",false),new BaseField<Subentity>{ElementName ="LabelTxnMap",Values = new List<Subentity>{labelTxnMap.addSubentity(new BaseField[]{SetField.setDataField("TxnType",5490),SetField.setDataField("LabelCount","1"),SetField.setRevisionedObject("PrinterLabelDefinition","Test","1",false),}),labelTxnMap.addSubentity(new BaseField[]{SetField.setDataField("TxnType",5490),SetField.setDataField("LabelCount","1"),SetField.setRevisionedObject("PrinterLabelDefinition","Test","1",false),}),}},new BaseField<Subentity>{ElementName ="TxnMap",Values = new List<Subentity>{txnMap.addSubentity(new BaseField[]{SetField.setDataField("TxnToUse",5490),SetField.setDataField("Sequence",1),}),txnMap.addSubentity(new BaseField[]{SetField.setDataField("TxnToUse",5490),SetField.setDataField("Sequence",2),}),txnMap.addSubentity(new BaseField[]{SetField.setDataField("TxnToUse",5490),SetField.setDataField("Sequence",3),})}}}),BillOfProcessOverrides.addNamedSubentity(null,new BaseField[]{SetField.setDataField("Name","Test3"),SetField.setRevisionedObject("Spec","Shipping","1",false),new BaseField<Subentity>{ElementName ="LabelTxnMap",Values = new List<Subentity>{labelTxnMap.addSubentity(new BaseField[]{SetField.setDataField("TxnType",1520),SetField.setDataField("LabelCount","2"),SetField.setRevisionedObject("PrinterLabelDefinition","Test","1",false),}),}},new BaseField<Subentity>{ElementName ="TxnMap",Values = new List<Subentity>{txnMap.addSubentity(new BaseField[]{SetField.setDataField("TxnType",1520),SetField.setDataField("Sequence",1),}),}}})};var inputDatas = new Dictionary<string, BaseField>();//inputDatas.Add("Revision", SetField.setDataField("1A"));inputDatas.Add("Base", SetField.setRevisionBaseByName("BOP1"));inputDatas.Add("Description", SetField.setDataField("BillOfProcess 123"));inputDatas.Add("BillOfProcessOverrides", BillOfProcessOverrides.getListData);IDictionary<string, BaseField> result = new Dictionary<string, BaseField>();var select = service.RequestSelectionValuesEx("", out DataTable data);var load = service.Load("BOP", "2.0", ref result);//var update = service.Update("BillOfProcess_20243707113756", "1A", false, inputDatas);var add = service.New(name, revision, inputDatas);var addNew = service.NewRev(name, revision, false, inputDatas);var delete = service.Delete(name, revision);var deleteAll = service.DeleteAll(name);}public static void WorkflowMaint(this IRevisionedObjectMaint service){var name = "Workflow_" + DateTime.Now.ToString("yyyymmddHHmmss");var revision = "1A";var Paths = new SetField<NamedSubentity>();var PathSelectors = new SetField<Subentity>();var Steps = new SetField<NamedSubentity>();Steps.setListData = new List<NamedSubentity>{////移除或更新PathSelectors//Steps.changeNamedSubentity("Assembly", new BaseField[]//{//    new BaseField<Subentity>//    {//        ElementName ="PathSelectors",//        Values = new List<Subentity>//        {//            Paths.deleteSubentity(0),//            Paths.changeSubentity(1,new BaseField[]{ }),//        }//    },//}),////移除或更新Paths//Steps.changeNamedSubentity("Assembly", new BaseField[]//{//    new BaseField<NamedSubentity>//    {//        ElementName ="Paths",//        Values = new List<NamedSubentity>//        {//            Paths.deleteNamedSubentity("Path1"),//            Paths.changeNamedSubentity("Path2",new BaseField[]{ }),//        }//    },//}),////移除或更新Steps//Steps.deleteNamedSubentity("Assembly"),Steps.addNamedSubentity("Assembly", new BaseField[]{SetField.setDataField("Xlocation",30),SetField.setDataField("Ylocation",30),SetField.setDataField("Description","Testing"),SetField.setRevisionedObject("Spec","Assembly","1",false),new BaseField<NamedSubentity>{ElementName ="Paths",Values = new List<NamedSubentity>{Paths.addNamedSubentity("Packing", new BaseField[]{SetField.setDataField("Description","默认路径"),SetField.setWorkflowStep("ToStep","Packing")}),Paths.addNamedSubentity("Inspection_1", new BaseField[]{SetField.setDataField("Description","其他路径1"),SetField.setWorkflowStep("ToStep","Inspection")}),Paths.addNamedSubentity("Shipping_1", new BaseField[]{SetField.setDataField("Description","其他路径2"),SetField.setWorkflowStep("ToStep","Shipping")}),}},new BaseField<Subentity>{ElementName ="PathSelectors",Values = new List<Subentity>{PathSelectors.addSubentity(new BaseField[]{SetField.setWorkflowPath("Path","Inspection_1"),SetField.setDataField("Expression","Container.IsCosmetic"),SetField.setDataField("Description","条件1"),SetField.setDataField("EffectiveFromDate",DateTime.Now),SetField.setDataField("EffectiveThruDate",DateTime.Now.AddDays(7)),SetField.setDataField("EffectiveFromDate",DateTime.Now),SetField.setDataField("EffectiveThruDateGMT",DateTime.UtcNow.AddDays(7))}),PathSelectors.addSubentity(new BaseField[]{SetField.setWorkflowPath("Path","Shipping_1"),SetField.setDataField("Expression","Container.IsShipped"),SetField.setDataField("Description","条件2"),SetField.setDataField("EffectiveThruDate",DateTime.Now),SetField.setDataField("EffectiveThruDateGMT",DateTime.UtcNow)}),PathSelectors.addSubentity(new BaseField[]{SetField.setWorkflowPath("Path","Shipping_1"),SetField.setDataField("Expression","Container.Product.IsSend"),SetField.setDataField("Description","条件3"),SetField.setDataField("EffectiveFromDate",DateTime.Now),SetField.setDataField("EffectiveFromDateGMT",DateTime.UtcNow)}),}}}),Steps.addNamedSubentity("Packing", new BaseField[]{SetField.setDataField("Xlocation",100),SetField.setDataField("Ylocation",30),SetField.setDataField("Description","Testing2"),SetField.setRevisionedObject("Spec","Packing","1",true),new BaseField<NamedSubentity>{ElementName ="Paths",Values = new List<NamedSubentity>{Paths.addNamedSubentity("Inspection", new BaseField[]{SetField.setDataField("Description","默认路径"),SetField.setWorkflowStep("ToStep","Inspection")}),Paths.addNamedSubentity("Shipping_2", new BaseField[]{SetField.setDataField("Description","其他路径1"),SetField.setWorkflowStep("ToStep","Shipping")}),Paths.addNamedSubentity("Packing_2", new BaseField[]{SetField.setDataField("Description","回本尊路径"),SetField.setWorkflowStep("ToStep","Packing")}),}},new BaseField<Subentity>{ElementName ="PathSelectors",Values = new List<Subentity>{PathSelectors.addSubentity(new BaseField[]{SetField.setWorkflowPath("Path","Shipping_2"),SetField.setDataField("Expression","Container.IsShipped"),SetField.setDataField("Description","发货条件1"),SetField.setDataField("EffectiveThruDate",DateTime.Now),SetField.setDataField("EffectiveThruDateGMT",DateTime.UtcNow)}),PathSelectors.addSubentity(new BaseField[]{SetField.setWorkflowPath("Path","Packing_2"),SetField.setDataField("Expression","Container.IsFailed"),SetField.setDataField("Description","回本尊条件"),SetField.setDataField("EffectiveThruDate",DateTime.Now),})}}}),Steps.addNamedSubentity("Inspection", new BaseField[]{SetField.setDataField("Xlocation",130),SetField.setDataField("Ylocation",30),SetField.setDataField("Description","Testing3"),SetField.setRevisionedObject("Spec","Inspection","1",true),new BaseField<NamedSubentity>{ElementName ="Paths",Values = new List<NamedSubentity>{Paths.addNamedSubentity("Shipping", new BaseField[]{SetField.setDataField("Description","默认路径"),SetField.setWorkflowStep("ToStep","Shipping")}),Paths.addNamedSubentity("Assembly_1", new BaseField[]{SetField.setDataField("Description","回首站路径"),SetField.setWorkflowStep("ToStep","Assembly")}),}},new BaseField<Subentity>{ElementName ="PathSelectors",Values = new List<Subentity>{PathSelectors.addSubentity(new BaseField[]{SetField.setWorkflowPath("Path","Assembly_1"),SetField.setDataField("Expression","Container.IsBack"),SetField.setDataField("Description","回首站条件1"),})}}}),Steps.addNamedSubentity("Shipping", new BaseField[]{SetField.setDataField("IsLastStep",true),SetField.setDataField("Xlocation",100),SetField.setDataField("Ylocation",90),SetField.setDataField("Description","Testing4"),SetField.setRevisionedObject("Spec","Shipping","1",true)}),};var inputDatas = new Dictionary<string, BaseField>();//inputDatas.Add("Revision", SetField.setDataField("1B"));//inputDatas.Add("Base", SetField.setRevisionBaseByName("Workflow"));inputDatas.Add("Description", SetField.setDataField(""));inputDatas.Add("Steps", Steps.getListData);IDictionary<string, BaseField> result = new Dictionary<string, BaseField>();var select = service.RequestSelectionValuesEx("", out DataTable data);var load = service.Load("Test", "2A", ref result);var update = service.Update("Test", "1A", true, inputDatas);var add = service.New(name, revision, inputDatas);var addNew = service.NewRev(name, "2A", true, inputDatas);var delete = service.Delete(name, revision);var deleteAll = service.DeleteAll(name);}
}
private void button1_Click(object sender, EventArgs e)
{using (var client = new ApiClient<IQueryService>("F123456", "MES@123", "192.168.3.102", 8080)){using (var service = client.createService("Query")){var sq = service.SQLQuery("select * from spec", out DataTable result1);var uq = service.UserQuery("Query_SpecData", new List<(string parameter, DbType dbType, object value)>{("AutoClose",DbType.Int32,1),("ResourceGroup",DbType.Object,"资源组1")}, out DataTable result2);var ss = service.ExecuteScalar("select specid,specrevision from spec", out object result3);}}using (var client = new ApiClient<INamedObjectMaint>("F123456", "MES@123", "192.168.3.102", 8080)){using (var service = client.createService("ResourceGroupMaint")){//service.SendMessage("建模测试");service.ResourceGroupMaint();}}using (var client = new ApiClient<IRevisionedObjectMaint>("F123456", "MES@123", "192.168.3.102", 8080)){using (var service = client.createService("BillOfProcessMaint")){var sessionId = service.GetSessionId();//service.SendMessage("建模测试");//service.WorkflowMaint();service.BillOfProcessMaint();}}
}

3.Web代理建模

        获取数据建模实例转换json串,用于web前端数据展示和编辑操作;json可读取到两个Subentity层级数据。通过部署基于Http的代理服务处理C/B端建模数据请求,Web端使用前端框架开发建模功能界面,通过webapi接口获取建模实例json数据进行编辑处理后回传实现NDO和RDO数据建模;

private void HttpClientButton_Click(object sender, EventArgs e){try{MessageField.BackColor = Control.DefaultBackColor;MessageField.ForeColor = Control.DefaultForeColor;MessageField.ResetText();using (var client = new HttpClient("F123456", "MES@123")){IDictionary<string, BaseField> inputDatas = new Dictionary<string, BaseField>();//NDOvar tt = client.submitMaintenance("FctoryMaint", OperationType.Load, "工厂2", ref inputDatas);var tt2 = client.submitMaintenance("FctoryMaint", OperationType.New, "工厂3", ref inputDatas);var tt3 = client.submitMaintenance("FctoryMaint", OperationType.Update, "工厂2", ref inputDatas);var tt4 = client.submitMaintenance("FctoryMaint", OperationType.Delete, "工厂2", ref inputDatas);//RDOvar rs = client.submitMaintenance("ProductMaint", OperationType.Load, "Test", "1A", false, ref inputDatas);var rs2 = client.submitMaintenance("ProductMaint", OperationType.New, "Test2", "1.0", false, ref inputDatas);var rs3 = client.submitMaintenance("ProductMaint", OperationType.NewRev, "Test2", "1.2", true, ref inputDatas);var rs4 = client.submitMaintenance("ProductMaint", OperationType.Update, "Test", "1B", true, ref inputDatas);var rs5= client.submitMaintenance("ProductMaint", OperationType.Delete, "Test", "1A", false, ref inputDatas);var rs6 = client.submitMaintenance("ProductMaint", OperationType.DeleteAllRevisions, "Test", "1A", false, ref inputDatas);}}catch (Exception ex){string err = ex.GetBaseException().Message;MessageField.BackColor = Color.Red;MessageField.ForeColor = Color.Yellow;MessageField.AppendText($"{ex.Message}\r\n");}}
​ Json建模实例 编辑

 

4.Label建模打印

        使用BarCode功能菜单设计产品标签,支持文本、活动文本、图片、条形码、二维码和表格等标签内容;配置数据源FieldName通过打印容器标签自动关联参数值进行打印,支持批量和单个标签打印, 支持输出标文件和Bartender等软件做打印功能集成.

​ 标签模板设计 编辑
​ 打印标签定义 编辑
​ 打印单个标签预览 编辑
​ 打印多个标签预览 编辑
​ 打印多个标签PDF 编辑

 

5.Data分厂管理

        同一个数据库实例将人机料法环数据建模进行分厂管控,登录访问者只能针对所属工厂的建模数据进行查询/筛选和维护操作;

​ 启用员工数据分厂 编辑
​ 数据分厂建模实例 编辑

五. 生产服务

        支持开始(Start)创建在制品的产品批次或序列号追踪码,通过编号规则(NumberingRule)建模设置按工厂和客户要求生成在制品条码编号(Container)并关联产品的生产流程(workflow); 在制品进站(MoveIn)和出站(MoveStd)通过工作流程路径设置规则进行验证和判断当前在制品所在工序(Operation)和下一个工序,在制品出站时根据工步(Step)路径选择器(PathSelector)设定人机料法环条件表达式计算决定在制品生成流向,提供多样机种产品柔性化的生成流程控制;

        车间事务(ShopFloor)对象作为基础服务,包含一些基本的生产抽象逻辑实现功能方法,被其他服务继承复用或重写逻辑功能; 在制品服务(ContainerTxn)针对需要产品编码输入验证并执行生产业务抽象逻辑的实现方法; 生产业务逻辑统一服务端执行并保持数据的一致性和有效性.

        系统支持使用表达式Expression计算数据值,应用到生产业务需求场景中: 产品生产流程路由参数化选择判断、产品配方参数/工艺参数动态计算值、产品客制化标签打印参数值、设备自动化动态计算参数值等; 表达式中含二元/多元,逻辑运算符,函数和自定义方法等多种组合计算方式;通过人机料法环建模设置动态表达式计算值,适应产品柔性化生产和数据可配置化实现生产业务需求;

1.创建产品

        创建产品在制品编码,可按照系统建模配置生成指定编号规则在制品; 也可指定编码(外购零部件入/半成品等)或特定的Range号段范围生成在制品编码;在制品工作流程(workflow)支持用户指定或者工单建模指定、产品建模指定、产品大类建模指定配置,重写FinishModifyingEntity方法获取产品标签打印参数配置实现创建产品即可打印生成标签;

​ 创建产品 编辑
​ 定制创建产品即打印标签 编辑

2.搁置产品

        当生产工艺或物料缺陷等问题需要将在制品进行冻结搁置,防止在制不良品继续生产执行;

搁置产品时可设置解除搁置的用户组,满足特定搁置原因时指定用户解除搁置权限;

​ 搁置产品 编辑

3.释放产品

        将已搁置的产品解除搁置状态继续生产执行;

​ 释放产品 编辑

4.查询产品

        查询在制品状态信息,显示当前工作流程和生产工序;

​ 查询在制品状态 编辑

5.产品移入

        产品生产时根据生产流程需要先移入工序管控,例如需要静置等待的生产工序;

​ 产品移入 编辑

6.产品移动

        在制品生产工序出站作业,可根据人机料法环参数配置控制在制品生产工作流程顺序; 产品移动历史将记录工作流程使用的路径名和起止工序,如触发备选路径将记录生效的表达式; 当工序规范使用标签打印配置即过站时生成标签文件;

​ 产品移动 编辑

7.打印标签

        将在制品相关标签进行手动补打功能, 启用模拟开关生成标签参数计算值(不产生历史数据);

​ 打印标签 编辑

8.产品维护

        修改在制品状态数据信息,如工单,产品版本,工厂,单位等信息;

​ 产品维护 编辑

9.非标移动

        修改当前在制品的工作流程和所在工序状态(非正常操作), 当在制品创建或生产流程发生改变,产品无法正常的生产时通过非标移动功能将产品跳转到目标工作流程生产工序;其二是工程验线阶段需要通过非标移动将产品移动到测试工序进行测试效验等;

​ 非标移动 编辑

10.批量搁置

        将在制品进行批量搁置操作.

​ 产品批量搁置 编辑

11.嵌套服务

        在制品生产业务涉及多个服务嵌套执行事务,满足生产定制业务需求; 例如创建产品>>产品移入>>产品移动>>产品搁置>>产品释放等子服务同步执行,子服务可以在一个主服务中执行或分布嵌套其他子服务中;每个服务执行失败将报错提示并回滚事务,只有所有服务执行成功才提交事务,历史数据将记录主服务和关联各子服务执行顺序.

​ 嵌套子服务执行 编辑

12.请求数据

        在制品生产业务执行完成后需要获取生产批次和数量进行SAP实时报工,实时AGV产品生产工序搬运自动化下发,或其他系统数据下发集成等需求,通过执行服务使用Lamdda表达式树请求参数得到对应的值字典集合;

​ 生产服务执行数据请求 编辑

 

六. 数据追溯

        1.建模审核追踪

                用户使用客户端或Api进行数据建模将会记录更改ChangeHistory和建模审核明细 ModelingAuditTrail(需启用AuditTrail)历史数据;每一个建模实例都会存在一条对应的ChangeHistory记录,通过客户端界面审核追踪可查询;当实例被删除后也可查询建模审核明细.

​ 建模审核追踪 编辑

        2.生产历史记录

                追踪产品批次(Container)在生产过程执行的车间事务(ShopFloor)做产生的历史数据(HistoryDetials)追溯;当产品批次被系统创建(Start),产品入站(MoveIn),产品过站(MoveStd)、产品返工(Rework)、产品冻结与释放(Hold/Release)等车间事务执行值记录主线(HistoryMainLine)和每个事务定义将要被记录的历史明细信息; 系统会将事务主线HistoryMainLine和HistoryDetials进行关联以便追踪每个车间事务所产生的历史数据.系统将事务执行产生的History进行分库存储,实现读写分离; 可根据ShopFloor对象设定保存历史的存储位置:仅WIP库,仅History库(生成新的InstanceId),WIP和History库(和WIP库同InstanceId)选项即可,执行完WIP生产事务成功后将历史分库存储。

​ WIP和History库 编辑

 

​ 仅History库 编辑

 

        3.在制品追踪

                使用WIP查询功能表单多维度汇总筛选查询产品明细: 工厂,工单,产品,生产状态,工作流程等数据信息,按照不同数据分类分组汇总查询和导出Excel;

​ 在制品查询 编辑
​ 导出Excel报表 编辑

        4.在线历史追溯

                使用History在线查询测试历史主线记录:支持在制品,工厂,产品和工序等查询条件过滤历史,支持生产服务历史明细查询;支持表头列过滤。过站MoveHistory记录工作流程中工步备选路径被激活时的表达式PathExpression,系统建模打印标签历史LabelHistorySummary记录标签参数名,计算值和运算表达式;

​ HistoryMainline在线查询 编辑
​ History明细查询 编辑

        5.数据实例表单

                系统将人机料法环建模实例数据表查询权限下放至用户端,可直观查看建模对象存储到数据库表的建模实例数据;系统根据ORM实体映射关联自动匹配建模对象和数据关系表字段,用户在查询时自动生成SQL语句获取建模实例并显示数据视图;支持表头列过滤,数据分组排序过滤和实例数据导出等功能,支持用户配置多语言显示表头。

​ 产品建模实例 编辑
​ 工艺流程实例 编辑
​ 工艺清单实例 编辑

七. 安装部署

       配置WIP和History数据库连接字符串,使用DBUpdaye更新数据库生成数据表单;配置MESAppService服务名,描述信息并启动服务;

 

八. 开发维护

        设置业务建模实体属性,特性和数据持久化映射,使用DBUpdate工具同步更新WIP和History数据库表结构;编译生成建模实体进行数据建模功能接口测试验证;升级WebApi代理服务,WCF应用服务;发布升级客户端/Web端功能系统;面向生产服务业务逻辑开发.

1.数据建模

        按照数据建模定义的对象实体,增加建模字段Field和数据库持久化映射关联;打开Visual Studio开关工具并新增WinForm建模功能界面,引用MES.UI.Controls程序集加载数据控件,使用鼠标拖拽控件到界面配置CDOName和FieldName属性即可加载数据实例,或使用委托事件OnGetValue、SelectionValues自定义加载建模实例,使用DataChange实现数据更改触发事件.

​ 建模页面 编辑

2.服务开发

        采用面向对象设计与编程开发,只需对业务建模对象实体和属性进行修改更新操作即实现业务功能;创建Service的对象并继承ShopFloorService或ContainerTxnService抽象服务对象,复用或重写业务逻辑方法实现具体的业务功能;执行服务时将创建单个Session事务单元处理提交修改的数据请求,可定制业务功能开发,提交服务报错将显示调用方法和错误代码行;方法中使用throw new exception("消息...")可进行Session事务回滚并返回消息;Session事务提交成功后自动生成SQL脚本统一提交数据库实例数据和记录历史数据.支持.Net各类组件和开源库功能应用开发和测试,使用C#高阶编程实现业务功能需求。

​ 抽象车间服务 编辑
​ 抽象产品服务 编辑
​ 在制品过站执行调试 编辑

3.启用模拟

        启用模拟时提交服务将进行事务回滚,执行结果返回成功但不会存储历史数据和实例更新数据;通过从服务对象中获取这些数据进行分析决策,其他进站、出站、车间服务等可以使用启用模拟的方式去获取这些数据进行系统功能调试和分析;

​ 打印标签模拟 编辑

4.系统升级

        DB升级:编译Entites和Mappings后使用数据库升级工具DBUpdate将在制品库表结构进行更新并自动同步历史库表结构更新;ShopFloor服务升级: 编译Services和WebProxy后更新最新dll库即可;

 

5.系统运维

        

九. 系统集成

        使用开放API编程将PLM,SAP,PDM,WMS,SCADA,OA等上下游业务系统数据集成,包括产品/物料主数据,BOM和生产工艺参数,制造订单和生产流程,仓库备料和发料,设备运行参数和数据采集等通过接口将需要的生产相关资料下发至MES数据建模; 生产执行业务集成,往下游系统集成,如EAP和AGV等可以通过定制开发生产服务实现动态参数建模配置和表达式运算值下发业务系统集成。


            using (var client = new ApiClient<IinquiryService>("F123456", "123456", "localhost", 8080)){using (var service = client.createService("ViewContainerStatus")){var inputDatas = new Dictionary<string, BaseField>();inputDatas.Add("Container", SetField.setContainer("工厂C2020000006L", ""));var rs = service.Inquiries(inputDatas, new List<string> { "Container.WhereUsed", "Container.Product.VendorItems", "Container.Workflow.Steps" }, out IDictionary<string, BaseField> responseDatas);}}using (var client = new ApiClient<IShopFloorService>("F123456", "123456", "localhost", 8080)){using (var service = client.createService("Hold")){var inputDatas = new Dictionary<string, BaseField>();inputDatas.Add("Container", SetField.setContainer("工厂C20200000061", ""));inputDatas.Add("HoldReason", SetField.setNamedObjectByName("生产搁置"));var rs = service.SubmitTransaction(inputDatas, new List<string>(), out IDictionary<string, BaseField> responseDatas);}using (var service = client.createService("Start")){var inputDatas = new Dictionary<string, BaseField>();var Details = new Subentity{DataFields = new List<DataField>{SetField.setDataField("AutoNumber",true),},Containers = new List<MESApplicationLib.Object.Container>(),NamedObjects = new List<NamedObject>{SetField.setNamedObjectByName("Level", "SS Level"),SetField.setNamedObjectByName("Owner", "Production"),SetField.setNamedObjectByName("StartReason", "NORMAL"),SetField.setNamedObjectByName("MfgOrder", "测试工单1")},RevisionedObjects = new List<RevisionedObject>{SetField.setRevisionedObject("Product","TEST","1D",false)}};inputDatas.Add("Details", Details);//var rs = service.SubmitTransaction(inputDatas);var rs = service.SubmitTransaction(inputDatas, new List<string> { "Details.ContainerName", "Container.Product.VendorItems", "Container.Workflow.Steps" }, out IDictionary<string, BaseField> responseDatas);//var rs = service.SubmitTransaction(inputDatas, new List<string> { "Container.Spec", "Details.Product.Name","Container.CurrentStatus.WorkflowStep" }, out IDictionary<string, BaseField> responseDatas);}}

九. 下载地址

电子制造通用MES+低代码可配置可扩展+多语言+并行工序生产流程+生产服务执行+数据分厂管理+标签设计与打印

https://download.csdn.net/download/weixin_43126602/89730762


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/904688.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

物料需求波动大、生产计划变化频繁?一文教你用工厂ERP系统MRP精确计算生产物料!

今天咱们来聊一聊一个大多数工厂都会遇到的问题: 物料需求波动大 和 生产计划变化频繁 。 这些问题可能让你在生产过程中经常“踩雷”,比如物料没采购够,生产停工; 或者物料买多了,库存积压,浪费了钱。有没有办法避免这些问题呢? 答案是: 有 !那就是通过工厂的 ERP系统…

docker使用GPU总结

在docker容器中使用显卡 一 docker19.03以前的事情 1.1 指定显卡硬件名 最初的容器中使用显卡,需要指定硬件名。经历了两种方式使用lxc驱动程序运行docker守护进程,以便能够修改配置并让容器访问显卡设备(非常麻烦,参考链接中最久远的回答)Docker 0.9中放弃了lxc作为默认执…

掌握 K8s Pod 基础应用 (二)

Pod生命周期 我们一般将pod对象从创建至终的这段时间范围称为pod的生命周期,它主要包含下面的过程:pod创建过程运行初始化容器(init container)过程运行主容器(main container)容器启动后钩子(post start)、容器终止前钩子(pre stop)容器的存活性探测(liveness prob…

叉车人员防撞报警系统

叉车人员防撞报警系统采用机器视觉图像感知技术,通过人工智能深度学习技术,对行人和车辆的精确检测,叉车人员防撞报警系统实现对人体和车辆检测分析识别,在机器视觉图像景中,通过特征识别算法建立人体和车辆图像模型,完成自动识别目标,并能以视觉图像智能分析精确区分干…

课堂在线点名助手

适合老师上课随机提问学生的小工具。前情概要 为提高程序的普适性,学生姓名用学号代替。 在线点卯在线提问点名助手body0 { font-family: Arial, sans-serif; background-image: url(https://img2024.cnblogs.com/blog/992978/202503/992978-20250324092106498-1518746661.jpg…

随堂笔记之Java方法

此内容源自B站狂神说Java基础的课后笔记与总结,用于复习和查看,因此写得比较简陋,不太适合萌新学习 方法定义方法调用 调用方法:对象名.方法名(实参列表)方法返回一个值的时候,方法调用通常被当做一个值 方法返回值是void,方法调用是一条语句*值传递和引用传递: Java全…

3.24

Android Studio 启动模拟器出现“Timed out after 300seconds waiting for emulator to come online“解决方案 问题: Timed out after 300seconds waiting for emulator to come online.**解决方法: 检查自己的Emulator是否是最新版本,如果不是检查更新到最新

使用ESP32的语音到文本转换

ESP32 + INMP441麦克风+ SD卡+ Deepgram API =语音到文本只需3秒!即时记录、存储和转录。现在就试试! 最快!使用ESP32板的语音到文本转换语音转文本技术改变了许多项目的游戏规则。从在智能家居中实现免提控制到为残疾人创建无障碍解决方案,将口语转换为文本的能力打开了无限的…

SNeP软件计算有效群体大小

001、官网: https://sourceforge.net/projects/snepnetrends/002、脚本: SNeP1.1 -ped sample_name.ped -map sample_name.map -threads 10 -ld -out ./sample_name003、结果文件:。

2025.3.28(周五)

android实验二第三部分 事情处理 1. 点击事件 (OnClickListener) 方法:setOnClickListener(View.OnClickListener listener) android:onClick(在 XML 中使用) 核心功能:处理按钮、文本、图片等控件的 单击事件。 使用场景:按钮提交、页面跳转、功能触发等。 2. 长按事件 (…

关于原生小程序canvas标签始终显示再最上层问题

官方说明: https://developers.weixin.qq.com/miniprogram/dev/component/native-component.html 解决方法:将canvas正常绘制 对canvas进行定位,远离手机屏幕显示区域 将canvas转换为img图片,将转换后的图片进行展示 如果图片清晰度不够,则将canvas成倍的绘制,将转换后的…

Particle Asset OTA 如何实现远程

问题 用粒子平台部署更新到你的舰队是很容易的。但是,当您的产品包含其他组件(如ML模型、显示器、协处理器、证书或图像和声音等媒体)时,远程管理更新就变得更具挑战性。传统的方法通常需要物理访问,这可能耗时、昂贵,而且在规模上不切实际。解决方案 粒子资产OTA使您能够轻…