2 * Copyright (c) 2010-2023 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.mybmw.internal.utils;
15 import static org.openhab.binding.mybmw.internal.utils.ChargingProfileWrapper.ProfileKey.TIMER1;
16 import static org.openhab.binding.mybmw.internal.utils.ChargingProfileWrapper.ProfileKey.TIMER2;
17 import static org.openhab.binding.mybmw.internal.utils.ChargingProfileWrapper.ProfileKey.TIMER3;
18 import static org.openhab.binding.mybmw.internal.utils.ChargingProfileWrapper.ProfileKey.TIMER4;
19 import static org.openhab.binding.mybmw.internal.utils.ChargingProfileWrapper.ProfileKey.WINDOWEND;
20 import static org.openhab.binding.mybmw.internal.utils.ChargingProfileWrapper.ProfileKey.WINDOWSTART;
21 import static org.openhab.binding.mybmw.internal.utils.Constants.NULL_LOCAL_TIME;
22 import static org.openhab.binding.mybmw.internal.utils.Constants.TIME_FORMATER;
24 import java.time.DayOfWeek;
25 import java.time.LocalTime;
26 import java.time.format.DateTimeParseException;
27 import java.util.EnumSet;
28 import java.util.HashMap;
30 import java.util.Optional;
33 import org.eclipse.jdt.annotation.NonNullByDefault;
34 import org.eclipse.jdt.annotation.Nullable;
35 import org.openhab.binding.mybmw.internal.MyBMWConstants.ChargingMode;
36 import org.openhab.binding.mybmw.internal.MyBMWConstants.ChargingPreference;
37 import org.openhab.binding.mybmw.internal.dto.charge.ChargingProfile;
38 import org.openhab.binding.mybmw.internal.dto.charge.ChargingSettings;
39 import org.openhab.binding.mybmw.internal.dto.charge.Time;
40 import org.openhab.binding.mybmw.internal.dto.charge.Timer;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
45 * The {@link ChargingProfileWrapper} Wrapper for ChargingProfiles
47 * @author Bernd Weymann - Initial contribution
48 * @author Norbert Truchsess - add ChargeProfileActions
49 * @author Martin Grassl - refactoring
52 public class ChargingProfileWrapper {
53 private final Logger logger = LoggerFactory.getLogger(ChargingProfileWrapper.class);
55 private static final String CHARGING_WINDOW = "CHARGING_WINDOW";
56 private static final String WEEKLY_PLANNER = "WEEKLY_PLANNER";
57 private static final String ACTIVATE = "ACTIVATE";
58 // not used private static final String DEACTIVATE = "DEACTIVATE";
60 public enum ProfileKey {
70 private Optional<ChargingMode> mode = Optional.empty();
71 private Optional<ChargingPreference> preference = Optional.empty();
72 private Optional<String> controlType = Optional.empty();
73 private Optional<ChargingSettings> chargeSettings = Optional.empty();
75 private final Map<ProfileKey, Boolean> enabled = new HashMap<>();
76 private final Map<ProfileKey, LocalTime> times = new HashMap<>();
77 private final Map<ProfileKey, Set<DayOfWeek>> daysOfWeek = new HashMap<>();
79 public ChargingProfileWrapper(final ChargingProfile profile) {
80 setPreference(profile.getChargingPreference());
81 setMode(profile.getChargingMode());
82 controlType = Optional.of(profile.getChargingControlType());
83 chargeSettings = Optional.of(profile.getChargingSettings());
84 setEnabled(ProfileKey.CLIMATE, profile.isClimatisationOn());
86 addTimer(TIMER1, profile.getTimerId(1));
87 addTimer(TIMER2, profile.getTimerId(2));
88 if (profile.getChargingControlType().equals(WEEKLY_PLANNER)) {
89 addTimer(TIMER3, profile.getTimerId(3));
90 addTimer(TIMER4, profile.getTimerId(4));
93 if (CHARGING_WINDOW.equals(profile.getChargingPreference())) {
94 addTime(WINDOWSTART, profile.getReductionOfChargeCurrent().getStart());
95 addTime(WINDOWEND, profile.getReductionOfChargeCurrent().getEnd());
97 preference.ifPresent(pref -> {
98 if (ChargingPreference.CHARGING_WINDOW.equals(pref)) {
99 addTime(WINDOWSTART, null);
100 addTime(WINDOWEND, null);
106 public @Nullable Boolean isEnabled(final ProfileKey key) {
107 return enabled.get(key);
110 public void setEnabled(final ProfileKey key, @Nullable final Boolean enabled) {
111 if (enabled == null) {
112 this.enabled.remove(key);
114 this.enabled.put(key, enabled);
118 public @Nullable String getMode() {
119 return mode.map(m -> m.name()).orElse(null);
122 public @Nullable String getControlType() {
123 return controlType.get();
126 public @Nullable ChargingSettings getChargingSettings() {
127 return chargeSettings.get();
130 public void setMode(final @Nullable String mode) {
133 this.mode = Optional.of(ChargingMode.valueOf(mode));
135 } catch (IllegalArgumentException iae) {
136 logger.warn("unexpected value for chargingMode: {}", mode);
139 this.mode = Optional.empty();
142 public @Nullable String getPreference() {
143 return preference.map(pref -> pref.name()).orElse(null);
146 public void setPreference(final @Nullable String preference) {
147 if (preference != null) {
149 this.preference = Optional.of(ChargingPreference.valueOf(preference));
151 } catch (IllegalArgumentException iae) {
152 logger.warn("unexpected value for chargingPreference: {}", preference);
155 this.preference = Optional.empty();
158 public @Nullable Set<DayOfWeek> getDays(final ProfileKey key) {
159 return daysOfWeek.get(key);
162 public LocalTime getTime(final ProfileKey key) {
163 LocalTime t = times.get(key);
167 logger.debug("Profile not valid - Key {} doesn't contain boolean value", key);
168 return Constants.NULL_LOCAL_TIME;
172 private void addTime(final ProfileKey key, @Nullable final Time time) {
174 times.put(key, time == null ? NULL_LOCAL_TIME : LocalTime.parse(Converter.getTime(time), TIME_FORMATER));
175 } catch (DateTimeParseException dtpe) {
176 logger.warn("unexpected value for {} time: {}", key.name(), time);
180 private void addTimer(final ProfileKey key, @Nullable final Timer timer) {
182 enabled.put(key, false);
184 daysOfWeek.put(key, EnumSet.noneOf(DayOfWeek.class));
186 enabled.put(key, ACTIVATE.equals(timer.action));
187 addTime(key, timer.timeStamp);
188 final EnumSet<DayOfWeek> daySet = EnumSet.noneOf(DayOfWeek.class);
189 if (timer.timerWeekDays != null) {
190 daysOfWeek.put(key, EnumSet.noneOf(DayOfWeek.class));
191 for (String day : timer.timerWeekDays) {
193 daySet.add(DayOfWeek.valueOf(day.toUpperCase()));
194 } catch (IllegalArgumentException iae) {
195 logger.warn("unexpected value for {} day: {}", key.name(), day);
197 daysOfWeek.put(key, daySet);