2 * Copyright (c) 2010-2020 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.dsmr.internal.device.cosem;
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;
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;
29 * CosemDate represents a datetime value and will try to autodetect the format
31 * @author M. Volaart - Initial contribution
32 * @author Hilbrand Bouwkamp - Class now a factory instead of data containing class
35 class CosemDate extends CosemValueDescriptor<DateTimeType> {
37 public static final CosemDate INSTANCE = new CosemDate("timestamp");
39 private final Logger logger = LoggerFactory.getLogger(CosemDate.class);
41 public CosemDate(String ohChannelId) {
46 * This enum contains the known date formats for the DSMR-specification
48 private enum CosemDateFormat {
50 * Ignore DST setting for general format. We use local time that is already DST
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");
56 * Cached compiled pattern
58 private final Pattern pattern;
61 * Cached java date formatter
63 private final DateTimeFormatter formatter;
66 * Constructs a new CosemDateFormat
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
72 private CosemDateFormat(String regex, String javaDateFormat) {
73 pattern = Pattern.compile(regex);
74 formatter = DateTimeFormatter.ofPattern(javaDateFormat);
79 * Parses a String value to an openHAB DateTimeType
81 * The input string must be in the format yyMMddHHmmssX
83 * Based on the DSMR specification X is:
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
91 * @param cosemValue the value to parse
92 * @return {@link DateTimeType} representing the value the cosem value
93 * @throws ParseException if parsing failed
96 protected DateTimeType getStateValue(String cosemValue) throws ParseException {
97 for (CosemDateFormat cosemDateFormat : CosemDateFormat.values()) {
98 logger.trace("Trying pattern: {}", cosemDateFormat.pattern);
100 Matcher m = cosemDateFormat.pattern.matcher(cosemValue);
103 logger.trace("{} matches pattern: {}", cosemValue, cosemDateFormat.pattern);
105 LocalDateTime localDateTime = LocalDateTime.parse(m.group(1), cosemDateFormat.formatter);
106 return new DateTimeType(ZonedDateTime.of(localDateTime, ZoneId.systemDefault()));
109 throw new ParseException("Cosem value: '" + cosemValue + "' is not a known CosemDate string", 0);