def valid_subscribe_topic(value, invalid_chars='\0'):
    """Validate that we can subscribe using this MQTT topic."""
    value = cv.string(value)
    if all(c not in value for c in invalid_chars):
        return vol.Length(min=1, max=65535)(value)
    raise vol.Invalid('Invalid MQTT topic name')
예제 #2
0
from homeassistant.const import CONF_DEVICES, CONF_EMAIL, CONF_PASSWORD
from homeassistant.helpers.entity import Entity

REQUIREMENTS = ["tank_utility==1.4.0"]

_LOGGER = logging.getLogger(__name__)

SCAN_INTERVAL = datetime.timedelta(hours=1)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_EMAIL):
    cv.string,
    vol.Required(CONF_PASSWORD):
    cv.string,
    vol.Required(CONF_DEVICES):
    vol.All(cv.ensure_list, vol.Length(min=1))
})

SENSOR_TYPE = "tank"
SENSOR_ROUNDING_PRECISION = 1
SENSOR_UNIT_OF_MEASUREMENT = "%"
SENSOR_ATTRS = [
    "name", "address", "capacity", "fuelType", "orientation", "status", "time",
    "time_iso"
]


def setup_platform(hass, config, add_entities, discovery_info=None):
    """Set up the Tank Utility sensor."""
    from tank_utility import auth
    email = config.get(CONF_EMAIL)
예제 #3
0
파일: sensor.py 프로젝트: rikroe/core
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
from homeassistant.const import CONF_DEVICES, CONF_EMAIL, CONF_PASSWORD, PERCENTAGE
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType

_LOGGER = logging.getLogger(__name__)

SCAN_INTERVAL = datetime.timedelta(hours=1)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Required(CONF_EMAIL): cv.string,
        vol.Required(CONF_PASSWORD): cv.string,
        vol.Required(CONF_DEVICES): vol.All(cv.ensure_list, vol.Length(min=1)),
    }
)

SENSOR_TYPE = "tank"
SENSOR_ROUNDING_PRECISION = 1
SENSOR_ATTRS = [
    "name",
    "address",
    "capacity",
    "fuelType",
    "orientation",
    "status",
    "time",
    "time_iso",
]
예제 #4
0
        raise vol.Invalid("All RCSwitch codes must be in quotes ('')")
    for c in value:
        if c not in ('0', '1'):
            raise vol.Invalid(
                u"Invalid RCSwitch code character '{}'. Only '0' and '1' are allowed"
                u"".format(c))
    if len(value) > 32:
        raise vol.Invalid(
            "Maximum length for RCSwitch codes is 32, code '{}' has length {}"
            "".format(value, len(value)))
    if not value:
        raise vol.Invalid("RCSwitch code must not be empty")
    return value


RC_SWITCH_TIMING_SCHEMA = vol.All([cv.uint8_t], vol.Length(min=2, max=2))

RC_SWITCH_PROTOCOL_SCHEMA = vol.Any(
    vol.All(vol.Coerce(int), vol.Range(min=1, max=7)),
    vol.Schema({
        vol.Required(CONF_PULSE_LENGTH): cv.uint32_t,
        vol.Optional(CONF_SYNC, default=[1, 31]): RC_SWITCH_TIMING_SCHEMA,
        vol.Optional(CONF_ZERO, default=[1, 3]): RC_SWITCH_TIMING_SCHEMA,
        vol.Optional(CONF_ONE, default=[3, 1]): RC_SWITCH_TIMING_SCHEMA,
        vol.Optional(CONF_INVERTED, default=False): cv.boolean,
    }))

