]> git.basschouten.com Git - openhab-addons.git/blob
3f9852d1a6b107032e8ab219453f4a479f341a7c
[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.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) {
54             HomeData homeData = (HomeData) data;
55             SetpointMode thermMode = homeData.getThermMode();
56             ThermProgram currentProgram = homeData.getActiveProgram();
57             switch (channelId) {
58                 case CHANNEL_SETPOINT_DURATION:
59                     return toQuantityType(homeData.getThermSetpointDefaultDuration(), Units.MINUTE);
60                 case CHANNEL_PLANNING:
61                     return (currentProgram != null ? toStringType(currentProgram.getName()) : null);
62                 case CHANNEL_SETPOINT_END_TIME:
63                     switch (thermMode) {
64                         case PROGRAM:
65                         case HOME:
66                         case SCHEDULE:
67                             return currentProgram != null ? toDateTimeType(nextProgramTime(currentProgram))
68                                     : UnDefType.UNDEF;
69                         default:
70                             return UnDefType.UNDEF;
71                     }
72                 case CHANNEL_SETPOINT_MODE:
73                     switch (thermMode) {
74                         case OFF:
75                         case MAX:
76                         case UNKNOWN:
77                             return UnDefType.UNDEF;
78                         case PROGRAM:
79                         case HOME:
80                         case SCHEDULE:
81                             if (currentProgram != null) {
82                                 TimeTableItem currentProgramMode = currentProgramMode(currentProgram);
83                                 if (currentProgramMode != null) {
84                                     Zone zone = currentProgram.getZone(String.valueOf(currentProgramMode.getZoneId()));
85                                     if (zone != null) {
86                                         return new StringType(zone.getName());
87                                     }
88                                 }
89                             }
90                             return UnDefType.NULL;
91                         default:
92                             return toStringType(thermMode);
93                     }
94             }
95         }
96         return null;
97     }
98
99     private static ZonedDateTime programBaseTimeZdt() {
100         return ZonedDateTime.now().with(DayOfWeek.MONDAY).truncatedTo(ChronoUnit.DAYS);
101     }
102
103     private static long minutesSinceProgramBaseTime() {
104         return ChronoUnit.MINUTES.between(programBaseTimeZdt(), ZonedDateTime.now());
105     }
106
107     private static @Nullable TimeTableItem currentProgramMode(ThermProgram activeProgram) {
108         long diff = minutesSinceProgramBaseTime();
109         return activeProgram.getTimetable().stream().filter(t -> t.getMinuteOffset() < diff)
110                 .reduce((first, second) -> second).orElse(null);
111     }
112
113     private static ZonedDateTime nextProgramTime(ThermProgram activeProgram) {
114         long diff = minutesSinceProgramBaseTime();
115         // By default we'll use the first slot of next week - this case will be true if
116         // we are in the last schedule of the week so below loop will not exit by break
117         List<TimeTableItem> timetable = activeProgram.getTimetable();
118         int next = timetable.get(0).getMinuteOffset() + (7 * 24 * 60);
119         for (TimeTableItem timeTable : timetable) {
120             if (timeTable.getMinuteOffset() > diff) {
121                 next = timeTable.getMinuteOffset();
122                 break;
123             }
124         }
125         return programBaseTimeZdt().plusMinutes(next);
126     }
127 }