]> git.basschouten.com Git - openhab-addons.git/blob
a44afae754828bea7373a4bb93bdd8b51d43170d
[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.device.cosem;
14
15 import java.text.ParseException;
16 import java.time.LocalDateTime;
17 import java.time.ZoneId;
18 import java.time.ZonedDateTime;
19 import java.time.format.DateTimeFormatter;
20 import java.util.regex.Matcher;
21 import java.util.regex.Pattern;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.openhab.core.library.types.DateTimeType;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 /**
29  * CosemDate represents a datetime value and will try to autodetect the format
30  *
31  * @author M. Volaart - Initial contribution
32  * @author Hilbrand Bouwkamp - Class now a factory instead of data containing class
33  */
34 @NonNullByDefault
35 class CosemDate extends CosemValueDescriptor<DateTimeType> {
36
37     public static final CosemDate INSTANCE = new CosemDate("timestamp");
38
39     private final Logger logger = LoggerFactory.getLogger(CosemDate.class);
40
41     public CosemDate(String ohChannelId) {
42         super(ohChannelId);
43     }
44
45     /**
46      * This enum contains the known date formats for the DSMR-specification
47      */
48     private enum CosemDateFormat {
49         /*
50          * Ignore DST setting for general format. We use local time that is already DST
51          */
52         COSEM_DATE_GENERAL("(\\d{12})([S,W]?)", "yyMMddHHmmss"),
53         COSEM_DATE_DSMR_V2("(\\d{2}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2})", "yy-MM-dd HH:mm:ss");
54
55         /**
56          * Cached compiled pattern
57          */
58         private final Pattern pattern;
59
60         /**
61          * Cached java date formatter
62          */
63         private final DateTimeFormatter formatter;
64
65         /**
66          * Constructs a new CosemDateFormat
67          *
68          * @param regex String containing the regular expression to check the value against (the date format
69          *            should at least contain 1 regex group
70          * @param javaDateFormat String containing the datetime format to use for parsing
71          */
72         private CosemDateFormat(String regex, String javaDateFormat) {
73             pattern = Pattern.compile(regex);
74             formatter = DateTimeFormatter.ofPattern(javaDateFormat);
75         }
76     }
77
78     /**
79      * Parses a String value to an openHAB DateTimeType
80      * <p>
81      * The input string must be in the format yyMMddHHmmssX
82      * <p>
83      * Based on the DSMR specification X is:
84      * <p>
85      * <ul>
86      * <li>''. Valid for DSMR v3 specification
87      * <li>'S'. Specifies a summer time (DST = 1) datetime
88      * <li>'W'. Specifies a winter time (DST = 0) datetime
89      * </ul>
90      *
91      * @param cosemValue the value to parse
92      * @return {@link DateTimeType} representing the value the cosem value
93      * @throws ParseException if parsing failed
94      */
95     @Override
96     protected DateTimeType getStateValue(String cosemValue) throws ParseException {
97         for (CosemDateFormat cosemDateFormat : CosemDateFormat.values()) {
98             logger.trace("Trying pattern: {}", cosemDateFormat.pattern);
99
100             Matcher m = cosemDateFormat.pattern.matcher(cosemValue);
101
102             if (m.matches()) {
103                 logger.trace("{} matches pattern: {}", cosemValue, cosemDateFormat.pattern);
104
105                 LocalDateTime localDateTime = LocalDateTime.parse(m.group(1), cosemDateFormat.formatter);
106                 return new DateTimeType(ZonedDateTime.of(localDateTime, ZoneId.systemDefault()));
107             }
108         }
109         throw new ParseException("Cosem value: '" + cosemValue + "' is not a known CosemDate string", 0);
110     }
111 }