RC_SWITCH_RAW_SCHEMA = vol.Schema({
    vol.Required(CONF_CODE):
    validate_rc_switch_code,
    vol.Optional(CONF_PROTOCOL, default=1):
예제 #5
0
파일: remote.py 프로젝트: Twtcer/core-1
from .device import BroadlinkDevice

_LOGGER = logging.getLogger(__name__)

SCAN_INTERVAL = timedelta(minutes=2)

CODE_STORAGE_VERSION = 1
FLAG_STORAGE_VERSION = 1
FLAG_SAVE_DELAY = 15

DEVICE_TYPES = RM_TYPES + RM4_TYPES

MINIMUM_SERVICE_SCHEMA = vol.Schema(
    {
        vol.Required(ATTR_COMMAND):
        vol.All(cv.ensure_list, [vol.All(cv.string, vol.Length(min=1))],
                vol.Length(min=1)),
        vol.Required(ATTR_DEVICE):
        vol.All(cv.string, vol.Length(min=1)),
    },
    extra=vol.ALLOW_EXTRA,
)

SERVICE_SEND_SCHEMA = MINIMUM_SERVICE_SCHEMA.extend({
    vol.Optional(ATTR_DELAY_SECS, default=DEFAULT_DELAY_SECS):
    vol.Coerce(float)
})

SERVICE_LEARN_SCHEMA = MINIMUM_SERVICE_SCHEMA.extend({
    vol.Optional(ATTR_ALTERNATIVE, default=False):
    cv.boolean,
예제 #6
0
    async_get_data_manager,
    async_remove_data_manager,
    get_data_manager_by_webhook_id,
    json_message_response,
)

DOMAIN = const.DOMAIN
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]

CONFIG_SCHEMA = vol.Schema(
    {
        DOMAIN: vol.All(
            cv.deprecated(const.CONF_PROFILES),
            vol.Schema(
                {
                    vol.Required(CONF_CLIENT_ID): vol.All(cv.string, vol.Length(min=1)),
                    vol.Required(CONF_CLIENT_SECRET): vol.All(
                        cv.string, vol.Length(min=1)
                    ),
                    vol.Optional(const.CONF_USE_WEBHOOK, default=False): cv.boolean,
                    vol.Optional(const.CONF_PROFILES): vol.All(
                        cv.ensure_list,
                        vol.Unique(),
                        vol.Length(min=1),
                        [vol.All(cv.string, vol.Length(min=1))],
                    ),
                }
            ),
        )
    },
    extra=vol.ALLOW_EXTRA,
예제 #7
0
from homeassistant.exceptions import PlatformNotReady
import homeassistant.helpers.config_validation as cv
from homeassistant.util import color, dt

REQUIREMENTS = ['python-miio==0.4.4', 'construct==2.9.45']

_LOGGER = logging.getLogger(__name__)

DEFAULT_NAME = 'Xiaomi Philips Light'
DATA_KEY = 'light.xiaomi_miio'

CONF_MODEL = 'model'

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_HOST): cv.string,
    vol.Required(CONF_TOKEN): vol.All(cv.string, vol.Length(min=32, max=32)),
    vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
    vol.Optional(CONF_MODEL): vol.In(
        ['philips.light.sread1',
         'philips.light.ceiling',
         'philips.light.zyceiling',
         'philips.light.moonlight',
         'philips.light.bulb',
         'philips.light.candle',
         'philips.light.candle2',
         'philips.light.mono1',
         'philips.light.downlight',
         ]),
})

# The light does not accept cct values < 1
예제 #8
0
from homeassistant.helpers import config_validation as cv
from homeassistant.components.camera import PLATFORM_SCHEMA, Camera

_LOGGER = logging.getLogger(__name__)

SCAN_INTERVAL = timedelta(seconds=5)

DEFAULT_TRIMS = {
    CONF_LEFT: 0,
    CONF_RIGHT: 0,
    CONF_TOP: 0,
    CONF_BOTTOM: 0
}

COLOR_SCHEMA = vol.Or(
    vol.All(vol.Length(min=3, max=3), vol.ExactSequence((cv.byte, cv.byte, cv.byte)), vol.Coerce(tuple)),
    vol.All(vol.Length(min=4, max=4), vol.ExactSequence((cv.byte, cv.byte, cv.byte, cv.byte)), vol.Coerce(tuple))
)

PERCENT_SCHEMA = vol.All(vol.Coerce(float), vol.Range(min=0, max=100))

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Required(CONF_HOST): cv.string,
        vol.Required(CONF_TOKEN): vol.All(str, vol.Length(min=32, max=32)),
        vol.Required(CONF_USERNAME): cv.string,
        vol.Required(CONF_PASSWORD): cv.string,
        vol.Required(CONF_COUNTRY): vol.In(CONF_AVAILABLE_COUNTRIES),
        vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
        vol.Optional(CONF_COLORS, default={}): vol.Schema({
            vol.In(CONF_AVAILABLE_COLORS): COLOR_SCHEMA
예제 #9
0
     vol.Optional("config_flow"): bool,
     vol.Optional("mqtt"): [str],
     vol.Optional("zeroconf"): [
         vol.Any(
             str,
             vol.Schema(
                 {
                     vol.Required("type"): str,
                     vol.Optional("macaddress"): vol.All(str, verify_uppercase),
                     vol.Optional("name"): vol.All(str, verify_lowercase),
                 }
             ),
         )
     ],
     vol.Optional("ssdp"): vol.Schema(
         vol.All([vol.All(vol.Schema({}, extra=vol.ALLOW_EXTRA), vol.Length(min=1))])
     ),
     vol.Optional("homekit"): vol.Schema({vol.Optional("models"): [str]}),
     vol.Required("documentation"): vol.All(
         vol.Url(), documentation_url  # pylint: disable=no-value-for-parameter
     ),
     vol.Optional(
         "issue_tracker"
     ): vol.Url(),  # pylint: disable=no-value-for-parameter
     vol.Optional("quality_scale"): vol.In(SUPPORTED_QUALITY_SCALES),
     vol.Optional("requirements"): [str],
     vol.Optional("dependencies"): [str],
     vol.Optional("after_dependencies"): [str],
     vol.Required("codeowners"): [str],
     vol.Optional("disabled"): str,
 }
예제 #10
0
# Valid sensors for configuration
VALID_SENSORS = ['%s_%s' % (typ, var)
                 for typ in SENSOR_TYPES
                 for var in SENSOR_VARIANTS]

ICON = 'mdi:flash'

MIN_TIME_BETWEEN_DAILY_UPDATES = timedelta(seconds=300)
MIN_TIME_BETWEEN_ACTIVE_UPDATES = timedelta(seconds=60)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_EMAIL): cv.string,
    vol.Required(CONF_PASSWORD): cv.string,
    vol.Required(CONF_MONITORED_CONDITIONS):
        vol.All(cv.ensure_list, vol.Length(min=1), [vol.In(VALID_SENSORS)]),
})


