]> git.basschouten.com Git - openhab-addons.git/blob
f4f6519d8e60c57dd00e90151781a1cb6e48094c
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.dsmr.internal.meter;
14
15 import java.util.Arrays;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.stream.Collectors;
19
20 import org.openhab.binding.dsmr.internal.DSMRBindingConstants;
21 import org.openhab.binding.dsmr.internal.device.cosem.CosemObject;
22 import org.openhab.binding.dsmr.internal.device.cosem.CosemObjectType;
23 import org.openhab.core.thing.ThingTypeUID;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * Supported meters
29  *
30  * @author M. Volaart - Initial contribution
31  */
32 public enum DSMRMeterType {
33     // Don't auto format the enum list. For readability the format for the enum is:
34     // First line parameters; DSMRMeterKind and CosemObjectType (identification object type)
35     // 2nd line and further required CosemObjectType
36     // optional CosemObjectType start on a new line
37     //@formatter:off
38
39     /** DSMR V2 / V3 Device meter type (used for device (and not meter specific) related messages) */
40     DEVICE_V2_V3(DSMRMeterKind.DEVICE, CosemObjectType.UNKNOWN,
41             CosemObjectType.P1_TEXT_CODE, CosemObjectType.P1_TEXT_STRING),
42
43     /** DSMR V4 Device meter type (used for device (and not meter specific) related messages) */
44     DEVICE_V4(DSMRMeterKind.DEVICE, CosemObjectType.UNKNOWN,
45             CosemObjectType.P1_TEXT_CODE, CosemObjectType.P1_TEXT_STRING, CosemObjectType.P1_VERSION_OUTPUT,
46             CosemObjectType.P1_TIMESTAMP),
47
48     /** DSMR V5 Device meter type (used for device (and not meter specific) related messages) */
49     DEVICE_V5(DSMRMeterKind.DEVICE, CosemObjectType.UNKNOWN,
50             new CosemObjectType[] {
51                     CosemObjectType.P1_TEXT_STRING, CosemObjectType.P1_VERSION_OUTPUT, CosemObjectType.P1_TIMESTAMP },
52             new CosemObjectType[] {
53                     CosemObjectType.P1_TEXT_STRING_LONG }),
54
55     /** ACE4000 Electricity */
56     ELECTRICITY_ACE4000(DSMRMeterKind.MAIN_ELECTRICITY, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
57             new CosemObjectType[] {
58                     CosemObjectType.METER_EQUIPMENT_IDENTIFIER, CosemObjectType.EMETER_DELIVERY_TARIFF0,
59                     CosemObjectType.EMETER_DELIVERY_TARIFF1, CosemObjectType.EMETER_PRODUCTION_TARIFF0,
60                     CosemObjectType.EMETER_PRODUCTION_TARIFF1, CosemObjectType.EMETER_TARIFF_INDICATOR,
61                     CosemObjectType.EMETER_ACTIVE_IMPORT_POWER, CosemObjectType.EMETER_SWITCH_POSITION },
62             new CosemObjectType[] {
63                     CosemObjectType.EMETER_DELIVERY_TARIFF2, CosemObjectType.EMETER_DELIVERY_TARIFF0_ANTIFRAUD,
64                     CosemObjectType.EMETER_DELIVERY_TARIFF1_ANTIFRAUD, CosemObjectType.EMETER_DELIVERY_TARIFF2_ANTIFRAUD,
65                     CosemObjectType.EMETER_PRODUCTION_TARIFF2, CosemObjectType.EMETER_TRESHOLD_A }),
66
67     /** ACE4000 Gas meter */
68     GAS_ACE4000(DSMRMeterKind.GAS, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
69             CosemObjectType.METER_EQUIPMENT_IDENTIFIER, CosemObjectType.GMETER_24H_DELIVERY_V2,
70             CosemObjectType.GMETER_VALVE_POSITION_V2_2),
71
72     /** ACE4000 Heating meter */
73     HEATING_ACE4000(DSMRMeterKind.HEATING, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
74             CosemObjectType.METER_EQUIPMENT_IDENTIFIER, CosemObjectType.HMETER_VALUE_V2),
75
76     /** ACE4000 Cooling meter */
77     COOLING_ACE4000(DSMRMeterKind.COOLING, CosemObjectType.UNKNOWN,
78             CosemObjectType.CMETER_VALUE_V2),
79
80     /** ACE4000 Water meter */
81     WATER_ACE4000(DSMRMeterKind.WATER, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
82             CosemObjectType.METER_EQUIPMENT_IDENTIFIER, CosemObjectType.WMETER_VALUE_V2),
83
84     /** ACE4000 first Slave electricity meter */
85     SLAVE_ELECTRICITY1_ACE4000(DSMRMeterKind.SLAVE_ELECTRICITY1, CosemObjectType.UNKNOWN,
86             CosemObjectType.EMETER_DELIVERY_TARIFF0, CosemObjectType.EMETER_DELIVERY_TARIFF1,
87             CosemObjectType.EMETER_DELIVERY_TARIFF2, CosemObjectType.EMETER_PRODUCTION_TARIFF0,
88             CosemObjectType.EMETER_PRODUCTION_TARIFF1, CosemObjectType.EMETER_PRODUCTION_TARIFF2,
89             CosemObjectType.EMETER_TARIFF_INDICATOR, CosemObjectType.EMETER_ACTIVE_IMPORT_POWER,
90             CosemObjectType.EMETER_TRESHOLD_A, CosemObjectType.EMETER_SWITCH_POSITION),
91
92     /** ACE4000 second Slave electricity meter */
93     SLAVE_ELECTRICITY2_ACE4000(DSMRMeterKind.SLAVE_ELECTRICITY2, CosemObjectType.UNKNOWN,
94             CosemObjectType.EMETER_DELIVERY_TARIFF0, CosemObjectType.EMETER_DELIVERY_TARIFF1,
95             CosemObjectType.EMETER_DELIVERY_TARIFF2, CosemObjectType.EMETER_PRODUCTION_TARIFF0,
96             CosemObjectType.EMETER_PRODUCTION_TARIFF1, CosemObjectType.EMETER_PRODUCTION_TARIFF2,
97             CosemObjectType.EMETER_TARIFF_INDICATOR, CosemObjectType.EMETER_ACTIVE_IMPORT_POWER,
98             CosemObjectType.EMETER_TRESHOLD_A, CosemObjectType.EMETER_SWITCH_POSITION),
99
100     /** DSMR V2.1 Electricity meter */
101     ELECTRICITY_V2_1(DSMRMeterKind.MAIN_ELECTRICITY, CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER_V2_X,
102             CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER_V2_X, CosemObjectType.EMETER_DELIVERY_TARIFF1,
103             CosemObjectType.EMETER_DELIVERY_TARIFF2, CosemObjectType.EMETER_PRODUCTION_TARIFF1,
104             CosemObjectType.EMETER_PRODUCTION_TARIFF2, CosemObjectType.EMETER_TARIFF_INDICATOR,
105             CosemObjectType.EMETER_TRESHOLD_A_V2_1, CosemObjectType.EMETER_SWITCH_POSITION_V2_1,
106             CosemObjectType.EMETER_ACTUAL_DELIVERY),
107
108     /** DSMR V2.1 Gas meter */
109     GAS_V2_1(DSMRMeterKind.GAS, CosemObjectType.GMETER_EQUIPMENT_IDENTIFIER_V2,
110             CosemObjectType.GMETER_EQUIPMENT_IDENTIFIER_V2, CosemObjectType.GMETER_24H_DELIVERY_V2,
111             CosemObjectType.GMETER_24H_DELIVERY_COMPENSATED_V2, CosemObjectType.GMETER_VALVE_POSITION_V2_1),
112
113     /** DSMR V2.2 Electricity meter */
114     ELECTRICITY_V2_2(DSMRMeterKind.MAIN_ELECTRICITY, CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER_V2_X,
115             CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER_V2_X, CosemObjectType.EMETER_DELIVERY_TARIFF1,
116             CosemObjectType.EMETER_DELIVERY_TARIFF2, CosemObjectType.EMETER_PRODUCTION_TARIFF1,
117             CosemObjectType.EMETER_PRODUCTION_TARIFF2, CosemObjectType.EMETER_TARIFF_INDICATOR,
118             CosemObjectType.EMETER_TRESHOLD_A, CosemObjectType.METER_VALVE_SWITCH_POSITION,
119             CosemObjectType.EMETER_ACTUAL_DELIVERY),
120
121     /** DSMR V2.2 Gas meter */
122     GAS_V2_2(DSMRMeterKind.GAS, CosemObjectType.GMETER_EQUIPMENT_IDENTIFIER_V2,
123             CosemObjectType.GMETER_EQUIPMENT_IDENTIFIER_V2, CosemObjectType.GMETER_24H_DELIVERY_V2,
124             CosemObjectType.GMETER_24H_DELIVERY_COMPENSATED_V2, CosemObjectType.GMETER_VALVE_POSITION_V2_2),
125
126     /** DSMR V2.2 Heating meter */
127     HEATING_V2_2(DSMRMeterKind.HEATING, CosemObjectType.HMETER_EQUIPMENT_IDENTIFIER_V2_2,
128             CosemObjectType.HMETER_EQUIPMENT_IDENTIFIER_V2_2, CosemObjectType.HMETER_VALUE_V2),
129
130     /** DSMR V2.2 Cooling meter */
131     COOLING_V2_2(DSMRMeterKind.COOLING, CosemObjectType.CMETER_EQUIPMENT_IDENTIFIER_V2_2,
132             CosemObjectType.CMETER_EQUIPMENT_IDENTIFIER_V2_2, CosemObjectType.CMETER_VALUE_V2),
133
134     /** DSMR V2.2 Water meter */
135     WATER_V2_2(DSMRMeterKind.WATER, CosemObjectType.WMETER_EQUIPMENT_IDENTIFIER_V2_2,
136             CosemObjectType.WMETER_EQUIPMENT_IDENTIFIER_V2_2, CosemObjectType.WMETER_VALUE_V2),
137
138     /** DSMR V3.0 Electricity meter */
139     ELECTRICITY_V3_0(DSMRMeterKind.MAIN_ELECTRICITY, CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER,
140             new CosemObjectType[] {
141                     CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER, CosemObjectType.EMETER_DELIVERY_TARIFF1,
142                     CosemObjectType.EMETER_DELIVERY_TARIFF2, CosemObjectType.EMETER_PRODUCTION_TARIFF1,
143                     CosemObjectType.EMETER_PRODUCTION_TARIFF2, CosemObjectType.EMETER_TARIFF_INDICATOR,
144                     CosemObjectType.EMETER_ACTUAL_DELIVERY, CosemObjectType.EMETER_ACTUAL_PRODUCTION},
145             new CosemObjectType[] {
146                     CosemObjectType.EMETER_TRESHOLD_A, CosemObjectType.EMETER_TRESHOLD_KWH,
147                     CosemObjectType.EMETER_SWITCH_POSITION}),
148
149     /** DSMR V3.0 Gas meter */
150     GAS_V3_0(DSMRMeterKind.GAS, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
151             new CosemObjectType[] {
152                     CosemObjectType.METER_DEVICE_TYPE, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
153                     CosemObjectType.GMETER_VALUE_V3},
154             new CosemObjectType[] {
155                     CosemObjectType.METER_VALVE_SWITCH_POSITION}),
156
157     /** DSMR V3.0 Water meter */
158     WATER_V3_0(DSMRMeterKind.WATER, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
159             CosemObjectType.METER_DEVICE_TYPE, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
160             CosemObjectType.WMETER_VALUE_V3, CosemObjectType.METER_VALVE_SWITCH_POSITION),
161
162     /** DSMR V3.0 GJ meter (heating, cooling) */
163     GJ_V3_0(DSMRMeterKind.GJ, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
164             CosemObjectType.METER_DEVICE_TYPE, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
165             CosemObjectType.GJMETER_VALUE_V3, CosemObjectType.METER_VALVE_SWITCH_POSITION),
166
167     /** DSMR V3.0 Generic meter */
168     GENERIC_V3_0(DSMRMeterKind.GENERIC, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
169             CosemObjectType.METER_DEVICE_TYPE, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
170             CosemObjectType.GENMETER_VALUE_V3, CosemObjectType.METER_VALVE_SWITCH_POSITION),
171
172     /** DSMR V4.0 Electricity meter */
173     ELECTRICITY_V4_0(DSMRMeterKind.MAIN_ELECTRICITY, CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER,
174             new CosemObjectType[] {
175                     CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER, CosemObjectType.EMETER_DELIVERY_TARIFF1,
176                     CosemObjectType.EMETER_DELIVERY_TARIFF2, CosemObjectType.EMETER_PRODUCTION_TARIFF1,
177                     CosemObjectType.EMETER_PRODUCTION_TARIFF2, CosemObjectType.EMETER_TARIFF_INDICATOR,
178                     CosemObjectType.EMETER_TRESHOLD_KWH, CosemObjectType.EMETER_SWITCH_POSITION,
179                     CosemObjectType.EMETER_ACTUAL_DELIVERY, CosemObjectType.EMETER_ACTUAL_PRODUCTION,
180                     CosemObjectType.EMETER_POWER_FAILURES, CosemObjectType.EMETER_LONG_POWER_FAILURES,
181                     CosemObjectType.EMETER_VOLTAGE_SAGS_L1, CosemObjectType.EMETER_VOLTAGE_SWELLS_L1 },
182             new CosemObjectType[] {
183                     CosemObjectType.EMETER_POWER_FAILURE_LOG, CosemObjectType.EMETER_VOLTAGE_SAGS_L2,
184                     CosemObjectType.EMETER_VOLTAGE_SAGS_L3, CosemObjectType.EMETER_VOLTAGE_SWELLS_L2,
185                     CosemObjectType.EMETER_VOLTAGE_SWELLS_L3 }),
186
187     /** DSMR V4 m3 meter (gas, water) */
188     M3_V4(DSMRMeterKind.M3, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
189             CosemObjectType.METER_DEVICE_TYPE, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
190             CosemObjectType.M3METER_VALUE, CosemObjectType.METER_VALVE_SWITCH_POSITION),
191
192     /** DSMR V4 GJ meter (heating, cooling) */
193     GJ_V4(DSMRMeterKind.GJ, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
194             CosemObjectType.METER_DEVICE_TYPE, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
195             CosemObjectType.GJMETER_VALUE_V4, CosemObjectType.METER_VALVE_SWITCH_POSITION),
196
197     /** DSMR V4 Slave Electricity meter */
198     SLAVE_ELECTRICITY_V4(DSMRMeterKind.SLAVE_ELECTRICITY1, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
199             CosemObjectType.METER_DEVICE_TYPE, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
200             CosemObjectType.EMETER_VALUE, CosemObjectType.EMETER_SWITCH_POSITION),
201
202     /** DSMR V4.0.4 Electricity meter */
203     ELECTRICITY_V4_0_4(DSMRMeterKind.MAIN_ELECTRICITY, CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER,
204             new CosemObjectType[] {
205                     CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER, CosemObjectType.EMETER_DELIVERY_TARIFF1,
206                     CosemObjectType.EMETER_DELIVERY_TARIFF2, CosemObjectType.EMETER_PRODUCTION_TARIFF1,
207                     CosemObjectType.EMETER_PRODUCTION_TARIFF2, CosemObjectType.EMETER_TARIFF_INDICATOR,
208                     CosemObjectType.EMETER_TRESHOLD_KWH, CosemObjectType.EMETER_SWITCH_POSITION,
209                     CosemObjectType.EMETER_ACTUAL_DELIVERY, CosemObjectType.EMETER_ACTUAL_PRODUCTION,
210                     CosemObjectType.EMETER_POWER_FAILURES, CosemObjectType.EMETER_LONG_POWER_FAILURES,
211                     CosemObjectType.EMETER_VOLTAGE_SAGS_L1, CosemObjectType.EMETER_VOLTAGE_SWELLS_L1,
212                     CosemObjectType.EMETER_INSTANT_CURRENT_L1, CosemObjectType.EMETER_INSTANT_POWER_DELIVERY_L1,
213                     CosemObjectType.EMETER_INSTANT_POWER_PRODUCTION_L1 },
214             new CosemObjectType[] {
215                     CosemObjectType.EMETER_POWER_FAILURE_LOG, CosemObjectType.EMETER_VOLTAGE_SAGS_L2,
216                     CosemObjectType.EMETER_VOLTAGE_SAGS_L3, CosemObjectType.EMETER_VOLTAGE_SWELLS_L2,
217                     CosemObjectType.EMETER_VOLTAGE_SWELLS_L3, CosemObjectType.EMETER_INSTANT_CURRENT_L2,
218                     CosemObjectType.EMETER_INSTANT_CURRENT_L3, CosemObjectType.EMETER_INSTANT_POWER_DELIVERY_L2,
219                     CosemObjectType.EMETER_INSTANT_POWER_DELIVERY_L3, CosemObjectType.EMETER_INSTANT_POWER_PRODUCTION_L2,
220                     CosemObjectType.EMETER_INSTANT_POWER_PRODUCTION_L3 }),
221
222     /** DSMR V4.2 Electricity meter (specification not available, implemented by reverse engineering */
223     ELECTRICITY_V4_2(DSMRMeterKind.MAIN_ELECTRICITY, CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER,
224             new CosemObjectType[] {
225                     CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER, CosemObjectType.EMETER_DELIVERY_TARIFF1,
226                     CosemObjectType.EMETER_DELIVERY_TARIFF2, CosemObjectType.EMETER_PRODUCTION_TARIFF1,
227                     CosemObjectType.EMETER_PRODUCTION_TARIFF2, CosemObjectType.EMETER_TARIFF_INDICATOR,
228                     CosemObjectType.EMETER_ACTUAL_DELIVERY, CosemObjectType.EMETER_ACTUAL_PRODUCTION,
229                     CosemObjectType.EMETER_POWER_FAILURES, CosemObjectType.EMETER_LONG_POWER_FAILURES,
230                     CosemObjectType.EMETER_VOLTAGE_SAGS_L1, CosemObjectType.EMETER_VOLTAGE_SWELLS_L1,
231                     CosemObjectType.EMETER_INSTANT_CURRENT_L1, CosemObjectType.EMETER_INSTANT_POWER_DELIVERY_L1,
232                     CosemObjectType.EMETER_INSTANT_POWER_PRODUCTION_L1 },
233             new CosemObjectType[] {
234                     CosemObjectType.EMETER_POWER_FAILURE_LOG, CosemObjectType.EMETER_VOLTAGE_SAGS_L2,
235                     CosemObjectType.EMETER_VOLTAGE_SAGS_L3, CosemObjectType.EMETER_VOLTAGE_SWELLS_L2,
236                     CosemObjectType.EMETER_VOLTAGE_SWELLS_L3, CosemObjectType.EMETER_INSTANT_CURRENT_L2,
237                     CosemObjectType.EMETER_INSTANT_CURRENT_L3, CosemObjectType.EMETER_INSTANT_POWER_DELIVERY_L2,
238                     CosemObjectType.EMETER_INSTANT_POWER_DELIVERY_L3, CosemObjectType.EMETER_INSTANT_POWER_PRODUCTION_L2,
239                     CosemObjectType.EMETER_INSTANT_POWER_PRODUCTION_L3 }),
240
241     /** DSMR V5.0 Electricity meter */
242     ELECTRICITY_V5_0(DSMRMeterKind.MAIN_ELECTRICITY, CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER,
243             new CosemObjectType[] {
244                     CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER, CosemObjectType.EMETER_DELIVERY_TARIFF1,
245                     CosemObjectType.EMETER_DELIVERY_TARIFF2, CosemObjectType.EMETER_PRODUCTION_TARIFF1,
246                     CosemObjectType.EMETER_PRODUCTION_TARIFF2, CosemObjectType.EMETER_TARIFF_INDICATOR,
247                     CosemObjectType.EMETER_ACTUAL_DELIVERY, CosemObjectType.EMETER_ACTUAL_PRODUCTION,
248                     CosemObjectType.EMETER_POWER_FAILURES, CosemObjectType.EMETER_LONG_POWER_FAILURES,
249                     CosemObjectType.EMETER_VOLTAGE_SAGS_L1, CosemObjectType.EMETER_VOLTAGE_SWELLS_L1,
250                     CosemObjectType.EMETER_INSTANT_CURRENT_L1, CosemObjectType.EMETER_INSTANT_POWER_DELIVERY_L1,
251                     CosemObjectType.EMETER_INSTANT_POWER_PRODUCTION_L1, CosemObjectType.EMETER_INSTANT_VOLTAGE_L1 },
252             new CosemObjectType[] {
253                     CosemObjectType.EMETER_POWER_FAILURE_LOG, CosemObjectType.EMETER_VOLTAGE_SAGS_L2,
254                     CosemObjectType.EMETER_VOLTAGE_SAGS_L3, CosemObjectType.EMETER_VOLTAGE_SWELLS_L2,
255                     CosemObjectType.EMETER_VOLTAGE_SWELLS_L3, CosemObjectType.EMETER_INSTANT_CURRENT_L2,
256                     CosemObjectType.EMETER_INSTANT_CURRENT_L3, CosemObjectType.EMETER_INSTANT_POWER_DELIVERY_L2,
257                     CosemObjectType.EMETER_INSTANT_POWER_DELIVERY_L3, CosemObjectType.EMETER_INSTANT_POWER_PRODUCTION_L2,
258                     CosemObjectType.EMETER_INSTANT_POWER_PRODUCTION_L3, CosemObjectType.EMETER_INSTANT_VOLTAGE_L2,
259                     CosemObjectType.EMETER_INSTANT_VOLTAGE_L3 }),
260
261     /** DSMR V5.0 m3 meter (gas, water) */
262     M3_V5_0(DSMRMeterKind.M3, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
263             CosemObjectType.METER_DEVICE_TYPE, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
264             CosemObjectType.M3METER_VALUE),
265
266     /** DSMR V5.0 GJ meter (heating, cooling) */
267     GJ_V5_0(DSMRMeterKind.GJ, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
268             CosemObjectType.METER_DEVICE_TYPE, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
269             CosemObjectType.GJMETER_VALUE_V4),
270
271     /** DSMR V5.0 Slave Electricity meter */
272     SLAVE_ELECTRICITY_V5_0(DSMRMeterKind.SLAVE_ELECTRICITY1, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
273             CosemObjectType.METER_DEVICE_TYPE, CosemObjectType.METER_EQUIPMENT_IDENTIFIER,
274             CosemObjectType.EMETER_VALUE),
275
276     /** Luxembourg "Smarty" V1.0 Electricity meter */
277     ELECTRICITY_SMARTY_V1_0(DSMRMeterKind.MAIN_ELECTRICITY, CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER_V2_X,
278             new CosemObjectType[] {
279                     CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER_V2_X, CosemObjectType.EMETER_DELIVERY_TARIFF0,
280                     CosemObjectType.EMETER_PRODUCTION_TARIFF0, CosemObjectType.EMETER_TOTAL_IMPORTED_ENERGY_REGISTER_Q,
281                     CosemObjectType.EMETER_TOTAL_EXPORTED_ENERGY_REGISTER_Q, CosemObjectType.EMETER_ACTUAL_DELIVERY,
282                     CosemObjectType.EMETER_ACTUAL_PRODUCTION, CosemObjectType.EMETER_ACTUAL_REACTIVE_DELIVERY,
283                     CosemObjectType.EMETER_ACTUAL_REACTIVE_PRODUCTION, CosemObjectType.EMETER_ACTIVE_THRESHOLD_SMAX,
284                     CosemObjectType.EMETER_SWITCH_POSITION },
285             new CosemObjectType[] {
286                     CosemObjectType.EMETER_POWER_FAILURES, CosemObjectType.EMETER_VOLTAGE_SAGS_L1,
287                     CosemObjectType.EMETER_VOLTAGE_SAGS_L2, CosemObjectType.EMETER_VOLTAGE_SAGS_L3,
288                     CosemObjectType.EMETER_VOLTAGE_SWELLS_L1, CosemObjectType.EMETER_VOLTAGE_SWELLS_L2,
289                     CosemObjectType.EMETER_VOLTAGE_SWELLS_L3, CosemObjectType.EMETER_INSTANT_CURRENT_L1,
290                     CosemObjectType.EMETER_INSTANT_CURRENT_L2, CosemObjectType.EMETER_INSTANT_CURRENT_L3,
291                     CosemObjectType.EMETER_INSTANT_POWER_DELIVERY_L1, CosemObjectType.EMETER_INSTANT_POWER_DELIVERY_L2,
292                     CosemObjectType.EMETER_INSTANT_POWER_DELIVERY_L3, CosemObjectType.EMETER_INSTANT_POWER_PRODUCTION_L1,
293                     CosemObjectType.EMETER_INSTANT_POWER_PRODUCTION_L2, CosemObjectType.EMETER_INSTANT_POWER_PRODUCTION_L3,
294                     CosemObjectType.EMETER_INSTANT_REACTIVE_POWER_DELIVERY_L1, CosemObjectType.EMETER_INSTANT_REACTIVE_POWER_DELIVERY_L2,
295                     CosemObjectType.EMETER_INSTANT_REACTIVE_POWER_DELIVERY_L3, CosemObjectType.EMETER_INSTANT_REACTIVE_POWER_PRODUCTION_L1,
296                     CosemObjectType.EMETER_INSTANT_REACTIVE_POWER_PRODUCTION_L2, CosemObjectType.EMETER_INSTANT_REACTIVE_POWER_PRODUCTION_L3,
297                     }),
298     /** Belgium Smart Meter for the e-MUCS specification */
299     DEVICE_EMUCS_V1_0(DSMRMeterKind.DEVICE, CosemObjectType.UNKNOWN,
300             CosemObjectType.P1_TEXT_STRING, CosemObjectType.P1_TEXT_STRING, CosemObjectType.P1_EMUCS_VERSION_OUTPUT,
301             CosemObjectType.P1_TIMESTAMP),
302
303     /** Belgium Smart Electricity Meter for the e-MUCS specification */
304     ELECTRICITY_EMUCS_V1_0(DSMRMeterKind.MAIN_ELECTRICITY, CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER,
305             new CosemObjectType[] {
306                     CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER, CosemObjectType.EMETER_DELIVERY_TARIFF1,
307                     CosemObjectType.EMETER_DELIVERY_TARIFF2, CosemObjectType.EMETER_PRODUCTION_TARIFF1,
308                     CosemObjectType.EMETER_PRODUCTION_TARIFF2, CosemObjectType.EMETER_TARIFF_INDICATOR,
309                     CosemObjectType.EMETER_ACTUAL_DELIVERY, CosemObjectType.EMETER_ACTUAL_PRODUCTION,
310                     CosemObjectType.EMETER_TRESHOLD_KWH, CosemObjectType.EMETER_FUSE_THRESHOLD_A,
311                     CosemObjectType.EMETER_SWITCH_POSITION},
312             new CosemObjectType[] {
313                     CosemObjectType.EMETER_INSTANT_CURRENT_L1, CosemObjectType.EMETER_INSTANT_CURRENT_L2,
314                     CosemObjectType.EMETER_INSTANT_CURRENT_L3, CosemObjectType.EMETER_INSTANT_VOLTAGE_L1,
315                     CosemObjectType.EMETER_INSTANT_VOLTAGE_L2, CosemObjectType.EMETER_INSTANT_VOLTAGE_L3
316                     }),
317
318     /** Belgium Smart Gas Meter for the e-MUCS specification */
319     GAS_EMUCS_V1_0(DSMRMeterKind.GAS, CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER,
320             new CosemObjectType[] {
321                     CosemObjectType.EMETER_EQUIPMENT_IDENTIFIER, CosemObjectType.METER_DEVICE_TYPE,
322                     CosemObjectType.GMETER_LAST_VALUE, CosemObjectType.METER_VALVE_SWITCH_POSITION });
323     // @formatter:on
324
325     public static final Set<ThingTypeUID> METER_THING_TYPES = Arrays.asList(DSMRMeterType.values()).stream()
326             .map(DSMRMeterType::getThingTypeUID).collect(Collectors.toSet());
327
328     private final Logger logger = LoggerFactory.getLogger(DSMRMeterType.class);
329
330     /**
331      * Meter kind
332      */
333     public final DSMRMeterKind meterKind;
334
335     /**
336      * Required objects for this meter type
337      */
338     public final CosemObjectType[] requiredCosemObjects;
339
340     /**
341      * Additional object this meter type can receive
342      */
343     public final CosemObjectType[] optionalCosemObjects;
344
345     /**
346      * All objects this meter type can receive (convenience for {requiredCosemObjects, optionalCosemObjects})
347      */
348     public final CosemObjectType[] supportedCosemObjects;
349
350     /**
351      * Which CosemObjectType is used to identify this meter
352      */
353     public final CosemObjectType cosemObjectTypeMeterId;
354
355     /**
356      * Creates a new enum
357      *
358      * @param meterKind kind of meter
359      * @param cosemObjectTypeMeterId identifier cosem object
360      * @param requiredCosemObjects list of objects that are present in this meter type
361      */
362     DSMRMeterType(DSMRMeterKind meterKind, CosemObjectType cosemObjectTypeMeterId,
363             CosemObjectType... requiredCosemObjects) {
364         this(meterKind, cosemObjectTypeMeterId, requiredCosemObjects, new CosemObjectType[0]);
365     }
366
367     /**
368      * Creates a new enum
369      *
370      * @param meterKind kind of meter
371      * @param cosemObjectTypeMeterId identifier cosem object
372      * @param requiredCosemObjects list of objects that are present in this meter type
373      * @param optionalCosemObjects list of objects that are optional present in this meter type
374      */
375     DSMRMeterType(DSMRMeterKind meterKind, CosemObjectType cosemObjectTypeMeterId,
376             CosemObjectType[] requiredCosemObjects, CosemObjectType[] optionalCosemObjects) {
377         this.meterKind = meterKind;
378         this.cosemObjectTypeMeterId = cosemObjectTypeMeterId;
379         this.requiredCosemObjects = requiredCosemObjects;
380         this.optionalCosemObjects = optionalCosemObjects;
381
382         supportedCosemObjects = new CosemObjectType[requiredCosemObjects.length + optionalCosemObjects.length];
383         System.arraycopy(requiredCosemObjects, 0, supportedCosemObjects, 0, requiredCosemObjects.length);
384         System.arraycopy(optionalCosemObjects, 0, supportedCosemObjects, requiredCosemObjects.length,
385                 optionalCosemObjects.length);
386     }
387
388     /**
389      * Returns if this DSMRMeterType is compatible for the Cosem Objects.
390      *
391      * If successful the real OBIS identification message (including the actual channel and identification value)
392      * is returned.
393      * If the meter is compatible but the meter type has no identification message, a message is created using the
394      * UNKNOWN OBISMsgType and no value.
395      * If the meter is not compatible, null is returned
396      *
397      *
398      * @param availableCosemObjects the Cosem Objects to detect if the current meter compatible
399      * @return {@link DSMRMeterDescriptor} containing the identification of the compatible meter
400      */
401     public DSMRMeterDescriptor isCompatible(Map<CosemObjectType, CosemObject> availableCosemObjects) {
402         DSMRMeterDescriptor meterDescriptor = null;
403
404         for (CosemObjectType objectType : requiredCosemObjects) {
405             if (!availableCosemObjects.containsKey(objectType)) {
406                 logger.trace("Required objectType {} not found", objectType);
407                 return null;
408             } else {
409                 logger.trace("FOUND Required objectType {}", objectType);
410             }
411             CosemObject cosemObject = availableCosemObjects.get(objectType);
412
413             // Checking by reference is possible here due to comparing enums
414             if (cosemObjectTypeMeterId != CosemObjectType.UNKNOWN && objectType == cosemObjectTypeMeterId) {
415                 meterDescriptor = new DSMRMeterDescriptor(this, cosemObject.getObisIdentifier().getGroupB());
416             }
417         }
418         // Meter type is compatible, check if an identification exists
419         if (meterDescriptor == null && cosemObjectTypeMeterId == CosemObjectType.UNKNOWN) {
420             logger.trace("Meter type {} has no identification, but is compatible", this);
421             meterDescriptor = new DSMRMeterDescriptor(this, DSMRMeterConstants.UNKNOWN_CHANNEL);
422         } else if (meterDescriptor != null) {
423             logger.trace("Meter type is compatible and has the following meter type:{}", this);
424         }
425         return meterDescriptor;
426     }
427
428     /**
429      * Returns the ThingTypeUID for this meterType
430      *
431      * @return {@link ThingTypeUID} containing the unique identifier for this meter type
432      */
433     public ThingTypeUID getThingTypeUID() {
434         return new ThingTypeUID(DSMRBindingConstants.BINDING_ID, name().toLowerCase());
435     }
436 }