""" Configure a switch using a digital output from a raspihats board. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/switch.raspihats/ """ import logging import voluptuous as vol from homeassistant.const import ( CONF_NAME, DEVICE_DEFAULT_NAME ) import homeassistant.helpers.config_validation as cv from homeassistant.components.switch import PLATFORM_SCHEMA from homeassistant.helpers.entity import ToggleEntity from homeassistant.components.raspihats import ( CONF_I2C_HATS, CONF_BOARD, CONF_ADDRESS, CONF_CHANNELS, CONF_INDEX, CONF_INVERT_LOGIC, CONF_INITIAL_STATE, I2C_HAT_NAMES, I2C_HATS_MANAGER, I2CHatsException ) _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ['raspihats'] _CHANNELS_SCHEMA = vol.Schema([{ vol.Required(CONF_INDEX): cv.positive_int, vol.Required(CONF_NAME): cv.string, vol.Optional(CONF_INVERT_LOGIC, default=False): cv.boolean, vol.Optional(CONF_INITIAL_STATE, default=None): cv.boolean, }]) _I2C_HATS_SCHEMA = vol.Schema([{ vol.Required(CONF_BOARD): vol.In(I2C_HAT_NAMES), vol.Required(CONF_ADDRESS): vol.Coerce(int), vol.Required(CONF_CHANNELS): _CHANNELS_SCHEMA }]) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_I2C_HATS): _I2C_HATS_SCHEMA, }) # pylint: disable=unused-argument def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the raspihats switch devices.""" I2CHatSwitch.I2C_HATS_MANAGER = hass.data[I2C_HATS_MANAGER] switches = [] i2c_hat_configs = config.get(CONF_I2C_HATS) for i2c_hat_config in i2c_hat_configs: board = i2c_hat_config[CONF_BOARD] address = i2c_hat_config[CONF_ADDRESS] try: I2CHatSwitch.I2C_HATS_MANAGER.register_board(board, address) for channel_config in i2c_hat_config[CONF_CHANNELS]: switches.append( I2CHatSwitch( board, address, channel_config[CONF_INDEX], channel_config[CONF_NAME], channel_config[CONF_INVERT_LOGIC], channel_config[CONF_INITIAL_STATE] ) ) except I2CHatsException as ex: _LOGGER.error( "Failed to register " + board + "I2CHat@" + hex(address) + " " + str(ex) ) add_devices(switches) class I2CHatSwitch(ToggleEntity): """Represents a switch that uses a I2C-HAT digital output.""" I2C_HATS_MANAGER = None def __init__( self, board, address, channel, name, invert_logic, initial_state): """Initialize switch.""" self._board = board self._address = address self._channel = channel self._name = name or DEVICE_DEFAULT_NAME self._invert_logic = invert_logic if initial_state is not None: if self._invert_logic: state = not initial_state else: state = initial_state self.I2C_HATS_MANAGER.write_dq( self._address, self._channel, state ) def online_callback(): """Callback fired when board is online.""" self.schedule_update_ha_state() self.I2C_HATS_MANAGER.register_online_callback( self._address, self._channel, online_callback ) def _log_message(self, message): string = self._name + " " string += self._board + "I2CHat@" + hex(self._address) + " " string += "channel:" + str(self._channel) + message return string @property def name(self): """Return the name of the switch.""" return self._name @property def should_poll(self): """Polling not needed.""" return False @property def is_on(self): """Return true if device is on.""" try: state = self.I2C_HATS_MANAGER.read_dq( self._address, self._channel ) return state != self._invert_logic except I2CHatsException as ex: _LOGGER.error( self._log_message("Is ON check failed, " + str(ex)) ) return False def turn_on(self): """Turn the device on.""" try: state = True if self._invert_logic is False else False self.I2C_HATS_MANAGER.write_dq( self._address, self._channel, state ) self.schedule_update_ha_state() except I2CHatsException as ex: _LOGGER.error( self._log_message("Turn ON failed, " + str(ex)) ) def turn_off(self): """Turn the device off.""" try: state = False if self._invert_logic is False else True self.I2C_HATS_MANAGER.write_dq( self._address, self._channel, state ) self.schedule_update_ha_state() except I2CHatsException as ex: _LOGGER.error( self._log_message("Turn OFF failed, " + str(ex)) )