def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up the Sense sensor."""
    from sense_energy import Senseable

    username = config.get(CONF_EMAIL)
    password = config.get(CONF_PASSWORD)

    data = Senseable(username, password)

    @Throttle(MIN_TIME_BETWEEN_DAILY_UPDATES)
    def update_trends():
        """Update the daily power usage."""
예제 #11
0
SUPPORT_TURN_ON = 1
SUPPORT_TURN_OFF = 2
SUPPORT_LOAD_URL = 4
SUPPORT_SET_BRIGHTNESS = 8

DISPLAY_DEVICE_SCHEMA = vol.Schema({
    ATTR_ENTITY_ID: cv.entity_ids,
})
DISPLAY_DEVICE_LOAD_URL_SCHEMA = DISPLAY_DEVICE_SCHEMA.extend({
    vol.Required(ATTR_URL): cv.string,
})
DISPLAY_DEVICE_SET_BRIGHTNESS_SCHEMA = DISPLAY_DEVICE_SCHEMA.extend({
    vol.Optional(ATTR_BRIGHTNESS, default=None):
        vol.Any(
            vol.All(str, vol.Length(min=0, max=3)),
            vol.All(int, vol.Range(min=0, max=255))
        )
})


@bind_hass
def is_on(hass, entity_id=None):
    entity_id = entity_id or ENTITY_ID_ALL_DISPLAYS
    return hass.states.is_state(entity_id, STATE_ON)


async def async_setup(hass, config):
    component = EntityComponent(
        _LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_DISPLAYS)
예제 #12
0
파일: __init__.py 프로젝트: rikroe/core
    json_message_response,
)

DOMAIN = const.DOMAIN
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]

CONFIG_SCHEMA = vol.Schema(
    {
        DOMAIN:
        vol.All(
            cv.deprecated(const.CONF_PROFILES),
            cv.deprecated(CONF_CLIENT_ID),
            cv.deprecated(CONF_CLIENT_SECRET),
            vol.Schema({
                vol.Optional(CONF_CLIENT_ID):
                vol.All(cv.string, vol.Length(min=1)),
                vol.Optional(CONF_CLIENT_SECRET):
                vol.All(cv.string, vol.Length(min=1)),
                vol.Optional(const.CONF_USE_WEBHOOK, default=False):
                cv.boolean,
                vol.Optional(const.CONF_PROFILES):
                vol.All(
                    cv.ensure_list,
                    vol.Unique(),
                    vol.Length(min=1),
                    [vol.All(cv.string, vol.Length(min=1))],
                ),
            }),
        )
    },
    extra=vol.ALLOW_EXTRA,
예제 #13
0
파일: light.py 프로젝트: 2Fake/core
# Constant color temp values for 2 flux_led special modes
# Warm-white and Cool-white modes
COLOR_TEMP_WARM_VS_COLD_WHITE_CUT_OFF: Final = 285

EFFECT_CUSTOM: Final = "custom"

SERVICE_CUSTOM_EFFECT: Final = "set_custom_effect"
SERVICE_SET_ZONES: Final = "set_zones"
SERVICE_SET_MUSIC_MODE: Final = "set_music_mode"

CUSTOM_EFFECT_DICT: Final = {
    vol.Required(CONF_COLORS):
    vol.All(
        cv.ensure_list,
        vol.Length(min=1, max=16),
        [
            vol.All(vol.Coerce(tuple),
                    vol.ExactSequence((cv.byte, cv.byte, cv.byte)))
        ],
    ),
    vol.Optional(CONF_SPEED_PCT, default=50):
    vol.All(vol.Coerce(int), vol.Range(min=0, max=100)),
    vol.Optional(CONF_TRANSITION, default=TRANSITION_GRADUAL):
    vol.All(cv.string,
            vol.In([TRANSITION_GRADUAL, TRANSITION_JUMP, TRANSITION_STROBE])),
}

SET_MUSIC_MODE_DICT: Final = {
    vol.Optional(ATTR_SENSITIVITY, default=100):
    vol.All(vol.Coerce(int), vol.Range(min=0, max=100)),
예제 #14
0
DEFAULT_NAME = 'LG TV Remote'

MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(seconds=1)
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)

SUPPORT_LGTV = SUPPORT_PAUSE | SUPPORT_VOLUME_STEP | \
               SUPPORT_VOLUME_MUTE | SUPPORT_PREVIOUS_TRACK | \
               SUPPORT_NEXT_TRACK | SUPPORT_TURN_OFF | \
               SUPPORT_SELECT_SOURCE | SUPPORT_PLAY

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_HOST):
    cv.string,
    vol.Optional(CONF_ACCESS_TOKEN):
    vol.All(cv.string, vol.Length(max=6)),
    vol.Optional(CONF_NAME, default=DEFAULT_NAME):
    cv.string,
})


def setup_platform(hass, config, add_entities, discovery_info=None):
    """Set up the LG TV platform."""
    from pylgnetcast import LgNetCastClient

    host = config.get(CONF_HOST)
    access_token = config.get(CONF_ACCESS_TOKEN)
    name = config.get(CONF_NAME)

    client = LgNetCastClient(host, access_token)
예제 #15
0
})

SERVICE_SELECT_PREVIOUS = 'select_previous'

SERVICE_SELECT_PREVIOUS_SCHEMA = vol.Schema({
    vol.Optional(ATTR_ENTITY_ID):
    cv.entity_ids,
})

SERVICE_SET_OPTIONS = 'set_options'

SERVICE_SET_OPTIONS_SCHEMA = vol.Schema({
    vol.Required(ATTR_ENTITY_ID):
    cv.entity_ids,
    vol.Required(ATTR_OPTIONS):
    vol.All(cv.ensure_list, vol.Length(min=1), [cv.string]),
})


def _cv_input_select(cfg):
    """Configure validation helper for input select (voluptuous)."""
    options = cfg[CONF_OPTIONS]
    initial = cfg.get(CONF_INITIAL)
    if initial is not None and initial not in options:
        raise vol.Invalid(
            'initial state "{}" is not part of the options: {}'.format(
                initial, ','.join(options)))
    return cfg


CONFIG_SCHEMA = vol.Schema(
예제 #16
0
    def post(self,
             title,
             body,
             author,
             permlink=None,
             reply_identifier=None,
             json_metadata=None,
             comment_options=None,
             community=None,
             tags=None,
             beneficiaries=None,
             self_vote=False):
        """ Create a new post.

        If this post is intended as a reply/comment, `reply_identifier` needs
        to be set with the identifier of the parent post/comment (eg.
        `author/permlink`).

        Optionally you can also set json_metadata, comment_options and upvote
        the newly created post as an author.

        Setting category, tags or community will override the values provided
        in json_metadata and/or comment_options where appropriate.

        Args:

        title (str): Title of the post
        body (str): Body of the post/comment
        author (str): Account are you posting from
        permlink (str): Manually set the permlink (defaults to None).
            If left empty, it will be derived from title automatically.
        reply_identifier (str): Identifier of the parent post/comment (only
            if this post is a reply/comment).
        json_metadata (str, dict): JSON meta object that can be attached to
            the post.
        comment_options (str, dict): JSON options object that can be
            attached to the post.

        Example::
            comment_options = {
                'max_accepted_payout': '1000000.000 SMOKE',
                'allow_votes': True,
                'allow_curation_rewards': True,
                'extensions': [[0, {
                    'beneficiaries': [
                        {'account': 'account1', 'weight': 5000},
                        {'account': 'account2', 'weight': 5000},
                    ]}
                ]]
            }

        community (str): (Optional) Name of the community we are posting
            into. This will also override the community specified in
            `json_metadata`.

        tags (str, list): (Optional) A list of tags (5 max) to go with the
            post. This will also override the tags specified in
            `json_metadata`. The first tag will be used as a 'category'. If
            provided as a string, it should be space separated.

        beneficiaries (list of dicts): (Optional) A list of beneficiaries
            for posting reward distribution. This argument overrides
            beneficiaries as specified in `comment_options`.

        For example, if we would like to split rewards between account1 and
        account2::

            beneficiaries = [
                {'account': 'account1', 'weight': 5000},
                {'account': 'account2', 'weight': 5000}
            ]

        self_vote (bool): (Optional) Upvote the post as author, right after
            posting.

        """

        # prepare json_metadata
        json_metadata = json_metadata or {}
        if isinstance(json_metadata, str):
            json_metadata = silent(json.loads)(json_metadata) or {}

        # override the community
        if community:
            json_metadata.update({'community': community})

        # deal with the category and tags
        if isinstance(tags, str):
            tags = list(set(filter(None, (re.split("[\W_]", tags)))))

        category = None
        tags = tags or json_metadata.get('tags', [])
        if tags:
            if len(tags) > 5:
                raise ValueError('Can only specify up to 5 tags per post.')

            # first tag should be a category
            category = tags[0]
            json_metadata.update({"tags": tags})

        # can't provide a category while replying to a post
        if reply_identifier and category:
            category = None

        # deal with replies/categories
        if reply_identifier:
            parent_author, parent_permlink = resolve_identifier(
                reply_identifier)
            if not permlink:
                permlink = derive_permlink(title, parent_permlink)
        elif category:
            parent_permlink = derive_permlink(category)
            parent_author = ""
            if not permlink:
                permlink = derive_permlink(title)
        else:
            parent_author = ""
            parent_permlink = ""
            if not permlink:
                permlink = derive_permlink(title)

        post_op = operations.Comment(
            **{
                "parent_author": parent_author,
                "parent_permlink": parent_permlink,
                "author": author,
                "permlink": permlink,
                "title": title,
                "body": body,
                "json_metadata": json_metadata
            })
        ops = [post_op]

        # if comment_options are used, add a new op to the transaction
        if comment_options or beneficiaries:
            options = keep_in_dict(comment_options or {}, [
                'max_accepted_payout', 'percent_steem_dollars', 'allow_votes',
                'allow_curation_rewards', 'extensions'
            ])
            # override beneficiaries extension
            if beneficiaries:
                # validate schema
                # or just simply vo.Schema([{'account': str, 'weight': int}])
                schema = vo.Schema([{
                    vo.Required('account'):
                    vo.All(str, vo.Length(max=16)),
                    vo.Required('weight', default=10000):
                    vo.All(int, vo.Range(min=1, max=10000))
                }])
                schema(beneficiaries)
                options['beneficiaries'] = beneficiaries

            default_max_payout = "1000000.000 SMOKE"
            comment_op = operations.CommentOptions(
                **{
                    "author":
                    author,
                    "permlink":
                    permlink,
                    "max_accepted_payout":
                    options.get("max_accepted_payout", default_max_payout),
                    "percent_steem_dollars":
                    int(options.get("percent_steem_dollars", 10000)),
                    "allow_votes":
                    options.get("allow_votes", True),
                    "allow_curation_rewards":
                    options.get("allow_curation_rewards", True),
                    "extensions":
                    options.get("extensions", []),
                    "beneficiaries":
                    options.get("beneficiaries"),
                })
            ops.append(comment_op)

        if self_vote:
            vote_op = operations.Vote(
                **{
                    'voter': author,
                    'author': author,
                    'permlink': permlink,
                    'weight': 10000,
                })
            ops.append(vote_op)

        return self.finalizeOp(ops, author, "posting")
예제 #17
0

def validate_fingerprint(value):
    value = cv.string(value)
    if re.match(r'^[0-9a-f]{40}$', value) is None:
        raise vol.Invalid(u"fingerprint must be valid SHA1 hash")
    return value


CONFIG_SCHEMA = vol.Schema({
    cv.GenerateID(): cv.declare_variable_id(MQTTClientComponent),
    vol.Required(CONF_BROKER): validate_broker,
    vol.Optional(CONF_PORT, default=1883): cv.port,
    vol.Optional(CONF_USERNAME, default=''): cv.string,
    vol.Optional(CONF_PASSWORD, default=''): cv.string,
    vol.Optional(CONF_CLIENT_ID): vol.All(cv.string, vol.Length(max=23)),
    vol.Optional(CONF_DISCOVERY): cv.boolean,
    vol.Optional(CONF_DISCOVERY_RETAIN): cv.boolean,
    vol.Optional(CONF_DISCOVERY_PREFIX): cv.publish_topic,
    vol.Optional(CONF_BIRTH_MESSAGE): MQTT_MESSAGE_SCHEMA,
    vol.Optional(CONF_WILL_MESSAGE): MQTT_MESSAGE_SCHEMA,
    vol.Optional(CONF_TOPIC_PREFIX): cv.publish_topic,
    vol.Optional(CONF_LOG_TOPIC): MQTT_MESSAGE_TEMPLATE_SCHEMA,
    vol.Optional(CONF_SSL_FINGERPRINTS): vol.All(cv.only_on_esp8266,
                                                 cv.ensure_list, [validate_fingerprint]),
    vol.Optional(CONF_KEEPALIVE): cv.positive_time_period_seconds,
    vol.Optional(CONF_ON_MESSAGE): vol.All(cv.ensure_list, [automation.AUTOMATION_SCHEMA.extend({
        cv.GenerateID(CONF_TRIGGER_ID): cv.declare_variable_id(MQTTMessageTrigger),
        vol.Required(CONF_TOPIC): cv.publish_topic,
        vol.Optional(CONF_QOS, default=0): cv.mqtt_qos,
    })])
예제 #18
0
파일: sensor.py 프로젝트: eXtgmA/ws980wifi
    "gust": ["gust", SPEED_METERS_PER_SECOND, None, "38", "2", "10"],
    "rain": ["rain", LENGTH_MILLIMETERS, None, "41", "4", "10"],
    "rain_day": ["rain day", LENGTH_MILLIMETERS, None, "46", "4", "10"],
    "rain_week": ["rain week", LENGTH_MILLIMETERS, None, "51", "4", "10"],
    "rain_month": ["rain month", LENGTH_MILLIMETERS, None, "56", "4", "10"],
    "rain_year": ["rain year", LENGTH_MILLIMETERS, None, "61", "4", "10"],
    "rain_total": ["rain total", LENGTH_MILLIMETERS, None, "66", "4", "10"],
    "light": ["light", ILLUMINANCE, None, "71", "4", "10"],
    "uv_value": ["uv value", UV_VALUE, None, "76", "2", "10"],
    "uv_index": ["uv index", UV_INDEX, None, "79", "1", "1"],
}

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Optional(CONF_MONITORED_CONDITIONS, default=["inside_temperature"]): vol.All(
            cv.ensure_list, vol.Length(min=1), [vol.In(SENSOR_PROPERTIES)]
        ),
        vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
        vol.Required(CONF_HOST): cv.string,
        vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
        vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int
    }
)

async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
    """Set up the sensor platform."""
    name = config.get(CONF_NAME)

    sensors = []
    for sensor_property in config[CONF_MONITORED_CONDITIONS]:
        sensors.append(WeatherSensor(name, sensor_property))
예제 #19
0
    "YI",
]

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_API_KEY):
    cv.string,
    vol.Optional(CONF_PWS_ID):
    cv.string,
    vol.Optional(CONF_LANG, default=DEFAULT_LANG):
    vol.All(vol.In(LANG_CODES)),
    vol.Inclusive(CONF_LATITUDE, "coordinates", "Latitude and longitude must exist together"):
    cv.latitude,
    vol.Inclusive(CONF_LONGITUDE, "coordinates", "Latitude and longitude must exist together"):
    cv.longitude,
    vol.Required(CONF_MONITORED_CONDITIONS):
    vol.All(cv.ensure_list, vol.Length(min=1), [vol.In(SENSOR_TYPES)]),
})


async def async_setup_platform(hass: HomeAssistantType,
                               config: ConfigType,
                               async_add_entities,
                               discovery_info=None):
    """Set up the WUnderground sensor."""
    latitude = config.get(CONF_LATITUDE, hass.config.latitude)
    longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
    pws_id = config.get(CONF_PWS_ID)

    rest = WUndergroundData(
        hass,
        config.get(CONF_API_KEY),
예제 #20
0
    EFFECT_WHITE_STROBE: 0x37,
    EFFECT_COLORJUMP: 0x38,
}
EFFECT_CUSTOM_CODE = 0x60

TRANSITION_GRADUAL = "gradual"
TRANSITION_JUMP = "jump"
TRANSITION_STROBE = "strobe"

FLUX_EFFECT_LIST = sorted(list(EFFECT_MAP)) + [EFFECT_RANDOM]

CUSTOM_EFFECT_SCHEMA = vol.Schema({
    vol.Required(CONF_COLORS):
    vol.All(
        cv.ensure_list,
        vol.Length(min=1, max=16),
        [
            vol.All(vol.ExactSequence(
                (cv.byte, cv.byte, cv.byte)), vol.Coerce(tuple))
        ],
    ),
    vol.Optional(CONF_SPEED_PCT, default=50):
    vol.All(vol.Range(min=0, max=100), vol.Coerce(int)),
    vol.Optional(CONF_TRANSITION, default=TRANSITION_GRADUAL):
    vol.All(cv.string,
            vol.In([TRANSITION_GRADUAL, TRANSITION_JUMP, TRANSITION_STROBE])),
})

DEVICE_SCHEMA = vol.Schema({
    vol.Optional(CONF_NAME):
    cv.string,
예제 #21
0
async def async_setup_entry(hass, config_entry, async_add_entities):
    """Set up an LMS Server from a config entry."""
    config = config_entry.data
    _LOGGER.debug("Reached async_setup_entry for host=%s", config[CONF_HOST])

    username = config.get(CONF_USERNAME)
    password = config.get(CONF_PASSWORD)
    host = config[CONF_HOST]
    port = config[CONF_PORT]

    hass.data.setdefault(DOMAIN, {})
    hass.data[DOMAIN].setdefault(config_entry.entry_id, {})

    known_players = hass.data[DOMAIN].setdefault(KNOWN_PLAYERS, [])

    session = async_get_clientsession(hass)
    _LOGGER.debug("Creating LMS object for %s", host)
    lms = Server(session, host, port, username, password)

    async def _discovery(now=None):
        """Discover squeezebox players by polling server."""
        async def _discovered_player(player):
            """Handle a (re)discovered player."""
            entity = next(
                (known for known in known_players
                 if known.unique_id == player.player_id),
                None,
            )
            if entity:
                await player.async_update()
                async_dispatcher_send(hass, SIGNAL_PLAYER_REDISCOVERED,
                                      player.player_id, player.connected)

            if not entity:
                _LOGGER.debug("Adding new entity: %s", player)
                entity = SqueezeBoxEntity(player)
                known_players.append(entity)
                async_add_entities([entity])

        players = await lms.async_get_players()
        if players:
            for player in players:
                hass.async_create_task(_discovered_player(player))

        hass.data[DOMAIN][config_entry.entry_id][
            PLAYER_DISCOVERY_UNSUB] = hass.helpers.event.async_call_later(
                DISCOVERY_INTERVAL, _discovery)

    _LOGGER.debug("Adding player discovery job for LMS server: %s", host)
    asyncio.create_task(_discovery())

    # Register entity services
    platform = entity_platform.current_platform.get()
    platform.async_register_entity_service(
        SERVICE_CALL_METHOD,
        {
            vol.Required(ATTR_COMMAND):
            cv.string,
            vol.Optional(ATTR_PARAMETERS):
            vol.All(cv.ensure_list, vol.Length(min=1), [cv.string]),
        },
        "async_call_method",
    )
    platform.async_register_entity_service(
        SERVICE_CALL_QUERY,
        {
            vol.Required(ATTR_COMMAND):
            cv.string,
            vol.Optional(ATTR_PARAMETERS):
            vol.All(cv.ensure_list, vol.Length(min=1), [cv.string]),
        },
        "async_call_query",
    )
    platform.async_register_entity_service(
        SERVICE_SYNC,
        {vol.Required(ATTR_OTHER_PLAYER): cv.string},
        "async_sync",
    )
    platform.async_register_entity_service(SERVICE_UNSYNC, None,
                                           "async_unsync")

    # Start server discovery task if not already running
    if hass.is_running:
        asyncio.create_task(start_server_discovery(hass))
    else:
        hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START,
                                   start_server_discovery(hass))

    return True
예제 #22
0
# pylint: disable=unused-import
from .const import DOMAIN
from .gateway import ConnectXiaomiGateway

_LOGGER = logging.getLogger(__name__)

CONF_FLOW_TYPE = "config_flow_device"
CONF_GATEWAY = "gateway"
DEFAULT_GATEWAY_NAME = "Xiaomi Gateway"

GATEWAY_CONFIG = vol.Schema({
    vol.Required(CONF_HOST):
    str,
    vol.Required(CONF_TOKEN):
    vol.All(str, vol.Length(min=32, max=32)),
    vol.Optional(CONF_NAME, default=DEFAULT_GATEWAY_NAME):
    str,
})

CONFIG_SCHEMA = vol.Schema({vol.Optional(CONF_GATEWAY, default=False): bool})


class XiaomiMiioFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
    """Handle a Xiaomi Miio config flow."""

    VERSION = 1
    CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL

    async def async_step_user(self, user_input=None):
        """Handle a flow initialized by the user."""
예제 #23
0
def validate_device_has_at_least_one_identifier(
        value: ConfigType) -> ConfigType:
    """Validate that a device info entry has at least one identifying value."""
    if value.get(CONF_IDENTIFIERS) or value.get(CONF_CONNECTIONS):
        return value
    raise vol.Invalid("Device must have at least one identifying value in "
                      "'identifiers' and/or 'connections'")


MQTT_ENTITY_DEVICE_INFO_SCHEMA = vol.All(
    cv.deprecated(CONF_DEPRECATED_VIA_HUB, CONF_VIA_DEVICE),
    vol.Schema({
        vol.Optional(CONF_IDENTIFIERS, default=list):
        vol.All(cv.ensure_list, [cv.string]),
        vol.Optional(CONF_CONNECTIONS, default=list):
        vol.All(cv.ensure_list, [vol.All(vol.Length(2), [cv.string])]),
        vol.Optional(CONF_MANUFACTURER):
        cv.string,
        vol.Optional(CONF_MODEL):
        cv.string,
        vol.Optional(CONF_NAME):
        cv.string,
        vol.Optional(CONF_SW_VERSION):
        cv.string,
        vol.Optional(CONF_VIA_DEVICE):
        cv.string,
    }),
    validate_device_has_at_least_one_identifier,
)

MQTT_JSON_ATTRS_SCHEMA = vol.Schema({
예제 #24
0
"""Define sensor commands."""
from typing import Any, Awaitable, Callable, Dict, cast

import voluptuous as vol

from aioguardian.errors import CommandError
from aioguardian.helpers.command import Command
import aioguardian.helpers.config_validation as cv

PARAM_UID = "uid"

PAIRED_SENSOR_UID_SCHEMA: vol.Schema = vol.Schema(
    {vol.Required(PARAM_UID): vol.All(cv.alphanumeric, vol.Length(max=12))})


class SensorCommands:
    """Define an object to manage sensor commands.

    Note that this class shouldn't be instantiated directly; an instance of it will
    automatically be added to the :meth:`Client <aioguardian.Client>` (as
    ``client.sensor``).
    """
    def __init__(self, execute_command: Callable[..., Awaitable]) -> None:
        """Initialize."""
        self._execute_command = execute_command

    async def pair_dump(self, *, silent: bool = True) -> Dict[str, Any]:
        """Dump information on all paired sensors.

        :param silent: If ``True``, silence "beep" tones associated with this command
        :type silent: ``bool``
