2 * Copyright (c) 2010-2022 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.mcp23017.internal.handler;
15 import static org.openhab.binding.mcp23017.internal.Mcp23017BindingConstants.DEFAULT_STATE;
17 import java.util.HashMap;
19 import java.util.Map.Entry;
20 import java.util.Optional;
22 import org.openhab.binding.mcp23017.internal.GPIODataHolder;
23 import org.openhab.binding.mcp23017.internal.PinMapper;
24 import org.openhab.core.config.core.Configuration;
25 import org.openhab.core.thing.ChannelUID;
26 import org.openhab.core.thing.Thing;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
30 import com.pi4j.gpio.extension.mcp.MCP23017GpioProvider;
31 import com.pi4j.io.gpio.GpioPin;
32 import com.pi4j.io.gpio.GpioPinDigitalInput;
33 import com.pi4j.io.gpio.GpioPinDigitalOutput;
34 import com.pi4j.io.gpio.Pin;
35 import com.pi4j.io.gpio.PinState;
38 * The {@link Mcp23017PinStateHolder} is a class where MCP23017 PIN state is held
40 * @author Anatol Ogorek - Initial contribution
42 public class Mcp23017PinStateHolder {
44 private final Logger logger = LoggerFactory.getLogger(getClass());
45 private Map<ChannelUID, GpioPinDigitalInput> inputPins = new HashMap<>();
46 private Map<ChannelUID, GpioPinDigitalOutput> outputPins = new HashMap<>();
47 private MCP23017GpioProvider mcpProvider;
50 public Mcp23017PinStateHolder(MCP23017GpioProvider mcpProvider, Thing thing) {
51 this.mcpProvider = mcpProvider;
55 public GpioPin getInputPin(ChannelUID channel) {
56 return inputPins.get(channel);
59 public GpioPinDigitalOutput getOutputPin(ChannelUID channel) {
60 logger.debug("Getting output pin for channel {}", channel);
61 GpioPinDigitalOutput outputPin = outputPins.get(channel);
62 if (outputPin == null) {
63 outputPin = initializeOutputPin(channel);
64 outputPins.put(channel, outputPin);
69 private GpioPinDigitalOutput initializeOutputPin(ChannelUID channel) {
70 Pin pin = PinMapper.get(channel.getIdWithoutGroup());
71 logger.debug("initializeOutputPin for channel {}", channel);
72 Configuration configuration = thing.getChannel(channel.getId()).getConfiguration();
73 PinState pinState = PinState.valueOf((String) configuration.get(DEFAULT_STATE));
74 logger.debug("initializing for pinState {}", pinState);
75 GpioPinDigitalOutput gpioPin = GPIODataHolder.GPIO.provisionDigitalOutputPin(mcpProvider, pin,
76 channel.getIdWithoutGroup(), pinState);
77 logger.debug("Bound digital output for PIN: {}, channel: {}, pinState: {}", pin, channel, pinState);
81 public void unBindGpioPins() {
82 inputPins.values().stream().forEach(gpioPin -> GPIODataHolder.GPIO.unprovisionPin(gpioPin));
85 outputPins.values().stream().forEach(gpioPin -> GPIODataHolder.GPIO.unprovisionPin(gpioPin));
89 public ChannelUID getChannelForInputPin(GpioPinDigitalInput pin) {
90 Optional<Entry<ChannelUID, GpioPinDigitalInput>> result = inputPins.entrySet().stream()
91 .filter(entry -> entry.getValue().equals(pin)).findFirst();
92 if (result.isPresent()) {
93 return result.get().getKey();
98 public void addInputPin(GpioPinDigitalInput pin, ChannelUID channel) {
99 inputPins.put(channel, pin);