]> git.basschouten.com Git - openhab-addons.git/blob
0ce8d4667bad9aff5ee69cb4ec118f4486d74575
[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.smartmeter.internal;
14
15 import java.net.URI;
16 import java.util.Collection;
17 import java.util.Locale;
18 import java.util.Map;
19 import java.util.concurrent.ConcurrentHashMap;
20
21 import javax.measure.Quantity;
22 import javax.measure.Unit;
23
24 import org.eclipse.jdt.annotation.NonNull;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.smartmeter.SmartMeterBindingConstants;
27 import org.openhab.core.library.CoreItemFactory;
28 import org.openhab.core.thing.type.ChannelType;
29 import org.openhab.core.thing.type.ChannelTypeBuilder;
30 import org.openhab.core.thing.type.ChannelTypeProvider;
31 import org.openhab.core.thing.type.ChannelTypeUID;
32 import org.openhab.core.thing.type.StateChannelTypeBuilder;
33 import org.openhab.core.types.StateDescriptionFragmentBuilder;
34 import org.openhab.core.types.util.UnitUtils;
35 import org.osgi.service.component.annotations.Component;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * A {@link ChannelTypeProvider} that listens for changes to the {@link MeterDevice} and updates the
41  * {@link ChannelType}s according to all available OBIS values.
42  * It creates one {@link ChannelType} per available OBIS value.
43  *
44  * @author Matthias Steigenberger - Initial contribution
45  *
46  */
47 @Component(service = { ChannelTypeProvider.class, SmartMeterChannelTypeProvider.class })
48 public class SmartMeterChannelTypeProvider implements ChannelTypeProvider, MeterValueListener {
49
50     private final Logger logger = LoggerFactory.getLogger(SmartMeterChannelTypeProvider.class);
51
52     private final Map<String, ChannelType> obisChannelMap = new ConcurrentHashMap<>();
53
54     @Override
55     public Collection<ChannelType> getChannelTypes(@Nullable Locale locale) {
56         return obisChannelMap.values();
57     }
58
59     @Override
60     public @Nullable ChannelType getChannelType(ChannelTypeUID channelTypeUID, @Nullable Locale locale) {
61         return obisChannelMap.values().stream().filter(channelType -> channelType.getUID().equals(channelTypeUID))
62                 .findFirst().orElse(null);
63     }
64
65     @Override
66     public void errorOccurred(Throwable e) {
67         // Nothing to do if there is a reading error...
68     }
69
70     @Override
71     public <Q extends @NonNull Quantity<Q>> void valueChanged(MeterValue<Q> value) {
72         if (!obisChannelMap.containsKey(value.getObisCode())) {
73             logger.debug("Creating ChannelType for OBIS {}", value.getObisCode());
74             obisChannelMap.put(value.getObisCode(), getChannelType(value.getUnit(), value.getObisCode()));
75         }
76     }
77
78     private ChannelType getChannelType(Unit<?> unit, String obis) {
79         String obisChannelId = SmartMeterBindingConstants.getObisChannelId(obis);
80         StateChannelTypeBuilder stateDescriptionBuilder;
81         if (unit != null) {
82             String dimension = UnitUtils.getDimensionName(unit);
83             stateDescriptionBuilder = ChannelTypeBuilder
84                     .state(new ChannelTypeUID(SmartMeterBindingConstants.BINDING_ID, obisChannelId), obis,
85                             CoreItemFactory.NUMBER + ":" + dimension)
86                     .withStateDescriptionFragment(StateDescriptionFragmentBuilder.create().withReadOnly(true)
87                             .withPattern("%.2f %unit%").build())
88                     .withConfigDescriptionURI(URI.create(SmartMeterBindingConstants.CHANNEL_TYPE_METERREADER_OBIS));
89         } else {
90             stateDescriptionBuilder = ChannelTypeBuilder
91                     .state(new ChannelTypeUID(SmartMeterBindingConstants.BINDING_ID, obisChannelId), obis,
92                             CoreItemFactory.STRING)
93                     .withStateDescriptionFragment(StateDescriptionFragmentBuilder.create().withReadOnly(true).build());
94         }
95         return stateDescriptionBuilder.build();
96     }
97
98     @Override
99     public <Q extends @NonNull Quantity<Q>> void valueRemoved(MeterValue<Q> value) {
100         obisChannelMap.remove(value.getObisCode());
101     }
102
103     /**
104      * Gets the {@link ChannelTypeUID} for the given OBIS code.
105      *
106      * @param obis The obis code.
107      * @return The {@link ChannelTypeUID} or null.
108      */
109     public ChannelTypeUID getChannelTypeIdForObis(String obis) {
110         ChannelType channeltype = obisChannelMap.get(obis);
111         return channeltype != null ? channeltype.getUID() : null;
112     }
113 }