예제 #25
0
COMMAND_SCHEMA = vol.Schema(
    {vol.Required(CONF_COMMAND): vol.All(cv.ensure_list, [cv.string])}
)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Optional(CONF_NAME): cv.string,
        vol.Required(CONF_HOST): cv.string,
        vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): vol.All(
            int, vol.Range(min=0)
        ),
        vol.Optional(CONF_SLOT, default=DEFAULT_SLOT): vol.All(
            int, vol.Range(min=1, max=1000000)
        ),
        vol.Required(CONF_TOKEN): vol.All(str, vol.Length(min=32, max=32)),
        vol.Optional(CONF_COMMANDS, default={}): cv.schema_with_slug_keys(
            COMMAND_SCHEMA
        ),
    },
    extra=vol.ALLOW_EXTRA,
)


async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
    """Set up the Xiaomi IR Remote (Chuangmi IR) platform."""
    host = config[CONF_HOST]
    token = config[CONF_TOKEN]

    # Create handler
    _LOGGER.info("Initializing with host %s (token %s...)", host, token[:5])
예제 #26
0
CONF_KEY = 'key'
CONF_DISABLE = 'disable'

DOMAIN = 'xiaomi_aqara'

PY_XIAOMI_GATEWAY = "xiaomi_gw"

TIME_TILL_UNAVAILABLE = timedelta(minutes=150)

