]> git.basschouten.com Git - openhab-addons.git/blob
fb5352ec015a7e122131b0a9627e8c577a4b6957
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.netatmo.internal.handler.channelhelper;
14
15 import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
16 import static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.*;
17
18 import java.time.DayOfWeek;
19 import java.time.ZonedDateTime;
20 import java.time.temporal.ChronoUnit;
21 import java.util.List;
22 import java.util.Set;
23
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.SetpointMode;
27 import org.openhab.binding.netatmo.internal.api.dto.HomeData;
28 import org.openhab.binding.netatmo.internal.api.dto.NAThing;
29 import org.openhab.binding.netatmo.internal.api.dto.ThermProgram;
30 import org.openhab.binding.netatmo.internal.api.dto.TimeTableItem;
31 import org.openhab.binding.netatmo.internal.api.dto.Zone;
32 import org.openhab.core.config.core.Configuration;
33 import org.openhab.core.library.types.StringType;
34 import org.openhab.core.library.unit.Units;
35 import org.openhab.core.types.State;
36 import org.openhab.core.types.UnDefType;
37
38 /**
39  * The {@link EnergyChannelHelper} handles specific channels of thermostat settings at home level.
40  *
41  * @author GaĆ«l L'hopital - Initial contribution
42  *
43  */
44 @NonNullByDefault
45 public class EnergyChannelHelper extends ChannelHelper {
46
47     public EnergyChannelHelper(Set<String> providedGroups) {
48         super(providedGroups);
49     }
50
51     @Override
52     protected @Nullable State internalGetProperty(String channelId, NAThing data, Configuration config) {
53         if (data instanceof HomeData.Energy energyData) {
54             SetpointMode thermMode = energyData.getThermMode();
55             ThermProgram currentProgram = energyData.getActiveProgram();
56             switch (channelId) {
57                 case CHANNEL_SETPOINT_DURATION:
58                     return toQuantityType(energyData.getThermSetpointDefaultDuration(), Units.MINUTE);
59                 case CHANNEL_PLANNING:
60                     return (currentProgram != null ? toStringType(currentProgram.getName()) : null);
61                 case CHANNEL_SETPOINT_END_TIME:
62                     switch (thermMode) {
63                         case PROGRAM:
64                         case HOME:
65                         case SCHEDULE:
66                             return currentProgram != null ? toDateTimeType(nextProgramTime(currentProgram))
67                                     : UnDefType.UNDEF;
68                         default:
69                             return UnDefType.UNDEF;
70                     }
71                 case CHANNEL_SETPOINT_MODE:
72                     switch (thermMode) {
73                         case OFF:
74                         case MAX:
75                         case UNKNOWN:
76                             return UnDefType.UNDEF;
77                         case PROGRAM:
78                         case HOME:
79                         case SCHEDULE:
80                             if (currentProgram != null) {
81                                 TimeTableItem currentProgramMode = currentProgramMode(currentProgram);
82                                 if (currentProgramMode != null) {
83                                     Zone zone = currentProgram.getZone(String.valueOf(currentProgramMode.getZoneId()));
84                                     if (zone != null) {
85                                         return new StringType(zone.getName());
86                                     }
87                                 }
88                             }
89                             return UnDefType.NULL;
90                         default:
91                             return toStringType(thermMode);
92                     }
93             }
94         }
95         return null;
96     }
97
98     private static ZonedDateTime programBaseTimeZdt() {
99         return ZonedDateTime.now().with(DayOfWeek.MONDAY).truncatedTo(ChronoUnit.DAYS);
100     }
101
102     private static long minutesSinceProgramBaseTime() {
103         return ChronoUnit.MINUTES.between(programBaseTimeZdt(), ZonedDateTime.now());
104     }
105
106     private static @Nullable TimeTableItem currentProgramMode(ThermProgram activeProgram) {
107         long diff = minutesSinceProgramBaseTime();
108         return activeProgram.getTimetable().stream().filter(t -> t.getMinuteOffset() < diff)
109                 .reduce((first, second) -> second).orElse(null);
110     }
111
112     private static ZonedDateTime nextProgramTime(ThermProgram activeProgram) {
113         long diff = minutesSinceProgramBaseTime();
114         // By default we'll use the first slot of next week - this case will be true if
115         // we are in the last schedule of the week so below loop will not exit by break
116         List<TimeTableItem> timetable = activeProgram.getTimetable();
117         int next = timetable.get(0).getMinuteOffset() + (7 * 24 * 60);
118         for (TimeTableItem timeTable : timetable) {
119             if (timeTable.getMinuteOffset() > diff) {
120                 next = timeTable.getMinuteOffset();
121                 break;
122             }
123         }
124         return programBaseTimeZdt().plusMinutes(next);
125     }
126 }