]> git.basschouten.com Git - openhab-addons.git/blob
60b8bed26fe4561a1a7f251d79a0c69e849eb045
[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.transform.vat.internal.profile;
14
15 import static org.openhab.transform.vat.internal.VATTransformationConstants.*;
16
17 import java.math.BigDecimal;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.openhab.core.i18n.LocaleProvider;
21 import org.openhab.core.library.types.DecimalType;
22 import org.openhab.core.library.types.QuantityType;
23 import org.openhab.core.thing.profiles.ProfileCallback;
24 import org.openhab.core.thing.profiles.ProfileContext;
25 import org.openhab.core.thing.profiles.ProfileTypeUID;
26 import org.openhab.core.thing.profiles.TimeSeriesProfile;
27 import org.openhab.core.transform.TransformationException;
28 import org.openhab.core.transform.TransformationHelper;
29 import org.openhab.core.transform.TransformationService;
30 import org.openhab.core.types.Command;
31 import org.openhab.core.types.State;
32 import org.openhab.core.types.TimeSeries;
33 import org.openhab.core.types.Type;
34 import org.openhab.core.types.UnDefType;
35 import org.openhab.transform.vat.internal.config.VATConfig;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * Profile to offer the {@link VATTransformationProfile} on an ItemChannelLink.
41  *
42  * @author Jacob Laursen - Initial contribution
43  */
44 @NonNullByDefault
45 public class VATTransformationProfile implements TimeSeriesProfile {
46
47     private final Logger logger = LoggerFactory.getLogger(VATTransformationProfile.class);
48
49     private final ProfileCallback callback;
50     private final TransformationService service;
51     private final LocaleProvider localeProvider;
52
53     private VATConfig configuration;
54
55     public VATTransformationProfile(final ProfileCallback callback, final TransformationService service,
56             final ProfileContext context, LocaleProvider localeProvider) {
57         this.callback = callback;
58         this.service = service;
59         this.localeProvider = localeProvider;
60         this.configuration = context.getConfiguration().as(VATConfig.class);
61     }
62
63     @Override
64     public ProfileTypeUID getProfileTypeUID() {
65         return PROFILE_TYPE_UID;
66     }
67
68     @Override
69     public void onCommandFromItem(Command command) {
70         callback.handleCommand(command);
71     }
72
73     @Override
74     public void onStateUpdateFromItem(State state) {
75     }
76
77     @Override
78     public void onCommandFromHandler(Command command) {
79         callback.sendCommand((Command) transformState(command));
80     }
81
82     @Override
83     public void onStateUpdateFromHandler(State state) {
84         callback.sendUpdate((State) transformState(state));
85     }
86
87     @Override
88     public void onTimeSeriesFromHandler(TimeSeries timeSeries) {
89         TimeSeries transformedTimeSeries = new TimeSeries(timeSeries.getPolicy());
90         timeSeries.getStates()
91                 .forEach(entry -> transformedTimeSeries.add(entry.timestamp(), (State) transformState(entry.state())));
92         callback.sendTimeSeries(transformedTimeSeries);
93     }
94
95     private Type transformState(Type state) {
96         String result = state.toFullString();
97         String percentage = getVATPercentage();
98         try {
99             result = TransformationHelper.transform(service, percentage, "%s", result);
100         } catch (TransformationException e) {
101             logger.warn("Could not apply '{}' transformation on state '{}' with value '{}'.", PROFILE_TYPE_UID.getId(),
102                     state, percentage);
103         }
104         Type resultType = state;
105         if (result != null) {
106             if (state instanceof DecimalType) {
107                 resultType = DecimalType.valueOf(result);
108             } else if (state instanceof QuantityType) {
109                 resultType = QuantityType.valueOf(result);
110             } else if (state instanceof UnDefType) {
111                 resultType = UnDefType.valueOf(result);
112             }
113             logger.debug("Transformed '{}' into '{}'", state, resultType);
114         }
115         return resultType;
116     }
117
118     private String getVATPercentage() {
119         if (!configuration.percentage.isBlank()) {
120             return getOverriddenVAT();
121         }
122
123         String country = localeProvider.getLocale().getCountry();
124         String rate = RATES.get(country);
125         if (rate == null) {
126             logger.warn("No VAT rate for country {}", country);
127             return "0";
128         }
129         return rate;
130     }
131
132     private String getOverriddenVAT() {
133         String percentage = configuration.percentage.trim();
134         if (percentage.endsWith("%")) {
135             percentage = percentage.substring(0, percentage.length() - 1).trim();
136         }
137         try {
138             return new BigDecimal(percentage).toString();
139         } catch (NumberFormatException e) {
140             logger.warn("{} is not a valid percentage", percentage);
141             return "0";
142         }
143     }
144 }