SERVICE_PLAY_RINGTONE = 'play_ringtone'
SERVICE_STOP_RINGTONE = 'stop_ringtone'
SERVICE_ADD_DEVICE = 'add_device'
SERVICE_REMOVE_DEVICE = 'remove_device'

GW_MAC = vol.All(cv.string, lambda value: value.replace(':', '').lower(),
                 vol.Length(min=12, max=12))

SERVICE_SCHEMA_PLAY_RINGTONE = vol.Schema({
    vol.Required(ATTR_RINGTONE_ID):
    vol.All(vol.Coerce(int), vol.NotIn([9, 14, 15, 16, 17, 18, 19])),
    vol.Optional(ATTR_RINGTONE_VOL):
    vol.All(vol.Coerce(int), vol.Clamp(min=0, max=100))
})

SERVICE_SCHEMA_REMOVE_DEVICE = vol.Schema({
    vol.Required(ATTR_DEVICE_ID):
    vol.All(cv.string, vol.Length(min=14, max=14))
})

GATEWAY_CONFIG = vol.Schema({
    vol.Optional(CONF_MAC, default=None):
예제 #27
0
            continue

        device_trackers = person[CONF_DEVICE_TRACKERS]

        if device_tracker_entity_id in device_trackers:
            return

        await coll.async_update_item(
            person[collection.CONF_ID],
            {CONF_DEVICE_TRACKERS: device_trackers + [device_tracker_entity_id]},
        )
        break


CREATE_FIELDS = {
    vol.Required(CONF_NAME): vol.All(str, vol.Length(min=1)),
    vol.Optional(CONF_USER_ID): vol.Any(str, None),
    vol.Optional(CONF_DEVICE_TRACKERS, default=list): vol.All(
        cv.ensure_list, cv.entities_domain(DEVICE_TRACKER_DOMAIN)
    ),
    vol.Optional(CONF_PICTURE): vol.Any(str, None),
}


UPDATE_FIELDS = {
    vol.Optional(CONF_NAME): vol.All(str, vol.Length(min=1)),
    vol.Optional(CONF_USER_ID): vol.Any(str, None),
    vol.Optional(CONF_DEVICE_TRACKERS, default=list): vol.All(
        cv.ensure_list, cv.entities_domain(DEVICE_TRACKER_DOMAIN)
    ),
    vol.Optional(CONF_PICTURE): vol.Any(str, None),
예제 #28
0
from homeassistant.const import (
    CONF_NAME,
    CONF_HOST,
    CONF_TOKEN,
)
from homeassistant.exceptions import PlatformNotReady

_LOGGER = logging.getLogger(__name__)

DEFAULT_NAME = 'Xiaomi Miio Switch'

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Required(CONF_HOST):
    cv.string,
    vol.Required(CONF_TOKEN):
    vol.All(cv.string, vol.Length(min=32, max=32)),
    vol.Optional(CONF_NAME, default=DEFAULT_NAME):
    cv.string,
})

REQUIREMENTS = ['python-miio==0.3.3']

ATTR_POWER = 'power'
ATTR_TEMPERATURE = 'temperature'
ATTR_LOAD_POWER = 'load_power'
ATTR_MODEL = 'model'
SUCCESS = ['ok']


# pylint: disable=unused-argument
@asyncio.coroutine
예제 #29
0
    customs = list(conf[CONF_CUSTOM])

    for sensor in conf[CONF_SENSORS]:
        if sensor in customs:
            _LOGGER.warning(
                "All custom sensors will be added automatically, no need to include them in sensors: %s",
                sensor,
            )
        elif sensor not in valid:
            raise vol.Invalid(f"{sensor} does not exist")
    return conf


CUSTOM_SCHEMA = vol.Any(
    {
        vol.Required(CONF_KEY): vol.All(cv.string, vol.Length(min=13, max=15)),
        vol.Required(CONF_UNIT): cv.string,
        vol.Optional(CONF_FACTOR, default=1): vol.Coerce(float),
        vol.Optional(CONF_PATH): vol.All(cv.ensure_list, [cv.string]),
    }
)

PLATFORM_SCHEMA = vol.All(
    PLATFORM_SCHEMA.extend(
        {
            vol.Required(CONF_HOST): cv.string,
            vol.Optional(CONF_SSL, default=False): cv.boolean,
            vol.Optional(CONF_VERIFY_SSL, default=True): cv.boolean,
            vol.Required(CONF_PASSWORD): cv.string,
            vol.Optional(CONF_GROUP, default=GROUPS[0]): vol.In(GROUPS),
            vol.Optional(CONF_SENSORS, default=[]): vol.Any(
예제 #30
0
    vol.Range(1, 48),
    vol.Required(CONF_NAME):
    cv.string,
    vol.Optional(CONF_NET_METERING, default=False):
    cv.boolean,
})

CHANNELS_SCHEMA = vol.All(cv.ensure_list, [CHANNEL_SCHEMA])

MONITOR_SCHEMA = vol.Schema({
    vol.Required(CONF_SERIAL_NUMBER):
    vol.All(
        cv.string,
        vol.Length(
            min=8,
            max=8,
            msg="GEM serial number must be specified as an 8-character "
            "string (including leading zeroes).",
        ),
        vol.Coerce(int),
    ),
    vol.Optional(CONF_CHANNELS, default=[]):
    CHANNELS_SCHEMA,
    vol.Optional(
        CONF_TEMPERATURE_SENSORS,
        default={
            CONF_TEMPERATURE_UNIT: TEMPERATURE_UNIT_CELSIUS,
            CONF_SENSORS: []
        },
    ):
    TEMPERATURE_SENSORS_SCHEMA,
    vol.Optional(CONF_PULSE_COUNTERS, default=[]):