平台设备模块主要提供设备连接支持及平台自带的设备连接平台Device Agent,目前只提供了三种设备的连接,如果原有支持连接的设备或第三方IOT平台不满足项目需求,则需要对其进行扩展。

1. 环境安装

1.1. 平台依赖

  1. 开发集成环境(Eclipse,IDEA)

  2. Maven3.6

  3. Lumos 3.0 及以上

1.2. Maven 依赖信息

接口SDK依赖信息
<dependency>
    <groupId>com.ags.lumosframework</groupId>
    <artifactId>lumos-device-sdk</artifactId>
    <version>3.0.0-SNAPSHOT</version>
</dependency>

2. 设备模块的扩展

平台对于设备模块的构想是: 平台提供设备类型及设备两个对象的数据维护,设备类型及设备都有与第三方平台的连接参数。 显然,设备类型的参数为整个类型的连接参数,设备的参数为某个具体设备的连接参数。 对于具体的连接实现与处理逻辑需要根据项目需求进行编码,平台提供对设备类型与第三方平台连接及其连接参数的扩展,针对打印模板提供打印模板参数的扩展。

2.1. 设备类型的扩展

平台支持设备类别的扩展,需要在LiquiBase脚本中添加设备类别:

<insert tableName="SYS_EQUIPMENT_CLASS">
    <column name="EQUIP_CLASS_NAME" value="test" />
    <column name="PARAMETER" value="" />

    <column name="ID" valueNumeric="1" />
    <column name="COMPANY_ID" valueNumeric="-1" />
    <column name="CREATE_TIME" valueDate="2019-06-01" />
    <column name="CREATE_USER_ID" valueNumeric="1" />
    <column name="CREATE_USER_NAME" value="admin" />
    <column name="CREATE_USER_FULL_NAME" value="admin" />
    <column name="DTS_CREATION_BID" valueNumeric="-1" />
    <column name="LM_TIME" valueDate="2019-06-01" />
    <column name="LM_USER_ID" valueNumeric="-1" />
    <column name="LM_USER_NAME" value="admin" />
    <column name="LM_USER_FULL_NAME" value="admin" />
    <column name="DTS_MODIFIED_BID" valueNumeric="-1" />
    <column name="DELETE_USER_ID" valueNumeric="-1" />
    <column name="DELETED" valueBoolean="false" />
</insert>
注意修改ID值,避免跟已有的ID值冲突。

2.2. 平台及其参数的扩展

可连接平台的扩展:
实现 IEquipmentPlatformDef 接口,

IEquipmentPlatformDef.java
package com.ags.lumosframework.device.sdk.base;

import java.util.List;

/**
 * 设备可连接的第三方平台定义
 */
public interface IEquipmentPlatformDef {

    /**
     * 获取设备可连接的第三方平台名称
     *
     * @return
     */
    String getName();

    /**
     * 获取设备可连接的第三方平台名称国际化Key
     *
     * @return
     */
    String getNameKey();

    /**
     * 获取可连接的第三方平台所需参数集合(属于设备类别的)
     *
     * @return
     */
    List<IParameterDef> getParameterDefs();

    /**
     * 获取设备可连接的第三方平台所需参数集合(属于设备的)
     * @return
     */
    List<IParameterDef> getConnectableEquipmentParameterDefs();

}

其中getParameterDefs及getConnectableEquipmentParameterDefs方法的返回值也可以进行扩展,扩展参数需实现 IParameterDef 接口,

IParameterDef.java
package com.ags.lumosframework.device.sdk.base;

/**
 * 设备可连接的第三方平台所需参数定义
 */
public interface IParameterDef {

    /**
     * 设备可连接的第三方平台所需参数名称
     *
     * @return
     */
    String getName();

}

示例:
平台的扩展:

package com.ags.lumosframework.device.sdk.base;

import java.util.Arrays;
import java.util.List;

public enum LumosEquipmentPlatform implements IEquipmentPlatformDef {

    /**
     * 平台提供的连接平台
     */
    DEVICE_AGENT("DeviceAgent", "device.platform.deviceagent", new IParameterDef[] {}, new IParameterDef[]{}),

