]> git.basschouten.com Git - openhab-addons.git/blob
ae25430dcb3b4f356e548da6a8c5ca6b00b8a4bb
[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.mybmw.internal.utils;
14
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;
23
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;
29 import java.util.Map;
30 import java.util.Optional;
31 import java.util.Set;
32
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;
43
44 /**
45  * The {@link ChargingProfileWrapper} Wrapper for ChargingProfiles
46  *
47  * @author Bernd Weymann - Initial contribution
48  * @author Norbert Truchsess - add ChargeProfileActions
49  * @author Martin Grassl - refactoring
50  */
51 @NonNullByDefault
52 public class ChargingProfileWrapper {
53     private final Logger logger = LoggerFactory.getLogger(ChargingProfileWrapper.class);
54
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";
59
60     public enum ProfileKey {
61         CLIMATE,
62         TIMER1,
63         TIMER2,
64         TIMER3,
65         TIMER4,
66         WINDOWSTART,
67         WINDOWEND
68     }
69
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();
74
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<>();
78
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());
85
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));
91         }
92
93         if (CHARGING_WINDOW.equals(profile.getChargingPreference())) {
94             addTime(WINDOWSTART, profile.getReductionOfChargeCurrent().getStart());
95             addTime(WINDOWEND, profile.getReductionOfChargeCurrent().getEnd());
96         } else {
97             preference.ifPresent(pref -> {
98                 if (ChargingPreference.CHARGING_WINDOW.equals(pref)) {
99                     addTime(WINDOWSTART, null);
100                     addTime(WINDOWEND, null);
101                 }
102             });
103         }
104     }
105
106     public @Nullable Boolean isEnabled(final ProfileKey key) {
107         return enabled.get(key);
108     }
109
110     public void setEnabled(final ProfileKey key, @Nullable final Boolean enabled) {
111         if (enabled == null) {
112             this.enabled.remove(key);
113         } else {
114             this.enabled.put(key, enabled);
115         }
116     }
117
118     public @Nullable String getMode() {
119         return mode.map(m -> m.name()).orElse(null);
120     }
121
122     public @Nullable String getControlType() {
123         return controlType.get();
124     }
125
126     public @Nullable ChargingSettings getChargingSettings() {
127         return chargeSettings.get();
128     }
129
130     public void setMode(final @Nullable String mode) {
131         if (mode != null) {
132             try {
133                 this.mode = Optional.of(ChargingMode.valueOf(mode));
134                 return;
135             } catch (IllegalArgumentException iae) {
136                 logger.warn("unexpected value for chargingMode: {}", mode);
137             }
138         }
139         this.mode = Optional.empty();
140     }
141
142     public @Nullable String getPreference() {
143         return preference.map(pref -> pref.name()).orElse(null);
144     }
145
146     public void setPreference(final @Nullable String preference) {
147         if (preference != null) {
148             try {
149                 this.preference = Optional.of(ChargingPreference.valueOf(preference));
150                 return;
151             } catch (IllegalArgumentException iae) {
152                 logger.warn("unexpected value for chargingPreference: {}", preference);
153             }
154         }
155         this.preference = Optional.empty();
156     }
157
158     public @Nullable Set<DayOfWeek> getDays(final ProfileKey key) {
159         return daysOfWeek.get(key);
160     }
161
162     public LocalTime getTime(final ProfileKey key) {
163         LocalTime t = times.get(key);
164         if (t != null) {
165             return t;
166         } else {
167             logger.debug("Profile not valid - Key {} doesn't contain boolean value", key);
168             return Constants.NULL_LOCAL_TIME;
169         }
170     }
171
172     private void addTime(final ProfileKey key, @Nullable final Time time) {
173         try {
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);
177         }
178     }
179
180     private void addTimer(final ProfileKey key, @Nullable final Timer timer) {
181         if (timer == null) {
182             enabled.put(key, false);
183             addTime(key, null);
184             daysOfWeek.put(key, EnumSet.noneOf(DayOfWeek.class));
185         } else {
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) {
192                     try {
193                         daySet.add(DayOfWeek.valueOf(day.toUpperCase()));
194                     } catch (IllegalArgumentException iae) {
195                         logger.warn("unexpected value for {} day: {}", key.name(), day);
196                     }
197                     daysOfWeek.put(key, daySet);
198                 }
199             }
200         }
201     }
202 }