]> git.basschouten.com Git - openhab-addons.git/blob
f7450c52c0884bb2ff003be30ea0680cecf48fb6
[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.net.DatagramPacket;
17 import java.net.InetAddress;
18 import java.net.MulticastSocket;
19 import java.nio.ByteBuffer;
20 import java.util.Arrays;
21 import java.util.Date;
22
23 import org.openhab.core.library.types.DecimalType;
24
25 /**
26  * The {@link EnergyMeter} class is responsible for communication with the SMA device
27  * and extracting the data fields out of the received telegrams.
28  *
29  * @author Osman Basha - Initial contribution
30  */
31 public class EnergyMeter {
32
33     private String multicastGroup;
34     private int port;
35
36     private String serialNumber;
37     private Date lastUpdate;
38
39     private final FieldDTO powerIn;
40     private final FieldDTO energyIn;
41     private final FieldDTO powerOut;
42     private final FieldDTO energyOut;
43     private final FieldDTO powerInL1;
44     private final FieldDTO energyInL1;
45     private final FieldDTO powerOutL1;
46     private final FieldDTO energyOutL1;
47     private final FieldDTO powerInL2;
48     private final FieldDTO energyInL2;
49     private final FieldDTO powerOutL2;
50     private final FieldDTO energyOutL2;
51     private final FieldDTO powerInL3;
52     private final FieldDTO energyInL3;
53     private final FieldDTO powerOutL3;
54     private final FieldDTO energyOutL3;
55
56     public static final String DEFAULT_MCAST_GRP = "239.12.255.254";
57     public static final int DEFAULT_MCAST_PORT = 9522;
58
59     public EnergyMeter(String multicastGroup, int port) {
60         this.multicastGroup = multicastGroup;
61         this.port = port;
62
63         powerIn = new FieldDTO(0x20, 4, 10);
64         energyIn = new FieldDTO(0x28, 8, 3600000);
65         powerOut = new FieldDTO(0x34, 4, 10);
66         energyOut = new FieldDTO(0x3C, 8, 3600000);
67
68         powerInL1 = new FieldDTO(0xA8, 4, 10);
69         energyInL1 = new FieldDTO(0xB0, 8, 3600000); // +8
70         powerOutL1 = new FieldDTO(0xBC, 4, 10); // + C
71         energyOutL1 = new FieldDTO(0xC4, 8, 3600000); // +8
72
73         powerInL2 = new FieldDTO(0x138, 4, 10);
74         energyInL2 = new FieldDTO(0x140, 8, 3600000); // +8
75         powerOutL2 = new FieldDTO(0x14C, 4, 10); // + C
76         energyOutL2 = new FieldDTO(0x154, 8, 3600000); // +8
77
78         powerInL3 = new FieldDTO(0x1C8, 4, 10);
79         energyInL3 = new FieldDTO(0x1D0, 8, 3600000); // +8
80         powerOutL3 = new FieldDTO(0x1DC, 4, 10); // + C
81         energyOutL3 = new FieldDTO(0x1E4, 8, 3600000); // +8
82     }
83
84     public void update() throws IOException {
85         byte[] bytes = new byte[608];
86         try (MulticastSocket socket = new MulticastSocket(port)) {
87             socket.setSoTimeout(5000);
88             InetAddress address = InetAddress.getByName(multicastGroup);
89             socket.joinGroup(address);
90
91             DatagramPacket msgPacket = new DatagramPacket(bytes, bytes.length);
92             socket.receive(msgPacket);
93
94             String sma = new String(Arrays.copyOfRange(bytes, 0x00, 0x03));
95             if (!"SMA".equals(sma)) {
96                 throw new IOException("Not a SMA telegram." + sma);
97             }
98
99             ByteBuffer buffer = ByteBuffer.wrap(Arrays.copyOfRange(bytes, 0x14, 0x18));
100             serialNumber = String.valueOf(buffer.getInt());
101
102             powerIn.updateValue(bytes);
103             energyIn.updateValue(bytes);
104             powerOut.updateValue(bytes);
105             energyOut.updateValue(bytes);
106
107             powerInL1.updateValue(bytes);
108             energyInL1.updateValue(bytes);
109             powerOutL1.updateValue(bytes);
110             energyOutL1.updateValue(bytes);
111
112             powerInL2.updateValue(bytes);
113             energyInL2.updateValue(bytes);
114             powerOutL2.updateValue(bytes);
115             energyOutL2.updateValue(bytes);
116
117             powerInL3.updateValue(bytes);
118             energyInL3.updateValue(bytes);
119             powerOutL3.updateValue(bytes);
120             energyOutL3.updateValue(bytes);
121
122             lastUpdate = new Date(System.currentTimeMillis());
123         } catch (Exception e) {
124             throw new IOException(e);
125         }
126     }
127
128     public String getSerialNumber() {
129         return serialNumber;
130     }
131
132     public Date getLastUpdate() {
133         return lastUpdate;
134     }
135
136     public DecimalType getPowerIn() {
137         return new DecimalType(powerIn.getValue());
138     }
139
140     public DecimalType getPowerOut() {
141         return new DecimalType(powerOut.getValue());
142     }
143
144     public DecimalType getEnergyIn() {
145         return new DecimalType(energyIn.getValue());
146     }
147
148     public DecimalType getEnergyOut() {
149         return new DecimalType(energyOut.getValue());
150     }
151
152     public DecimalType getPowerInL1() {
153         return new DecimalType(powerInL1.getValue());
154     }
155
156     public DecimalType getPowerOutL1() {
157         return new DecimalType(powerOutL1.getValue());
158     }
159
160     public DecimalType getEnergyInL1() {
161         return new DecimalType(energyInL1.getValue());
162     }
163
164     public DecimalType getEnergyOutL1() {
165         return new DecimalType(energyOutL1.getValue());
166     }
167
168     public DecimalType getPowerInL2() {
169         return new DecimalType(powerInL2.getValue());
170     }
171
172     public DecimalType getPowerOutL2() {
173         return new DecimalType(powerOutL2.getValue());
174     }
175
176     public DecimalType getEnergyInL2() {
177         return new DecimalType(energyInL2.getValue());
178     }
179
180     public DecimalType getEnergyOutL2() {
181         return new DecimalType(energyOutL2.getValue());
182     }
183
184     public DecimalType getPowerInL3() {
185         return new DecimalType(powerInL3.getValue());
186     }
187
188     public DecimalType getPowerOutL3() {
189         return new DecimalType(powerOutL3.getValue());
190     }
191
192     public DecimalType getEnergyInL3() {
193         return new DecimalType(energyInL3.getValue());
194     }
195
196     public DecimalType getEnergyOutL3() {
197         return new DecimalType(energyOutL3.getValue());
198     }
199 }