]> git.basschouten.com Git - openhab-addons.git/blob
1e029a4d6f57acda2f247a38f1842fe7eb4a9410
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.plugwise.internal.protocol;
14
15 import static java.time.ZoneOffset.UTC;
16 import static org.openhab.binding.plugwise.internal.protocol.field.MessageType.POWER_BUFFER_RESPONSE;
17
18 import java.time.ZonedDateTime;
19 import java.util.regex.Matcher;
20 import java.util.regex.Pattern;
21
22 import org.openhab.binding.plugwise.internal.protocol.field.Energy;
23 import org.openhab.binding.plugwise.internal.protocol.field.MACAddress;
24 import org.openhab.binding.plugwise.internal.protocol.field.PowerCalibration;
25
26 /**
27  * Contains the historical pulse measurements at a certain log address from a device (Circle, Circle+, Stealth). This
28  * message is the response of a {@link PowerBufferRequestMessage}. The consumed/produced {@link Energy} (kWh) of the
29  * datapoints can be calculated using {@link PowerCalibration} data.
30  *
31  * @author Wouter Born, Karel Goderis - Initial contribution
32  */
33 public class PowerBufferResponseMessage extends Message {
34
35     private static final Pattern PAYLOAD_PATTERN = Pattern
36             .compile("(\\w{16})(\\w{8})(\\w{8})(\\w{8})(\\w{8})(\\w{8})(\\w{8})(\\w{8})(\\w{8})(\\w{8})");
37     private static final String EMPTY_TIMESTAMP = "FFFFFFFF";
38
39     private Energy[] datapoints;
40     private int logAddress;
41
42     public PowerBufferResponseMessage(int sequenceNumber, String payload) {
43         super(POWER_BUFFER_RESPONSE, sequenceNumber, payload);
44     }
45
46     public Energy[] getDatapoints() {
47         return datapoints;
48     }
49
50     public int getLogAddress() {
51         return logAddress;
52     }
53
54     public Energy getMostRecentDatapoint() {
55         Energy result = null;
56         for (Energy datapoint : datapoints) {
57             if (datapoint != null) {
58                 result = datapoint;
59             }
60         }
61         return result;
62     }
63
64     private Energy parseEnergy(String timeHex, String pulsesHex) {
65         ZonedDateTime utcDateTime = !timeHex.equals(EMPTY_TIMESTAMP) ? parseDateTime(timeHex) : null;
66         if (utcDateTime == null) {
67             return null;
68         }
69         long pulses = Long.parseLong(pulsesHex, 16);
70         return new Energy(utcDateTime, pulses);
71     }
72
73     @Override
74     protected void parsePayload() {
75         Matcher matcher = PAYLOAD_PATTERN.matcher(payload);
76         if (matcher.matches()) {
77             macAddress = new MACAddress(matcher.group(1));
78             datapoints = new Energy[4];
79             datapoints[0] = parseEnergy(matcher.group(2), matcher.group(3));
80             datapoints[1] = parseEnergy(matcher.group(4), matcher.group(5));
81             datapoints[2] = parseEnergy(matcher.group(6), matcher.group(7));
82             datapoints[3] = parseEnergy(matcher.group(8), matcher.group(9));
83             logAddress = (Integer.parseInt(matcher.group(10), 16) - 278528) / 32;
84         } else {
85             throw new PlugwisePayloadMismatchException(POWER_BUFFER_RESPONSE, PAYLOAD_PATTERN, payload);
86         }
87     }
88
89     private ZonedDateTime parseDateTime(String timeHex) {
90         int year = Integer.parseInt(timeHex.substring(0, 2), 16) + 2000;
91         int month = Integer.parseInt(timeHex.substring(2, 4), 16);
92         int minutes = Integer.parseInt(timeHex.substring(4, 8), 16);
93
94         return ZonedDateTime.of(year, month, 1, 0, 0, 0, 0, UTC).plusMinutes(minutes);
95     }
96 }