    /**
     * FII提供IOT平台
     */
    COREPRO("CorePro", "device.platform.corepro", new IParameterDef[] {LumosDeviceParameter.PRODUCT_KEY}, new IParameterDef[]{LumosDeviceParameter.PRODUCT_KEY});

    private String name;

    private String nameKey;

    private IParameterDef[] parameters;

    private IParameterDef[] equipmentParameterDefs;

    LumosEquipmentPlatform(String name, String nameKey, IParameterDef[] parameters, IParameterDef[] equipmentParameterDefs) {
        this.name = name;
        this.nameKey = nameKey;
        this.parameters = parameters;
        this.equipmentParameterDefs = equipmentParameterDefs;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getNameKey() {
        return nameKey;
    }

    @Override
    public List<IParameterDef> getParameterDefs() {
        return Arrays.asList(parameters);
    }

    @Override
    public List<IParameterDef> getConnectableEquipmentParameterDefs() {
        return Arrays.asList(equipmentParameterDefs);
    }

}

参数的扩展:

package com.ags.lumosframework.device.sdk.base;

public enum LumosDeviceParameter implements IParameterDef {

    /**
     * 设备类别标识参数
     */
    PRODUCT_KEY("ProductKey");

    private String name;

    LumosDeviceParameter(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

}

在对应项目的spring.factories文件中加入

com.ags.lumosframework.device.sdk.base.IEquipmentPlatformDef=\
com.ags.lumosframework.device.sdk.base.LumosEquipmentPlatform

com.ags.lumosframework.device.sdk.base.IParameterDef=\
com.ags.lumosframework.device.sdk.base.LumosDeviceParameter

2.3. 打印参数的扩展

平台本身并没有打印模板参数定义,需要根据项目需求进行扩展。
扩展打印模板参数只需实现 IPrintParameter 接口

IPrintParameter.java
package com.ags.lumosframework.common.parameter;

/**
 *
 */
public interface IPrintParameter extends IParameterDef {

    /**
     * 获取一个Reader用于读取对应类型的参数值
     *
     * @return
     */
    default Reader getReader() {
        return (obj, parameters) -> obj;
    }

    /**
     * 获取一个Reader用于设置对应类型的参数值
     *
     * @return
     */
    default Writer getWriter() {
        return (obj, value) -> {
        };
    }

}
Reader.java
package com.ags.lumosframework.common.parameter;

public interface Reader {

    /**
     * 根据传入的参数(parameters)读取Obj中的某属性值
     *
     * @param obj
     * @param parameters
     * @return
     */
    Object read(Object obj, Object... parameters);

}
只需要重写IPrintParameter接口中的getReader(Object,Object…​)方法。

示例:
MES扩展的打印参数:

package com.ags.mes.server.api.enums;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ags.lumosframework.common.parameter.IPrintParameter;
import com.ags.lumosframework.common.parameter.ParameterType;
import com.ags.lumosframework.common.parameter.Reader;
import com.ags.lumosframework.common.spring.BeanManager;
import com.ags.mes.server.api.domain.*;
import com.ags.mes.server.api.domain.base.WIP;
import com.ags.mes.server.api.service.IDataAcquisitionResultService;
import com.ags.mes.server.api.service.IPackageInstanceService;

public enum MesPrintParameterEnum implements IPrintParameter {

    /**
     * 工单编号
     */
    ORDER_NUMBER("OrderNumber", "", (obj, parameters) -> {
        if (obj instanceof WIP) {
            return ((WIP)obj).getWorkOrderNumber();
        }
        if (obj instanceof WorkOrder) {
            return ((WorkOrder)obj).getOrderNumber();
        }
        return "";
    }),

    /**
     * 工单项编号
     */
    ORDER_ITEM_NUMBER("OrderItemNumber", "", (obj, parameters) -> {
        if (obj instanceof WIP) {
            return ((WIP)obj).getWorkOrderItemNumber();
        }
        if (obj instanceof WorkOrderItem) {
            return ((WorkOrderItem)obj).getOrderItemName();
        }
        return "";
    }),

    /**
     * Lot SN
     */
    LOT_SN("LotSN", "", (obj, parameters) -> {
        if (obj instanceof Lot) {
            return ((Lot)obj).getSerialNumber();
        }
        return "";
    }),

    /**
     * Unit SN
     */
    UNIT_SN("UnitSN", "", (obj, parameters) -> {
        if (obj instanceof Unit) {
            return ((Unit)obj).getSerialNumber();
        }
        return "";
    }),

