Add MCP23017 (#466)

* Add MCP23017

* Add test
This commit is contained in:
Otto Winter 2019-03-03 16:51:55 +01:00 committed by GitHub
parent 067ec30c56
commit 99861259d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 2 deletions

View File

@ -0,0 +1,35 @@
import voluptuous as vol
from esphome import pins
import esphome.config_validation as cv
from esphome.const import CONF_ADDRESS, CONF_ID
from esphome.cpp_generator import Pvariable
from esphome.cpp_helpers import setup_component
from esphome.cpp_types import App, GPIOInputPin, GPIOOutputPin, io_ns
DEPENDENCIES = ['i2c']
MULTI_CONF = True
MCP23017GPIOMode = io_ns.enum('MCP23017GPIOMode')
MCP23017_GPIO_MODES = {
'INPUT': MCP23017GPIOMode.MCP23017_INPUT,
'INPUT_PULLUP': MCP23017GPIOMode.MCP23017_INPUT_PULLUP,
'OUTPUT': MCP23017GPIOMode.MCP23017_OUTPUT,
}
MCP23017GPIOInputPin = io_ns.class_('MCP23017GPIOInputPin', GPIOInputPin)
MCP23017GPIOOutputPin = io_ns.class_('MCP23017GPIOOutputPin', GPIOOutputPin)
CONFIG_SCHEMA = cv.Schema({
vol.Required(CONF_ID): cv.declare_variable_id(pins.MCP23017),
vol.Optional(CONF_ADDRESS, default=0x20): cv.i2c_address,
}).extend(cv.COMPONENT_SCHEMA.schema)
def to_code(config):
rhs = App.make_mcp23017_component(config[CONF_ADDRESS])
var = Pvariable(config[CONF_ID], rhs)
setup_component(var, config)
BUILD_FLAGS = '-DUSE_MCP23017'

View File

@ -199,6 +199,7 @@ CONF_CSS_URL = 'css_url'
CONF_JS_URL = 'js_url' CONF_JS_URL = 'js_url'
CONF_SSL_FINGERPRINTS = 'ssl_fingerprints' CONF_SSL_FINGERPRINTS = 'ssl_fingerprints'
CONF_PCF8574 = 'pcf8574' CONF_PCF8574 = 'pcf8574'
CONF_MCP23017 = 'mcp23017'
CONF_PCF8575 = 'pcf8575' CONF_PCF8575 = 'pcf8575'
CONF_SCAN = 'scan' CONF_SCAN = 'scan'
CONF_KEEPALIVE = 'keepalive' CONF_KEEPALIVE = 'keepalive'

View File

@ -1,5 +1,5 @@
from esphome.const import CONF_INVERTED, CONF_MODE, CONF_NUMBER, CONF_PCF8574, \ from esphome.const import CONF_INVERTED, CONF_MODE, CONF_NUMBER, CONF_PCF8574, \
CONF_SETUP_PRIORITY CONF_SETUP_PRIORITY, CONF_MCP23017
from esphome.core import CORE, EsphomeError from esphome.core import CORE, EsphomeError
from esphome.cpp_generator import IntLiteral, RawExpression from esphome.cpp_generator import IntLiteral, RawExpression
from esphome.cpp_types import GPIOInputPin, GPIOOutputPin from esphome.cpp_types import GPIOInputPin, GPIOOutputPin
@ -24,6 +24,21 @@ def generic_gpio_pin_expression_(conf, mock_obj, default_mode):
yield hub.make_output_pin(number, inverted) yield hub.make_output_pin(number, inverted)
return return
raise EsphomeError(u"Unknown default mode {}".format(default_mode))
if CONF_MCP23017 in conf:
from esphome.components import mcp23017
for hub in CORE.get_variable(conf[CONF_MCP23017]):
yield None
if default_mode == u'INPUT':
mode = mcp23017.MCP23017_GPIO_MODES[conf.get(CONF_MODE, u'INPUT')]
yield hub.make_input_pin(number, mode, inverted)
return
if default_mode == u'OUTPUT':
yield hub.make_output_pin(number, inverted)
return
raise EsphomeError(u"Unknown default mode {}".format(default_mode)) raise EsphomeError(u"Unknown default mode {}".format(default_mode))
if len(conf) == 1: if len(conf) == 1:
yield IntLiteral(number) yield IntLiteral(number)

View File

@ -5,7 +5,7 @@ import logging
import voluptuous as vol import voluptuous as vol
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.const import CONF_INVERTED, CONF_MODE, CONF_NUMBER, CONF_PCF8574 from esphome.const import CONF_INVERTED, CONF_MODE, CONF_NUMBER, CONF_PCF8574, CONF_MCP23017
from esphome.core import CORE from esphome.core import CORE
from esphome.cpp_types import Component, esphome_ns, io_ns from esphome.cpp_types import Component, esphome_ns, io_ns
@ -358,6 +358,7 @@ def validate_has_interrupt(value):
I2CDevice = esphome_ns.class_('I2CDevice') I2CDevice = esphome_ns.class_('I2CDevice')
PCF8574Component = io_ns.class_('PCF8574Component', Component, I2CDevice) PCF8574Component = io_ns.class_('PCF8574Component', Component, I2CDevice)
MCP23017 = io_ns.class_('MCP23017', Component, I2CDevice)
PCF8574_OUTPUT_PIN_SCHEMA = cv.Schema({ PCF8574_OUTPUT_PIN_SCHEMA = cv.Schema({
vol.Required(CONF_PCF8574): cv.use_variable_id(PCF8574Component), vol.Required(CONF_PCF8574): cv.use_variable_id(PCF8574Component),
@ -370,6 +371,17 @@ PCF8574_INPUT_PIN_SCHEMA = PCF8574_OUTPUT_PIN_SCHEMA.extend({
vol.Optional(CONF_MODE): cv.one_of("INPUT", "INPUT_PULLUP", upper=True), vol.Optional(CONF_MODE): cv.one_of("INPUT", "INPUT_PULLUP", upper=True),
}) })
MCP23017_OUTPUT_PIN_SCHEMA = cv.Schema({
vol.Required(CONF_MCP23017): cv.use_variable_id(MCP23017),
vol.Required(CONF_NUMBER): vol.All(vol.Coerce(int), vol.Range(min=0, max=15)),
vol.Optional(CONF_MODE): cv.one_of("OUTPUT", upper=True),
vol.Optional(CONF_INVERTED, default=False): cv.boolean,
})
MCP23017_INPUT_PIN_SCHEMA = MCP23017_OUTPUT_PIN_SCHEMA.extend({
vol.Optional(CONF_MODE): cv.one_of("INPUT", "INPUT_PULLUP", upper=True),
})
def internal_gpio_output_pin_schema(value): def internal_gpio_output_pin_schema(value):
if isinstance(value, dict): if isinstance(value, dict):
@ -380,6 +392,8 @@ def internal_gpio_output_pin_schema(value):
def gpio_output_pin_schema(value): def gpio_output_pin_schema(value):
if isinstance(value, dict) and CONF_PCF8574 in value: if isinstance(value, dict) and CONF_PCF8574 in value:
return PCF8574_OUTPUT_PIN_SCHEMA(value) return PCF8574_OUTPUT_PIN_SCHEMA(value)
if isinstance(value, dict) and CONF_MCP23017 in value:
return MCP23017_OUTPUT_PIN_SCHEMA(value)
return internal_gpio_output_pin_schema(value) return internal_gpio_output_pin_schema(value)
@ -392,6 +406,8 @@ def internal_gpio_input_pin_schema(value):
def gpio_input_pin_schema(value): def gpio_input_pin_schema(value):
if isinstance(value, dict) and CONF_PCF8574 in value: if isinstance(value, dict) and CONF_PCF8574 in value:
return PCF8574_INPUT_PIN_SCHEMA(value) return PCF8574_INPUT_PIN_SCHEMA(value)
if isinstance(value, dict) and CONF_MCP23017 in value:
return MCP23017_INPUT_PIN_SCHEMA(value)
return internal_gpio_input_pin_schema(value) return internal_gpio_input_pin_schema(value)
@ -404,4 +420,6 @@ def internal_gpio_input_pullup_pin_schema(value):
def gpio_input_pullup_pin_schema(value): def gpio_input_pullup_pin_schema(value):
if isinstance(value, dict) and CONF_PCF8574 in value: if isinstance(value, dict) and CONF_PCF8574 in value:
return PCF8574_INPUT_PIN_SCHEMA(value) return PCF8574_INPUT_PIN_SCHEMA(value)
if isinstance(value, dict) and CONF_MCP23017 in value:
return MCP23017_INPUT_PIN_SCHEMA(value)
return internal_gpio_input_pin_schema(value) return internal_gpio_input_pin_schema(value)

View File

@ -613,6 +613,13 @@ binary_sensor:
number: 1 number: 1
mode: INPUT mode: INPUT
inverted: True inverted: True
- platform: gpio
name: "MCP binary sensor"
pin:
mcp23017: mcp23017_hub
number: 1
mode: INPUT
inverted: True
pca9685: pca9685:
frequency: 500 frequency: 500
@ -669,6 +676,13 @@ output:
number: 0 number: 0
mode: OUTPUT mode: OUTPUT
inverted: False inverted: False
- platform: gpio
id: id22
pin:
mcp23017: mcp23017_hub
number: 0
mode: OUTPUT
inverted: False
- platform: my9231 - platform: my9231
id: my_0 id: my_0
channel: 0 channel: 0
@ -1140,6 +1154,9 @@ pcf8574:
address: 0x21 address: 0x21
pcf8575: False pcf8575: False
mcp23017:
- id: 'mcp23017_hub'
stepper: stepper:
- platform: a4988 - platform: a4988
id: my_stepper id: my_stepper