大型通用电子制造执行系统(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>();
//NDO
var 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);
//RDO
var 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
大型通用电子制造执行系统(MES)的更多相关文章
- 国际制造执行系统(MES)应用与发展
某些专家认为,当今制造业的生存三要素是信息技术(IT).供应链管理(SCM)和成批制造技术.使用信息技术就是由依赖人工的作业方式转变为作业的快速化.高效化,大量减少人工介入,降低生产经营成本:供应链管 ...
- MES制造执行系统
mes : Manufacturing Execution System 制造执行系统 起因:ERP系统和底层设备之间出现了断层. 包括资源管理,生产调度,单元分配,生产跟踪,性能分析,文档管理,人 ...
- 工厂想采购一套信息化生产执行系统mes,不知道用哪家比较好?
好的信息化生产执行系统MES多的是,但是否适用于贵工厂那就不得而知了,要知道,不同行业.不同产品.不同规模的工厂用同一套系统效果呈现出来都不一样的,所以匹配很重要,个性化差异化.变化性等决定了一个工厂 ...
- 时光如梭,MES生产制造执行系统上线2周年--->2016.08,发个博客展示一下系统的主要功能!
以下程序是系统当中的主要功能信息,一些相对简单功能就不在此处展示了. 1.模具基础资料Excel导入与模具资料手动更新功能.友情提示:为了避免不必要的麻烦已经将部分信息打码.! 2.配方资料Excel ...
- C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 区域管理功能增强(电子商务方向)
由于公司是面向全国服务的.全国各地都有分公司,需要管理到覆盖全国的各种业务,各种业务系统信息系统的数据都需要规范化. 公司开展网络订单功能,在全国范围内实现网络下单.提高工作效率,提高各公司之间的数据 ...
- C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 主管可以看下属的数据
主管可以看下属的数据,这个是经常用到的一个权限,不管是大公司,还是小公司都需要的功能. 通过以下2个方法,可以任意达到想要的效果了,设置简单灵活,还能递归运算下属,有时候简单好用就是硬道理. #reg ...
- C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 成熟组件化运行效果分解
1:成熟的组件就是可以写很少的代码,可以实现很多功能.2:又可以用源码方式调用,又可以用dll方式调用.3:不需要学习里面的细节,只要会调用就可以了.4:成熟稳定,功能齐全,bug少,甚至没bug.5 ...
- C#.NET 大型通用信息化系统集成快速开发平台 4.0 版本 - 组织机构的名称编号是否允许重复?
通常情况下,一个公司内部的部门名称,编号是不可能重复的.但是是在多公司的情况下,很可能有部门名称重复的问题存在,这时需要允许部门名称重复. 例如一个大型IT公司,在2个地区都有研发部或者客户服务部,这 ...
- 大型EMR电子病历源码三甲医院医疗信息管理系统软件网络版
详情请点击查看 开发环境 :VS2010 + C# + ORACLE系统简介:1各种记录的书写,并可保留修改痕迹 在各种记录的书写过程中,根据系统提供的首次护理记录.一般护理记录.术前术后护理记录等模 ...
- C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 严格的用户账户审核功能
整个集团有几万个用户,一个个用户添加是不现实的,只有每个公司的系统管理员添加.或者用户申请帐户,然后有相应的管理员审核,才会更准确一些. 每个公司.分公司.部门的账户情况只有所在公司的管理员是最清楚的 ...
随机推荐
- IM通讯协议专题学习(十):初识 Thrift 序列化协议
本文由字节跳动技术团队杨晨曦分享,本文有修订和改动. 1.引言 本文将带你一起初步认识Thrift的序列化协议,包括Binary协议.Compact协议(类似于Protobuf).JSON协议,希望能 ...
- d2go使用总结
d2go使用总结 安装 PyTorch Nightly 安装 PyTorch Nightly(以 CUDA 10.2 为例,详见PyTorch 网站): conda install pytorch t ...
- MACOS 降级
最近升级了macos 15.2,结果导致外接显示器显示不正常,经常断掉或者黑屏,因此macos进行降级处理: 1. 首先在App Store下载Ventura 系统; 2. 准备一个16G的U盘,然后 ...
- Jenkins使用问题汇总
1. 禁止job出现403问题 解决方法: 在系统管理 –> Configure Global Security中调整设置:取消"启用安全(Enable security)" ...
- Solution Set - “带我去看极光与大海吧”
目录 0.「AGC 062C」Mex of Subset Sum 1.「THUPC 2021 初赛」「洛谷 P7136」方格游戏 2.「THUPC 2023 初赛」「洛谷 P9139」喵了个喵 II ...
- 使用Ollama
推荐 Ollama 本地运行大模型(LLM)完全指南 Ollama中文学习 应用 查看可支持的模型:https://ollama.com/library 查看运行中的模型 ollama ps 停止模型 ...
- linux下自建NAS教程
NAS,英文全名Network Attached Storage,翻译过来是:网络附接存储. 引用维基百科定义 网络附接存储(英语:Network Attached Storage,缩写:NAS)[1 ...
- 2025-01-22:使二进制数组全部等于 1 的最少操作次数Ⅱ。用go语言,给定一个二进制数组 nums,你可以对数组进行以下操作任意次(包括0次): 选择任何一个下标 i,并将从该下标开始到数组末
2025-01-22:使二进制数组全部等于 1 的最少操作次数Ⅱ.用go语言,给定一个二进制数组 nums,你可以对数组进行以下操作任意次(包括0次): 选择任何一个下标 i,并将从该下标开始到数组末 ...
- 一篇关于c语言的大补帖
一晃今年又开始了,作为一个失意的中年技术男,现在的心境真的是五味杂陈.赶紧写一篇吧,我怕过了这个点,今年就在没有那个心情去写了. 因为是基础嘛,从事软件开发以来c或者c++相关的东西断断续续 也刷了差 ...
- 一种提升SQL改写效率的方法
本文分享自天翼云开发者社区<一种提升SQL改写效率的方法>,作者:唐****律 一.背景 SQL改写是数据库产品中使用比较频繁的一个技术,在大多数产品中的调用频率也非常高,通常对性能的需求 ...