cheng
2023-12-12 c64c9f6fb38f65be99b827c1af8d3c3852f68ba4
提交 | 用户 | 时间
71e81e 1 package cn.stylefeng.guns.plcserver.opc.unit;
2
3 import org.jinterop.dcom.common.JIErrorCodes;
4 import org.jinterop.dcom.common.JIException;
5 import org.jinterop.dcom.core.JIArray;
6 import org.jinterop.dcom.core.JIVariant;
7 import org.openscada.opc.lib.da.Group;
8 import org.openscada.opc.lib.da.Item;
9 import org.openscada.opc.lib.da.ItemState;
10
11 import java.text.DecimalFormat;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Objects;
16 import java.util.stream.Collectors;
17
18 public class OPCUnit {
19
20     /**
21      * 读单个值
22      */
23     public static String read(Item item) {
24         try {
25             ItemState state = item.read(true);
26             return getValue(state);
27         } catch (JIException e) {
28             e.printStackTrace();
29         }
30         return null;
31     }
32
33     /**
34      * 读一组值,对于读取异常的点位会返回null值
35      */
36     public static List<String> readValues(Group group, List<String> tags) {
37         //添加到group中,如果添加失败则添加null
38         List<Item> items = tags.stream().map(tag -> {
39             try {
40                 return group.addItem(tag);
41             } catch (Exception e) {
42                 //log.info(e.toString());
43             }
44             return null;
45         }).collect(Collectors.toList());
46
47         List<String> result = new ArrayList<>();
48         try {
49             //读取所有的值,过滤null值,否则会出异常
50             Map<Item, ItemState> map = group.read(true,
51                     items.stream().filter(Objects::nonNull).toArray(Item[]::new));
52             //解析
53             for (Item item : items) {
54                 if (item == null) {
55                     result.add(null);
56                     continue;
57                 }
58                 String value = getValue(map.get(item));
59                 result.add(value);
60             }
61         } catch (JIException e) {
62             e.printStackTrace();
63         }
64         return result;
65     }
66
67     /**
68      * 写值到变量
69      */
70     public static void write(Item item, String val) {
71         try {
72             JIVariant value = new JIVariant(val);
73             item.write(value);
74         } catch (JIException e) {
75             e.printStackTrace();
76         }
77     }
78
79     /**
80      * 写值到变量:数组
81      */
82     public static void write(Item item, String[] snArray) {
83         try {
84
85             /** 构造写入数据 */
86             Long[] integerData = new Long[snArray.length];
87             for (int i = 0; i < snArray.length; i++) {
88                 integerData[i] = Long.valueOf(snArray[i]);
89             }
90             final JIArray array = new JIArray(integerData, false);
91             final JIVariant value = new JIVariant(array);
92
93             item.write(value);
94         } catch (JIException e) {
95             e.printStackTrace();
96         }
97     }
98
99     /**
100      * 如果是 bool、string、short、int等直接返回字符串;
101      * 如果是 long 类型的数组,返回数字内容间加点,对应 long,数组,大小为6
102      * 如果是 float 类型的数组,返回数字内容间加逗号,对应 float,数组,大小为20
103      */
104     private static String getValue(ItemState state) {
105         JIVariant variant = state.getValue();
106         try {
107             int type = variant.getType();
108             //Boolean
109             if (type == JIVariant.VT_BOOL) {
110                 boolean value = variant.getObjectAsBoolean();
111                 return String.valueOf(value);
112             }
113             //String
114             else if (type == JIVariant.VT_BSTR) {
115                 return variant.getObjectAsString().getString();
116             }
117             //Word DWord
118             else if (type == JIVariant.VT_UI2 || type == JIVariant.VT_UI4) {
119                 Number value = variant.getObjectAsUnsigned().getValue();
120                 return String.valueOf(value);
121             }
122             //Sort
123             else if (type == JIVariant.VT_I2) {
124                 short value = variant.getObjectAsShort();
125                 return String.valueOf(value);
126             }
127             //Float
128             else if (type == JIVariant.VT_R4) {
129                 float value = variant.getObjectAsFloat();
130                 return String.valueOf(value);
131             }
132             //long 类型的数组
133             else if (type == 8195) {
134                 JIArray jarr = variant.getObjectAsArray();
135                 Integer[] arr = (Integer[]) jarr.getArrayInstance();
136                 StringBuilder value = new StringBuilder();
137                 for (Integer i : arr) {
138                     value.append(i).append(".");
139                 }
140                 String res = value.substring(0, value.length() - 1);
141                 // "25.36087601.1.1.18.36"-->"25.36087601.01.0001.18.36"
142                 String[] array = res.split("[.]");
143                 return array[0] + "." + array[1] + "." + new DecimalFormat("00").format(Long.valueOf(array[2]))
144                         + "." + new DecimalFormat("0000").format(Long.valueOf(array[3])) + "." + array[4] + "."
145                         + array[5];
146             }
147             //float 类型的数组
148             else if (type == 8196) {
149                 JIArray jarr = variant.getObjectAsArray();
150                 Float[] arr = (Float[]) jarr.getArrayInstance();
151                 StringBuilder value = new StringBuilder();
152                 for (Float f : arr) {
153                     value.append(f).append(",");
154                 }
155                 return value.substring(0, value.length() - 1);
156             }
157             //其他类型
158             else {
159                 Object value = variant.getObject();
160                 return String.valueOf(value);
161             }
162         } catch (JIException e) {
163             e.printStackTrace();
164         }
165         return null;
166     }
167     /**
168      * 获取value
169      * @param var
170      * @return
171      * @throws JIException
172      */
173     private static Object getVal(JIVariant var) throws JIException {
174         Object value;
175         int type = var.getType();
176         switch (type) {
177             case JIVariant.VT_I2:
178                 value = var.getObjectAsShort();
179                 break;
180             case JIVariant.VT_I4:
181                 value = var.getObjectAsInt();
182                 break;
183             case JIVariant.VT_I8:
184                 value = var.getObjectAsLong();
185                 break;
186             case JIVariant.VT_R4:
187                 value = var.getObjectAsFloat();
188                 break;
189             case JIVariant.VT_R8:
190                 value = var.getObjectAsDouble();
191                 break;
192             case JIVariant.VT_BSTR:
193                 value = var.getObjectAsString2();
194                 break;
195             case JIVariant.VT_BOOL:
196                 value = var.getObjectAsBoolean();
197                 break;
198             case JIVariant.VT_UI2:
199             case JIVariant.VT_UI4:
200                 value = var.getObjectAsUnsigned().getValue();
201                 break;
202             case JIVariant.VT_EMPTY:
203                 throw new JIException(JIErrorCodes.JI_VARIANT_IS_NULL, "Variant is Empty.");
204             case JIVariant.VT_NULL:
205                 throw new JIException(JIErrorCodes.JI_VARIANT_IS_NULL, "Variant is null.");
206             default:
207                 throw new JIException(JIErrorCodes.JI_VARIANT_IS_NULL, "Unknown Type.");
208         }
209
210         return value;
211     }
212 }