    /**
     * 物料编码
     */
    PART_NUMBER("PartNumber", "", (obj, parameters) -> {
        if (obj instanceof WIP) {
            return ((WIP)obj).getPartNumber();
        }
        if (obj instanceof WorkOrderItem) {
            return ((WorkOrderItem)obj).getPartNumber();
        }
        return "";
    }),

    /**
     * 物料版本
     */
    PART_REVISION("PartRevision", "", (obj, parameters) -> {
        if (obj instanceof WIP) {
            return ((WIP)obj).getPartRevision();
        }
        if (obj instanceof WorkOrderItem) {
            return ((WorkOrderItem)obj).getPartRevision();
        }
        return "";
    }),

    /**
     * Enterprise
     */
    ENTERPRISE("Enterprise", "", (obj, parameters) -> {
        if (obj instanceof WIP) {
            return ((WIP)obj).getEnterpriseName();
        }
        return "";
    }),
    /**
     * Site
     */
    SITE("Site", "", (obj, parameters) -> {
        if (obj instanceof WIP) {
            return ((WIP)obj).getSiteName();
        }
        return "";
    }),
    /**
     * Area
     */
    AREA("Area", "", (obj, parameters) -> {
        if (obj instanceof WIP) {
            return ((WIP)obj).getAreaName();
        }
        return "";
    }),

    /**
     *
     */
    PRODUCTION_LINE("ProductionLine", "", (obj, parameters) -> {
        if (obj instanceof WIP) {
            return ((WIP)obj).getProductionLineName();
        }
        return "";
    }),

    /**
     * 包装箱序列号
     */
    PACKAGEINSTANCE_SN("PackageInstanceSN", "", (obj, parameters) -> {
        if (obj instanceof PackageInstance) {
            return ((PackageInstance)obj).getSerialNumber();
        }
        return "";
    }),

    /**
     * 子包装箱序列号
     */
    SUB_PACKAGEINSTANCE_SN("SubPackageInstanceSN", "", (obj, parameters) -> {
        Map<String, String> result = new HashMap<>();
        if (obj instanceof PackageInstance) {
            PackageInstance temp = (PackageInstance)obj;
            IPackageInstanceService packageInstanceService = BeanManager.getService(IPackageInstanceService.class);
            List<PackageInstance> subPackageInstances =
                packageInstanceService.getSubPackageInstance(((PackageInstance)obj).getId());
            for (int i = 1; i < subPackageInstances.size() + 1; i++) {
                result.put("SubPackageInstanceSN_" + i, subPackageInstances.get(i - 1).getSerialNumber());
            }
        }
        return result;
    }),

    /**
     * 自定义参数(数据从数据采集中获取)
     */
    CUTOMIZED("Customized", "", (obj, parameters) -> {
        Map<String, String> result = new HashMap<>();
        if (obj instanceof WIP) {
            WIP<?> wip = (WIP<?>)obj;
            IDataAcquisitionResultService service = BeanManager.getService(IDataAcquisitionResultService.class);
            List<String> strParameters = new ArrayList<>();
            for (Object parameter : parameters) {
                strParameters.add((String)parameter);
            }
            List<DataAcquisitionResult> dataAcquisitionResults =
                service.listByName(wip.getObjectType(), wip.getSerialNumber(), strParameters);
            for (DataAcquisitionResult dataAcquisitionResult : dataAcquisitionResults) {
                result.put(dataAcquisitionResult.getName(), dataAcquisitionResult.getResultValue());
            }
        }
        return result;
    });

    private String name;

    private String nameKey;

    private Reader reader;

    MesPrintParameterEnum(String name, String nameKey, Reader reader) {
        this.name = name;
        this.nameKey = nameKey;
        this.reader = reader;
    }

    @Override
    public String getKey() {
        return this.name();
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getNameI18NKey() {
        return nameKey;
    }

    @Override
    public ParameterType getType() {
        return null;
    }

    @Override
    public Reader getReader() {
        return reader;
    }
}

在对应项目的spring.factories文件中加入:

com.ags.lumosframework.common.parameter.IPrintParameter=\
com.ags.mes.server.api.enums.MesPrintParameterEnum