mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
commit
7f0c334391
@ -7,6 +7,9 @@ omit =
|
|||||||
homeassistant/external/*
|
homeassistant/external/*
|
||||||
|
|
||||||
# omit pieces of code that rely on external devices being present
|
# omit pieces of code that rely on external devices being present
|
||||||
|
homeassistant/components/arduino.py
|
||||||
|
homeassistant/components/*/arduino.py
|
||||||
|
|
||||||
homeassistant/components/wink.py
|
homeassistant/components/wink.py
|
||||||
homeassistant/components/*/wink.py
|
homeassistant/components/*/wink.py
|
||||||
|
|
||||||
|
134
homeassistant/components/arduino.py
Normal file
134
homeassistant/components/arduino.py
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
"""
|
||||||
|
components.arduino
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
Arduino component that connects to a directly attached Arduino board which
|
||||||
|
runs with the Firmata firmware.
|
||||||
|
|
||||||
|
Configuration:
|
||||||
|
|
||||||
|
To use the Arduino board you will need to add something like the following
|
||||||
|
to your config/configuration.yaml
|
||||||
|
|
||||||
|
arduino:
|
||||||
|
port: /dev/ttyACM0
|
||||||
|
|
||||||
|
Variables:
|
||||||
|
|
||||||
|
port
|
||||||
|
*Required
|
||||||
|
The port where is your board connected to your Home Assistant system.
|
||||||
|
If you are using an original Arduino the port will be named ttyACM*. The exact
|
||||||
|
number can be determined with 'ls /dev/ttyACM*' or check your 'dmesg'/
|
||||||
|
'journalctl -f' output. Keep in mind that Arduino clones are often using a
|
||||||
|
different name for the port (e.g. '/dev/ttyUSB*').
|
||||||
|
|
||||||
|
A word of caution: The Arduino is not storing states. This means that with
|
||||||
|
every initialization the pins are set to off/low.
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from PyMata.pymata import PyMata
|
||||||
|
import serial
|
||||||
|
|
||||||
|
from homeassistant.helpers import validate_config
|
||||||
|
from homeassistant.const import (EVENT_HOMEASSISTANT_START,
|
||||||
|
EVENT_HOMEASSISTANT_STOP)
|
||||||
|
|
||||||
|
DOMAIN = "arduino"
|
||||||
|
DEPENDENCIES = []
|
||||||
|
BOARD = None
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def setup(hass, config):
|
||||||
|
""" Setup the Arduino component. """
|
||||||
|
|
||||||
|
if not validate_config(config,
|
||||||
|
{DOMAIN: ['port']},
|
||||||
|
_LOGGER):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# pylint: disable=global-statement
|
||||||
|
global BOARD
|
||||||
|
try:
|
||||||
|
BOARD = ArduinoBoard(config[DOMAIN]['port'])
|
||||||
|
except (serial.serialutil.SerialException, FileNotFoundError):
|
||||||
|
_LOGGER.exception("Your port is not accessible.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if BOARD.get_firmata()[1] <= 2:
|
||||||
|
_LOGGER.error("The StandardFirmata sketch should be 2.2 or newer.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def stop_arduino(event):
|
||||||
|
""" Stop the Arduino service. """
|
||||||
|
BOARD.disconnect()
|
||||||
|
|
||||||
|
def start_arduino(event):
|
||||||
|
""" Start the Arduino service. """
|
||||||
|
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_arduino)
|
||||||
|
|
||||||
|
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_arduino)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class ArduinoBoard(object):
|
||||||
|
""" Represents an Arduino board. """
|
||||||
|
|
||||||
|
def __init__(self, port):
|
||||||
|
self._port = port
|
||||||
|
self._board = PyMata(self._port, verbose=False)
|
||||||
|
|
||||||
|
def set_mode(self, pin, direction, mode):
|
||||||
|
""" Sets the mode and the direction of a given pin. """
|
||||||
|
if mode == 'analog' and direction == 'in':
|
||||||
|
self._board.set_pin_mode(pin,
|
||||||
|
self._board.INPUT,
|
||||||
|
self._board.ANALOG)
|
||||||
|
elif mode == 'analog' and direction == 'out':
|
||||||
|
self._board.set_pin_mode(pin,
|
||||||
|
self._board.OUTPUT,
|
||||||
|
self._board.ANALOG)
|
||||||
|
elif mode == 'digital' and direction == 'in':
|
||||||
|
self._board.set_pin_mode(pin,
|
||||||
|
self._board.OUTPUT,
|
||||||
|
self._board.DIGITAL)
|
||||||
|
elif mode == 'digital' and direction == 'out':
|
||||||
|
self._board.set_pin_mode(pin,
|
||||||
|
self._board.OUTPUT,
|
||||||
|
self._board.DIGITAL)
|
||||||
|
elif mode == 'pwm':
|
||||||
|
self._board.set_pin_mode(pin,
|
||||||
|
self._board.OUTPUT,
|
||||||
|
self._board.PWM)
|
||||||
|
|
||||||
|
def get_analog_inputs(self):
|
||||||
|
""" Get the values from the pins. """
|
||||||
|
self._board.capability_query()
|
||||||
|
return self._board.get_analog_response_table()
|
||||||
|
|
||||||
|
def set_digital_out_high(self, pin):
|
||||||
|
""" Sets a given digital pin to high. """
|
||||||
|
self._board.digital_write(pin, 1)
|
||||||
|
|
||||||
|
def set_digital_out_low(self, pin):
|
||||||
|
""" Sets a given digital pin to low. """
|
||||||
|
self._board.digital_write(pin, 0)
|
||||||
|
|
||||||
|
def get_digital_in(self, pin):
|
||||||
|
""" Gets the value from a given digital pin. """
|
||||||
|
self._board.digital_read(pin)
|
||||||
|
|
||||||
|
def get_analog_in(self, pin):
|
||||||
|
""" Gets the value from a given analog pin. """
|
||||||
|
self._board.analog_read(pin)
|
||||||
|
|
||||||
|
def get_firmata(self):
|
||||||
|
""" Return the version of the Firmata firmware. """
|
||||||
|
return self._board.get_firmata_version()
|
||||||
|
|
||||||
|
def disconnect(self):
|
||||||
|
""" Disconnects the board and closes the serial connection. """
|
||||||
|
self._board.reset()
|
||||||
|
self._board.close()
|
87
homeassistant/components/sensor/arduino.py
Normal file
87
homeassistant/components/sensor/arduino.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
"""
|
||||||
|
homeassistant.components.sensor.arduino
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Support for getting information from Arduino pins. Only analog pins are
|
||||||
|
supported.
|
||||||
|
|
||||||
|
Configuration:
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
platform: arduino
|
||||||
|
pins:
|
||||||
|
7:
|
||||||
|
name: Door switch
|
||||||
|
type: analog
|
||||||
|
0:
|
||||||
|
name: Brightness
|
||||||
|
type: analog
|
||||||
|
|
||||||
|
Variables:
|
||||||
|
|
||||||
|
pins
|
||||||
|
*Required
|
||||||
|
An array specifying the digital pins to use on the Arduino board.
|
||||||
|
|
||||||
|
These are the variables for the pins array:
|
||||||
|
|
||||||
|
name
|
||||||
|
*Required
|
||||||
|
The name for the pin that will be used in the frontend.
|
||||||
|
|
||||||
|
type
|
||||||
|
*Required
|
||||||
|
The type of the pin: 'analog'.
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import homeassistant.components.arduino as arduino
|
||||||
|
from homeassistant.helpers.entity import Entity
|
||||||
|
from homeassistant.const import DEVICE_DEFAULT_NAME
|
||||||
|
|
||||||
|
DEPENDENCIES = ['arduino']
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
|
""" Sets up the Arduino platform. """
|
||||||
|
|
||||||
|
# Verify that Arduino board is present
|
||||||
|
if arduino.BOARD is None:
|
||||||
|
_LOGGER.error('A connection has not been made to the Arduino board.')
|
||||||
|
return False
|
||||||
|
|
||||||
|
sensors = []
|
||||||
|
pins = config.get('pins')
|
||||||
|
for pinnum, pin in pins.items():
|
||||||
|
if pin.get('name'):
|
||||||
|
sensors.append(ArduinoSensor(pin.get('name'),
|
||||||
|
pinnum,
|
||||||
|
'analog'))
|
||||||
|
add_devices(sensors)
|
||||||
|
|
||||||
|
|
||||||
|
class ArduinoSensor(Entity):
|
||||||
|
""" Represents an Arduino Sensor. """
|
||||||
|
def __init__(self, name, pin, pin_type):
|
||||||
|
self._pin = pin
|
||||||
|
self._name = name or DEVICE_DEFAULT_NAME
|
||||||
|
self.pin_type = pin_type
|
||||||
|
self.direction = 'in'
|
||||||
|
self._value = None
|
||||||
|
|
||||||
|
arduino.BOARD.set_mode(self._pin, self.direction, self.pin_type)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self):
|
||||||
|
""" Returns the state of the sensor. """
|
||||||
|
return self._value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
""" Get the name of the sensor. """
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
""" Get the latest value from the pin. """
|
||||||
|
self._value = arduino.BOARD.get_analog_inputs()[self._pin][1]
|
93
homeassistant/components/switch/arduino.py
Normal file
93
homeassistant/components/switch/arduino.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
"""
|
||||||
|
homeassistant.components.switch.arduino
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Support for switching Arduino pins on and off. So fare only digital pins are
|
||||||
|
supported.
|
||||||
|
|
||||||
|
Configuration:
|
||||||
|
|
||||||
|
switch:
|
||||||
|
platform: arduino
|
||||||
|
pins:
|
||||||
|
11:
|
||||||
|
name: Fan Office
|
||||||
|
type: digital
|
||||||
|
12:
|
||||||
|
name: Light Desk
|
||||||
|
type: digital
|
||||||
|
|
||||||
|
Variables:
|
||||||
|
|
||||||
|
pins
|
||||||
|
*Required
|
||||||
|
An array specifying the digital pins to use on the Arduino board.
|
||||||
|
|
||||||
|
These are the variables for the pins array:
|
||||||
|
|
||||||
|
name
|
||||||
|
*Required
|
||||||
|
The name for the pin that will be used in the frontend.
|
||||||
|
|
||||||
|
type
|
||||||
|
*Required
|
||||||
|
The type of the pin: 'digital'.
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import homeassistant.components.arduino as arduino
|
||||||
|
from homeassistant.components.switch import SwitchDevice
|
||||||
|
from homeassistant.const import DEVICE_DEFAULT_NAME
|
||||||
|
|
||||||
|
DEPENDENCIES = ['arduino']
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
|
""" Sets up the Arduino platform. """
|
||||||
|
|
||||||
|
# Verify that Arduino board is present
|
||||||
|
if arduino.BOARD is None:
|
||||||
|
_LOGGER.error('A connection has not been made to the Arduino board.')
|
||||||
|
return False
|
||||||
|
|
||||||
|
switches = []
|
||||||
|
pins = config.get('pins')
|
||||||
|
for pinnum, pin in pins.items():
|
||||||
|
if pin.get('name'):
|
||||||
|
switches.append(ArduinoSwitch(pin.get('name'),
|
||||||
|
pinnum,
|
||||||
|
pin.get('type')))
|
||||||
|
add_devices(switches)
|
||||||
|
|
||||||
|
|
||||||
|
class ArduinoSwitch(SwitchDevice):
|
||||||
|
""" Represents an Arduino Switch. """
|
||||||
|
def __init__(self, name, pin, pin_type):
|
||||||
|
self._pin = pin
|
||||||
|
self._name = name or DEVICE_DEFAULT_NAME
|
||||||
|
self.pin_type = pin_type
|
||||||
|
self.direction = 'out'
|
||||||
|
self._state = False
|
||||||
|
|
||||||
|
arduino.BOARD.set_mode(self._pin, self.direction, self.pin_type)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
""" Get the name of the pin. """
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self):
|
||||||
|
""" Returns True if pin is high/on. """
|
||||||
|
return self._state
|
||||||
|
|
||||||
|
def turn_on(self):
|
||||||
|
""" Turns the pin to high/on. """
|
||||||
|
self._state = True
|
||||||
|
arduino.BOARD.set_digital_out_high(self._pin)
|
||||||
|
|
||||||
|
def turn_off(self):
|
||||||
|
""" Turns the pin to low/off. """
|
||||||
|
self._state = False
|
||||||
|
arduino.BOARD.set_digital_out_low(self._pin)
|
@ -73,3 +73,6 @@ jsonrpc-requests>=0.1
|
|||||||
|
|
||||||
# Forecast.io Bindings (sensor.forecast)
|
# Forecast.io Bindings (sensor.forecast)
|
||||||
python-forecastio>=1.3.3
|
python-forecastio>=1.3.3
|
||||||
|
|
||||||
|
# Firmata Bindings (*.arduino)
|
||||||
|
PyMata==2.07a
|
||||||
|
Loading…
x
Reference in New Issue
Block a user