diff --git a/.coveragerc b/.coveragerc index c1fe30c6f42..773bc9fb0f6 100644 --- a/.coveragerc +++ b/.coveragerc @@ -269,7 +269,9 @@ omit = homeassistant/components/firmata/board.py homeassistant/components/firmata/const.py homeassistant/components/firmata/entity.py + homeassistant/components/firmata/light.py homeassistant/components/firmata/pin.py + homeassistant/components/firmata/sensor.py homeassistant/components/firmata/switch.py homeassistant/components/fitbit/sensor.py homeassistant/components/fixer/sensor.py diff --git a/homeassistant/components/arduino/__init__.py b/homeassistant/components/arduino/__init__.py index e87a625522e..2890fd4abda 100644 --- a/homeassistant/components/arduino/__init__.py +++ b/homeassistant/components/arduino/__init__.py @@ -23,6 +23,12 @@ CONFIG_SCHEMA = vol.Schema( def setup(hass, config): """Set up the Arduino component.""" + _LOGGER.warning( + "The %s integration has been deprecated. Please move your " + "configuration to the firmata integration. " + "https://www.home-assistant.io/integrations/firmata", + DOMAIN, + ) port = config[DOMAIN][CONF_PORT] diff --git a/homeassistant/components/firmata/__init__.py b/homeassistant/components/firmata/__init__.py index b64a88cbf57..c0394a95a49 100644 --- a/homeassistant/components/firmata/__init__.py +++ b/homeassistant/components/firmata/__init__.py @@ -6,7 +6,17 @@ import logging import voluptuous as vol from homeassistant import config_entries -from homeassistant.const import CONF_NAME, EVENT_HOMEASSISTANT_STOP +from homeassistant.const import ( + CONF_BINARY_SENSORS, + CONF_LIGHTS, + CONF_MAXIMUM, + CONF_MINIMUM, + CONF_NAME, + CONF_PIN, + CONF_SENSORS, + CONF_SWITCHES, + EVENT_HOMEASSISTANT_STOP, +) from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv, device_registry as dr @@ -14,21 +24,22 @@ from .board import FirmataBoard from .const import ( CONF_ARDUINO_INSTANCE_ID, CONF_ARDUINO_WAIT, - CONF_BINARY_SENSORS, + CONF_DIFFERENTIAL, CONF_INITIAL_STATE, CONF_NEGATE_STATE, - CONF_PIN, CONF_PIN_MODE, + CONF_PLATFORM_MAP, CONF_SAMPLING_INTERVAL, CONF_SERIAL_BAUD_RATE, CONF_SERIAL_PORT, CONF_SLEEP_TUNE, - CONF_SWITCHES, DOMAIN, FIRMATA_MANUFACTURER, + PIN_MODE_ANALOG, PIN_MODE_INPUT, PIN_MODE_OUTPUT, PIN_MODE_PULLUP, + PIN_MODE_PWM, ) _LOGGER = logging.getLogger(__name__) @@ -40,8 +51,8 @@ ANALOG_PIN_SCHEMA = vol.All(cv.string, vol.Match(r"^A[0-9]+$")) SWITCH_SCHEMA = vol.Schema( { vol.Required(CONF_NAME): cv.string, + # Both digital and analog pins may be used as digital output vol.Required(CONF_PIN): vol.Any(cv.positive_int, ANALOG_PIN_SCHEMA), - # will be analog mode in future too vol.Required(CONF_PIN_MODE): PIN_MODE_OUTPUT, vol.Optional(CONF_INITIAL_STATE, default=False): cv.boolean, vol.Optional(CONF_NEGATE_STATE, default=False): cv.boolean, @@ -49,17 +60,45 @@ SWITCH_SCHEMA = vol.Schema( required=True, ) +LIGHT_SCHEMA = vol.Schema( + { + vol.Required(CONF_NAME): cv.string, + # Both digital and analog pins may be used as PWM/analog output + vol.Required(CONF_PIN): vol.Any(cv.positive_int, ANALOG_PIN_SCHEMA), + vol.Required(CONF_PIN_MODE): PIN_MODE_PWM, + vol.Optional(CONF_INITIAL_STATE, default=0): cv.positive_int, + vol.Optional(CONF_MINIMUM, default=0): cv.positive_int, + vol.Optional(CONF_MAXIMUM, default=255): cv.positive_int, + }, + required=True, +) + BINARY_SENSOR_SCHEMA = vol.Schema( { vol.Required(CONF_NAME): cv.string, + # Both digital and analog pins may be used as digital input vol.Required(CONF_PIN): vol.Any(cv.positive_int, ANALOG_PIN_SCHEMA), - # will be analog mode in future too vol.Required(CONF_PIN_MODE): vol.Any(PIN_MODE_INPUT, PIN_MODE_PULLUP), vol.Optional(CONF_NEGATE_STATE, default=False): cv.boolean, }, required=True, ) +SENSOR_SCHEMA = vol.Schema( + { + vol.Required(CONF_NAME): cv.string, + # Currently only analog input sensor is implemented + vol.Required(CONF_PIN): ANALOG_PIN_SCHEMA, + vol.Required(CONF_PIN_MODE): PIN_MODE_ANALOG, + # Default differential is 40 to avoid a flood of messages on initial setup + # in case pin is unplugged. Firmata responds really really fast + vol.Optional(CONF_DIFFERENTIAL, default=40): vol.All( + cv.positive_int, vol.Range(min=1) + ), + }, + required=True, +) + BOARD_CONFIG_SCHEMA = vol.Schema( { vol.Required(CONF_SERIAL_PORT): cv.string, @@ -71,7 +110,9 @@ BOARD_CONFIG_SCHEMA = vol.Schema( ), vol.Optional(CONF_SAMPLING_INTERVAL): cv.positive_int, vol.Optional(CONF_SWITCHES): [SWITCH_SCHEMA], + vol.Optional(CONF_LIGHTS): [LIGHT_SCHEMA], vol.Optional(CONF_BINARY_SENSORS): [BINARY_SENSOR_SCHEMA], + vol.Optional(CONF_SENSORS): [SENSOR_SCHEMA], }, required=True, ) @@ -155,14 +196,11 @@ async def async_setup_entry( sw_version=board.firmware_version, ) - if CONF_BINARY_SENSORS in config_entry.data: - hass.async_create_task( - hass.config_entries.async_forward_entry_setup(config_entry, "binary_sensor") - ) - if CONF_SWITCHES in config_entry.data: - hass.async_create_task( - hass.config_entries.async_forward_entry_setup(config_entry, "switch") - ) + for (conf, platform) in CONF_PLATFORM_MAP.items(): + if conf in config_entry.data: + hass.async_create_task( + hass.config_entries.async_forward_entry_setup(config_entry, platform) + ) return True @@ -173,16 +211,11 @@ async def async_unload_entry( _LOGGER.debug("Closing Firmata board %s", config_entry.data[CONF_NAME]) unload_entries = [] - if CONF_BINARY_SENSORS in config_entry.data: - unload_entries.append( - hass.config_entries.async_forward_entry_unload( - config_entry, "binary_sensor" + for (conf, platform) in CONF_PLATFORM_MAP.items(): + if conf in config_entry.data: + unload_entries.append( + hass.config_entries.async_forward_entry_unload(config_entry, platform) ) - ) - if CONF_SWITCHES in config_entry.data: - unload_entries.append( - hass.config_entries.async_forward_entry_unload(config_entry, "switch") - ) results = [] if unload_entries: results = await asyncio.gather(*unload_entries) diff --git a/homeassistant/components/firmata/binary_sensor.py b/homeassistant/components/firmata/binary_sensor.py index 4576b8dc69e..c2708fc2753 100644 --- a/homeassistant/components/firmata/binary_sensor.py +++ b/homeassistant/components/firmata/binary_sensor.py @@ -4,10 +4,10 @@ import logging from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_NAME +from homeassistant.const import CONF_NAME, CONF_PIN from homeassistant.core import HomeAssistant -from .const import CONF_NEGATE_STATE, CONF_PIN, CONF_PIN_MODE, DOMAIN +from .const import CONF_NEGATE_STATE, CONF_PIN_MODE, DOMAIN from .entity import FirmataPinEntity from .pin import FirmataBinaryDigitalInput, FirmataPinUsedException @@ -30,7 +30,7 @@ async def async_setup_entry( api.setup() except FirmataPinUsedException: _LOGGER.error( - "Could not setup binary sensor on pin %s since pin already in use.", + "Could not setup binary sensor on pin %s since pin already in use", binary_sensor[CONF_PIN], ) continue diff --git a/homeassistant/components/firmata/board.py b/homeassistant/components/firmata/board.py index bae30014d63..73e3c004cb9 100644 --- a/homeassistant/components/firmata/board.py +++ b/homeassistant/components/firmata/board.py @@ -5,17 +5,23 @@ from typing import Union from pymata_express.pymata_express import PymataExpress from pymata_express.pymata_express_serial import serial -from homeassistant.const import CONF_NAME +from homeassistant.const import ( + CONF_BINARY_SENSORS, + CONF_LIGHTS, + CONF_NAME, + CONF_SENSORS, + CONF_SWITCHES, +) from .const import ( CONF_ARDUINO_INSTANCE_ID, CONF_ARDUINO_WAIT, - CONF_BINARY_SENSORS, CONF_SAMPLING_INTERVAL, CONF_SERIAL_BAUD_RATE, CONF_SERIAL_PORT, CONF_SLEEP_TUNE, - CONF_SWITCHES, + PIN_TYPE_ANALOG, + PIN_TYPE_DIGITAL, ) _LOGGER = logging.getLogger(__name__) @@ -34,13 +40,19 @@ class FirmataBoard: self.protocol_version = None self.name = self.config[CONF_NAME] self.switches = [] + self.lights = [] self.binary_sensors = [] + self.sensors = [] self.used_pins = [] if CONF_SWITCHES in self.config: self.switches = self.config[CONF_SWITCHES] + if CONF_LIGHTS in self.config: + self.lights = self.config[CONF_LIGHTS] if CONF_BINARY_SENSORS in self.config: self.binary_sensors = self.config[CONF_BINARY_SENSORS] + if CONF_SENSORS in self.config: + self.sensors = self.config[CONF_SENSORS] async def async_setup(self, tries=0) -> bool: """Set up a Firmata instance.""" @@ -109,11 +121,11 @@ board %s: %s", def get_pin_type(self, pin: FirmataPinType) -> tuple: """Return the type and Firmata location of a pin on the board.""" if isinstance(pin, str): - pin_type = "analog" + pin_type = PIN_TYPE_ANALOG firmata_pin = int(pin[1:]) firmata_pin += self.api.first_analog_pin else: - pin_type = "digital" + pin_type = PIN_TYPE_DIGITAL firmata_pin = pin return (pin_type, firmata_pin) diff --git a/homeassistant/components/firmata/const.py b/homeassistant/components/firmata/const.py index 1ad3cbb8423..6259582b5f7 100644 --- a/homeassistant/components/firmata/const.py +++ b/homeassistant/components/firmata/const.py @@ -1,24 +1,35 @@ """Constants for the Firmata component.""" -import logging - -LOGGER = logging.getLogger(__package__) +from homeassistant.const import ( + CONF_BINARY_SENSORS, + CONF_LIGHTS, + CONF_SENSORS, + CONF_SWITCHES, +) CONF_ARDUINO_INSTANCE_ID = "arduino_instance_id" CONF_ARDUINO_WAIT = "arduino_wait" -CONF_BINARY_SENSORS = "binary_sensors" +CONF_DIFFERENTIAL = "differential" CONF_INITIAL_STATE = "initial" CONF_NAME = "name" CONF_NEGATE_STATE = "negate" -CONF_PIN = "pin" CONF_PINS = "pins" CONF_PIN_MODE = "pin_mode" +PIN_MODE_ANALOG = "ANALOG" PIN_MODE_OUTPUT = "OUTPUT" +PIN_MODE_PWM = "PWM" PIN_MODE_INPUT = "INPUT" PIN_MODE_PULLUP = "PULLUP" +PIN_TYPE_ANALOG = 1 +PIN_TYPE_DIGITAL = 0 CONF_SAMPLING_INTERVAL = "sampling_interval" CONF_SERIAL_BAUD_RATE = "serial_baud_rate" CONF_SERIAL_PORT = "serial_port" CONF_SLEEP_TUNE = "sleep_tune" -CONF_SWITCHES = "switches" DOMAIN = "firmata" FIRMATA_MANUFACTURER = "Firmata" +CONF_PLATFORM_MAP = { + CONF_BINARY_SENSORS: "binary_sensor", + CONF_LIGHTS: "light", + CONF_SENSORS: "sensor", + CONF_SWITCHES: "switch", +} diff --git a/homeassistant/components/firmata/light.py b/homeassistant/components/firmata/light.py new file mode 100644 index 00000000000..e95b5101413 --- /dev/null +++ b/homeassistant/components/firmata/light.py @@ -0,0 +1,98 @@ +"""Support for Firmata light output.""" + +import logging +from typing import Type + +from homeassistant.components.light import ( + ATTR_BRIGHTNESS, + SUPPORT_BRIGHTNESS, + LightEntity, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_MAXIMUM, CONF_MINIMUM, CONF_NAME, CONF_PIN +from homeassistant.core import HomeAssistant + +from .board import FirmataPinType +from .const import CONF_INITIAL_STATE, CONF_PIN_MODE, DOMAIN +from .entity import FirmataPinEntity +from .pin import FirmataBoardPin, FirmataPinUsedException, FirmataPWMOutput + +_LOGGER = logging.getLogger(__name__) + + +async def async_setup_entry( + hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities +) -> None: + """Set up the Firmata lights.""" + new_entities = [] + + board = hass.data[DOMAIN][config_entry.entry_id] + for light in board.lights: + pin = light[CONF_PIN] + pin_mode = light[CONF_PIN_MODE] + initial = light[CONF_INITIAL_STATE] + minimum = light[CONF_MINIMUM] + maximum = light[CONF_MAXIMUM] + api = FirmataPWMOutput(board, pin, pin_mode, initial, minimum, maximum) + try: + api.setup() + except FirmataPinUsedException: + _LOGGER.error( + "Could not setup light on pin %s since pin already in use", + light[CONF_PIN], + ) + continue + name = light[CONF_NAME] + light_entity = FirmataLight(api, config_entry, name, pin) + new_entities.append(light_entity) + + if new_entities: + async_add_entities(new_entities) + + +class FirmataLight(FirmataPinEntity, LightEntity): + """Representation of a light on a Firmata board.""" + + def __init__( + self, + api: Type[FirmataBoardPin], + config_entry: ConfigEntry, + name: str, + pin: FirmataPinType, + ): + """Initialize the light pin entity.""" + super().__init__(api, config_entry, name, pin) + + # Default first turn on to max + self._last_on_level = 255 + + async def async_added_to_hass(self) -> None: + """Set up a light.""" + await self._api.start_pin() + + @property + def is_on(self) -> bool: + """Return true if light is on.""" + return self._api.state > 0 + + @property + def brightness(self) -> int: + """Return the brightness of the light.""" + return self._api.state + + @property + def supported_features(self) -> int: + """Flag supported features.""" + return SUPPORT_BRIGHTNESS + + async def async_turn_on(self, **kwargs) -> None: + """Turn on light.""" + level = kwargs.get(ATTR_BRIGHTNESS, self._last_on_level) + await self._api.set_level(level) + self.async_write_ha_state() + self._last_on_level = level + + async def async_turn_off(self, **kwargs) -> None: + """Turn off light.""" + await self._api.set_level(0) + self.async_write_ha_state() diff --git a/homeassistant/components/firmata/manifest.json b/homeassistant/components/firmata/manifest.json index d894c0a440b..8b283c4f81d 100644 --- a/homeassistant/components/firmata/manifest.json +++ b/homeassistant/components/firmata/manifest.json @@ -4,7 +4,7 @@ "config_flow": false, "documentation": "https://www.home-assistant.io/integrations/firmata", "requirements": [ - "pymata-express==1.13" + "pymata-express==1.19" ], "codeowners": [ "@DaAwesomeP" diff --git a/homeassistant/components/firmata/pin.py b/homeassistant/components/firmata/pin.py index 644986fb66c..3259d76cbb3 100644 --- a/homeassistant/components/firmata/pin.py +++ b/homeassistant/components/firmata/pin.py @@ -2,10 +2,8 @@ import logging from typing import Callable -from homeassistant.core import callback - from .board import FirmataBoard, FirmataPinType -from .const import PIN_MODE_INPUT, PIN_MODE_PULLUP +from .const import PIN_MODE_INPUT, PIN_MODE_PULLUP, PIN_TYPE_ANALOG _LOGGER = logging.getLogger(__name__) @@ -25,6 +23,10 @@ class FirmataBoardPin: self._pin_type, self._firmata_pin = self.board.get_pin_type(self._pin) self._state = None + if self._pin_type == PIN_TYPE_ANALOG: + # Pymata wants the analog pin formatted as the # from "A#" + self._analog_pin = int(self._pin[1:]) + def setup(self): """Set up a pin and make sure it is valid.""" if not self.board.mark_pin_used(self._pin): @@ -85,6 +87,53 @@ class FirmataBinaryDigitalOutput(FirmataBoardPin): self._state = False +class FirmataPWMOutput(FirmataBoardPin): + """Representation of a Firmata PWM/analog Output Pin.""" + + def __init__( + self, + board: FirmataBoard, + pin: FirmataPinType, + pin_mode: str, + initial: bool, + minimum: int, + maximum: int, + ): + """Initialize the PWM/analog output pin.""" + self._initial = initial + self._min = minimum + self._max = maximum + self._range = self._max - self._min + super().__init__(board, pin, pin_mode) + + async def start_pin(self) -> None: + """Set initial state on a pin.""" + _LOGGER.debug( + "Setting initial state for PWM/analog output pin %s on board %s to %d", + self._pin, + self.board.name, + self._initial, + ) + api = self.board.api + await api.set_pin_mode_pwm_output(self._firmata_pin) + + new_pin_state = round((self._initial * self._range) / 255) + self._min + await api.pwm_write(self._firmata_pin, new_pin_state) + self._state = self._initial + + @property + def state(self) -> int: + """Return PWM/analog state.""" + return self._state + + async def set_level(self, level: int) -> None: + """Set PWM/analog output.""" + _LOGGER.debug("Setting PWM/analog output on pin %s to %d", self._pin, level) + new_pin_state = round((level * self._range) / 255) + self._min + await self.board.api.pwm_write(self._firmata_pin, new_pin_state) + self._state = level + + class FirmataBinaryDigitalInput(FirmataBoardPin): """Representation of a Firmata Digital Input Pin.""" @@ -99,7 +148,7 @@ class FirmataBinaryDigitalInput(FirmataBoardPin): async def start_pin(self, forward_callback: Callable[[], None]) -> None: """Get initial state and start reporting a pin.""" _LOGGER.debug( - "Starting reporting updates for input pin %s on board %s", + "Starting reporting updates for digital input pin %s on board %s", self._pin, self.board.name, ) @@ -133,7 +182,6 @@ class FirmataBinaryDigitalInput(FirmataBoardPin): """Return true if digital input is on.""" return self._state - @callback async def latch_callback(self, data: list) -> None: """Update pin state on callback.""" if data[1] != self._firmata_pin: @@ -151,3 +199,65 @@ class FirmataBinaryDigitalInput(FirmataBoardPin): return self._state = new_state self._forward_callback() + + +class FirmataAnalogInput(FirmataBoardPin): + """Representation of a Firmata Analog Input Pin.""" + + def __init__( + self, board: FirmataBoard, pin: FirmataPinType, pin_mode: str, differential: int + ): + """Initialize the analog input pin.""" + self._differential = differential + self._forward_callback = None + super().__init__(board, pin, pin_mode) + + async def start_pin(self, forward_callback: Callable[[], None]) -> None: + """Get initial state and start reporting a pin.""" + _LOGGER.debug( + "Starting reporting updates for analog input pin %s on board %s", + self._pin, + self.board.name, + ) + self._forward_callback = forward_callback + api = self.board.api + # Only PIN_MODE_ANALOG_INPUT mode is supported as sensor input + await api.set_pin_mode_analog_input( + self._analog_pin, self.latch_callback, self._differential + ) + + self._state = (await self.board.api.analog_read(self._analog_pin))[0] + + self._forward_callback() + + async def stop_pin(self) -> None: + """Stop reporting analog input pin.""" + _LOGGER.debug( + "Stopping reporting updates for analog input pin %s on board %s", + self._pin, + self.board.name, + ) + api = self.board.api + await api.disable_analog_reporting(self._analog_pin) + + @property + def state(self) -> int: + """Return sensor state.""" + return self._state + + async def latch_callback(self, data: list) -> None: + """Update pin state on callback.""" + if data[1] != self._analog_pin: + return + _LOGGER.debug( + "Received latch %d for analog input pin %s on board %s", + data[2], + self._pin, + self.board.name, + ) + new_state = data[2] + if self._state == new_state: + _LOGGER.debug("stopping") + return + self._state = new_state + self._forward_callback() diff --git a/homeassistant/components/firmata/sensor.py b/homeassistant/components/firmata/sensor.py new file mode 100644 index 00000000000..cb9db1f11e5 --- /dev/null +++ b/homeassistant/components/firmata/sensor.py @@ -0,0 +1,59 @@ +"""Support for Firmata sensor input.""" + +import logging + +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_NAME, CONF_PIN +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity import Entity + +from .const import CONF_DIFFERENTIAL, CONF_PIN_MODE, DOMAIN +from .entity import FirmataPinEntity +from .pin import FirmataAnalogInput, FirmataPinUsedException + +_LOGGER = logging.getLogger(__name__) + + +async def async_setup_entry( + hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities +) -> None: + """Set up the Firmata sensors.""" + new_entities = [] + + board = hass.data[DOMAIN][config_entry.entry_id] + for sensor in board.sensors: + pin = sensor[CONF_PIN] + pin_mode = sensor[CONF_PIN_MODE] + differential = sensor[CONF_DIFFERENTIAL] + api = FirmataAnalogInput(board, pin, pin_mode, differential) + try: + api.setup() + except FirmataPinUsedException: + _LOGGER.error( + "Could not setup sensor on pin %s since pin already in use", + sensor[CONF_PIN], + ) + continue + name = sensor[CONF_NAME] + sensor_entity = FirmataSensor(api, config_entry, name, pin) + new_entities.append(sensor_entity) + + if new_entities: + async_add_entities(new_entities) + + +class FirmataSensor(FirmataPinEntity, Entity): + """Representation of a sensor on a Firmata board.""" + + async def async_added_to_hass(self) -> None: + """Set up a sensor.""" + await self._api.start_pin(self.async_write_ha_state) + + async def async_will_remove_from_hass(self) -> None: + """Stop reporting a sensor.""" + await self._api.stop_pin() + + @property + def state(self) -> int: + """Return sensor state.""" + return self._api.state diff --git a/homeassistant/components/firmata/switch.py b/homeassistant/components/firmata/switch.py index ab67a6d6840..f1aaf3357c0 100644 --- a/homeassistant/components/firmata/switch.py +++ b/homeassistant/components/firmata/switch.py @@ -4,16 +4,10 @@ import logging from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_NAME +from homeassistant.const import CONF_NAME, CONF_PIN from homeassistant.core import HomeAssistant -from .const import ( - CONF_INITIAL_STATE, - CONF_NEGATE_STATE, - CONF_PIN, - CONF_PIN_MODE, - DOMAIN, -) +from .const import CONF_INITIAL_STATE, CONF_NEGATE_STATE, CONF_PIN_MODE, DOMAIN from .entity import FirmataPinEntity from .pin import FirmataBinaryDigitalOutput, FirmataPinUsedException @@ -37,7 +31,7 @@ async def async_setup_entry( api.setup() except FirmataPinUsedException: _LOGGER.error( - "Could not setup switch on pin %s since pin already in use.", + "Could not setup switch on pin %s since pin already in use", switch[CONF_PIN], ) continue @@ -55,7 +49,6 @@ class FirmataSwitch(FirmataPinEntity, SwitchEntity): async def async_added_to_hass(self) -> None: """Set up a switch.""" await self._api.start_pin() - self.async_write_ha_state() @property def is_on(self) -> bool: @@ -64,12 +57,10 @@ class FirmataSwitch(FirmataPinEntity, SwitchEntity): async def async_turn_on(self, **kwargs) -> None: """Turn on switch.""" - _LOGGER.debug("Turning switch %s on", self._name) await self._api.turn_on() self.async_write_ha_state() async def async_turn_off(self, **kwargs) -> None: """Turn off switch.""" - _LOGGER.debug("Turning switch %s off", self._name) await self._api.turn_off() self.async_write_ha_state() diff --git a/requirements_all.txt b/requirements_all.txt index ba2c86a00eb..c630670b08a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1470,7 +1470,7 @@ pylutron==0.2.5 pymailgunner==1.4 # homeassistant.components.firmata -pymata-express==1.13 +pymata-express==1.19 # homeassistant.components.mediaroom pymediaroom==0.6.4.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 8b8e96dc2b0..4ba319cd732 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -713,7 +713,7 @@ pylutron-caseta==0.6.1 pymailgunner==1.4 # homeassistant.components.firmata -pymata-express==1.13 +pymata-express==1.19 # homeassistant.components.melcloud pymelcloud==2.5.2