]> git.basschouten.com Git - openhab-addons.git/blob
91dea24a86c369765c2bac62203b0a8552e89275
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.smaenergymeter.internal.handler;
14
15 import java.io.IOException;
16 import java.nio.ByteBuffer;
17 import java.util.Arrays;
18
19 import org.openhab.core.library.types.DecimalType;
20
21 /**
22  * The {@link EnergyMeter} class is responsible for communication with the SMA device
23  * and extracting the data fields out of the received telegrams.
24  *
25  * @author Osman Basha - Initial contribution
26  * @author Ćukasz Dywicki - Extracted multicast group handling to
27  *         {@link org.openhab.binding.smaenergymeter.internal.packet.PacketListener}.
28  */
29 public class EnergyMeter {
30
31     private static final byte[] E_METER_PROTOCOL_ID = new byte[] { 0x60, 0x69 };
32
33     private String serialNumber;
34     private final FieldDTO powerIn;
35     private final FieldDTO energyIn;
36     private final FieldDTO powerOut;
37     private final FieldDTO energyOut;
38     private final FieldDTO powerInL1;
39     private final FieldDTO energyInL1;
40     private final FieldDTO powerOutL1;
41     private final FieldDTO energyOutL1;
42     private final FieldDTO powerInL2;
43     private final FieldDTO energyInL2;
44     private final FieldDTO powerOutL2;
45     private final FieldDTO energyOutL2;
46     private final FieldDTO powerInL3;
47     private final FieldDTO energyInL3;
48     private final FieldDTO powerOutL3;
49     private final FieldDTO energyOutL3;
50
51     public EnergyMeter() {
52         powerIn = new FieldDTO(0x20, 4, 10);
53         energyIn = new FieldDTO(0x28, 8, 3600000);
54         powerOut = new FieldDTO(0x34, 4, 10);
55         energyOut = new FieldDTO(0x3C, 8, 3600000);
56
57         powerInL1 = new FieldDTO(0xA8, 4, 10);
58         energyInL1 = new FieldDTO(0xB0, 8, 3600000); // +8
59         powerOutL1 = new FieldDTO(0xBC, 4, 10); // + C
60         energyOutL1 = new FieldDTO(0xC4, 8, 3600000); // +8
61
62         powerInL2 = new FieldDTO(0x138, 4, 10);
63         energyInL2 = new FieldDTO(0x140, 8, 3600000); // +8
64         powerOutL2 = new FieldDTO(0x14C, 4, 10); // + C
65         energyOutL2 = new FieldDTO(0x154, 8, 3600000); // +8
66
67         powerInL3 = new FieldDTO(0x1C8, 4, 10);
68         energyInL3 = new FieldDTO(0x1D0, 8, 3600000); // +8
69         powerOutL3 = new FieldDTO(0x1DC, 4, 10); // + C
70         energyOutL3 = new FieldDTO(0x1E4, 8, 3600000); // +8
71     }
72
73     public void parse(byte[] bytes) throws IOException {
74         try {
75             String sma = new String(Arrays.copyOfRange(bytes, 0, 3));
76             if (!"SMA".equals(sma)) {
77                 throw new IOException("Not a SMA telegram." + sma);
78             }
79             byte[] protocolId = Arrays.copyOfRange(bytes, 16, 18);
80             if (!Arrays.equals(protocolId, E_METER_PROTOCOL_ID)) {
81                 throw new IllegalArgumentException(
82                         "Received frame with wrong protocol ID " + Arrays.toString(protocolId));
83             }
84
85             ByteBuffer buffer = ByteBuffer.wrap(Arrays.copyOfRange(bytes, 0x14, 0x18));
86             serialNumber = Integer.toHexString(buffer.getInt());
87
88             powerIn.updateValue(bytes);
89             energyIn.updateValue(bytes);
90             powerOut.updateValue(bytes);
91             energyOut.updateValue(bytes);
92
93             powerInL1.updateValue(bytes);
94             energyInL1.updateValue(bytes);
95             powerOutL1.updateValue(bytes);
96             energyOutL1.updateValue(bytes);
97
98             powerInL2.updateValue(bytes);
99             energyInL2.updateValue(bytes);
100             powerOutL2.updateValue(bytes);
101             energyOutL2.updateValue(bytes);
102
103             powerInL3.updateValue(bytes);
104             energyInL3.updateValue(bytes);
105             powerOutL3.updateValue(bytes);
106             energyOutL3.updateValue(bytes);
107         } catch (Exception e) {
108             throw new IOException(e);
109         }
110     }
111
112     public String getSerialNumber() {
113         return serialNumber;
114     }
115
116     public DecimalType getPowerIn() {
117         return new DecimalType(powerIn.getValue());
118     }
119
120     public DecimalType getPowerOut() {
121         return new DecimalType(powerOut.getValue());
122     }
123
124     public DecimalType getEnergyIn() {
125         return new DecimalType(energyIn.getValue());
126     }
127
128     public DecimalType getEnergyOut() {
129         return new DecimalType(energyOut.getValue());
130     }
131
132     public DecimalType getPowerInL1() {
133         return new DecimalType(powerInL1.getValue());
134     }
135
136     public DecimalType getPowerOutL1() {
137         return new DecimalType(powerOutL1.getValue());
138     }
139
140     public DecimalType getEnergyInL1() {
141         return new DecimalType(energyInL1.getValue());
142     }
143
144     public DecimalType getEnergyOutL1() {
145         return new DecimalType(energyOutL1.getValue());
146     }
147
148     public DecimalType getPowerInL2() {
149         return new DecimalType(powerInL2.getValue());
150     }
151
152     public DecimalType getPowerOutL2() {
153         return new DecimalType(powerOutL2.getValue());
154     }
155
156     public DecimalType getEnergyInL2() {
157         return new DecimalType(energyInL2.getValue());
158     }
159
160     public DecimalType getEnergyOutL2() {
161         return new DecimalType(energyOutL2.getValue());
162     }
163
164     public DecimalType getPowerInL3() {
165         return new DecimalType(powerInL3.getValue());
166     }
167
168     public DecimalType getPowerOutL3() {
169         return new DecimalType(powerOutL3.getValue());
170     }
171
172     public DecimalType getEnergyInL3() {
173         return new DecimalType(energyInL3.getValue());
174     }
175
176     public DecimalType getEnergyOutL3() {
177         return new DecimalType(energyOutL3.getValue());
178     }
179 }