示例#1
0
 def test_default_no_duplicates(self, mock_warn):
     """Ensure warning on duplicates."""
     sen = pysma.Sensors()
     assert mock_warn.call_count == 0
     # Add duplicate frequency
     news = pysma.Sensor('key1', 'frequency', '')
     sen.add(news)
     assert mock_warn.call_count == 1
     assert sen[news.name] == news
     # Add duplicate freq, key should not be raised
     sen.add(pysma.Sensor('6100_00465700', 'frequency', ''))
     assert mock_warn.call_count == 2
     # Add duplicate freq key only
     sen.add(pysma.Sensor('6100_00465700', 'f001', ''))
     assert mock_warn.call_count == 3
示例#2
0
文件: test_init.py 项目: fitool/pysma
 def test_null(self):
     """Test a null or None result."""
     sens = pysma.Sensor("6100_40263F00", "s_null", "W")
     assert (sens.extract_value(
         {"result": {
             "_": {
                 "6100_40263F00": {
                     "val": None
                 }
             }
         }}) is False)
     assert sens.value is None
     assert (sens.extract_value(
         {"result": {
             "_": {
                 "6100_40263F00": {
                     "1": [{
                         "val": None
                     }]
                 }
             }
         }}) is False)
     assert sens.value is None
     assert sens.extract_value({"result": {"_": {}}}) is False
     assert sens.value is None
示例#3
0
文件: test_init.py 项目: fitool/pysma
 def test_default_no_duplicates(self, mock_warn):
     """Ensure warning on duplicates."""
     sen = pysma.Sensors()
     assert len(sen) > 25
     assert len(sen) < 50
     assert mock_warn.call_count == 0
     # Add duplicate frequency
     news = pysma.Sensor("key1", "frequency", "")
     sen.add(news)
     assert mock_warn.call_count == 1
     assert sen[news.name] == news
     # Add duplicate freq, key should not be raised
     sen.add(pysma.Sensor("6100_00465700", "frequency", ""))
     assert mock_warn.call_count == 2
     # Add duplicate freq key only
     sen.add(pysma.Sensor("6100_00465700", "f001", ""))
     assert mock_warn.call_count == 3
     # Test different key_idx only
     sen.add(pysma.Sensor("key1_0", "frequency_0", ""))
     assert mock_warn.call_count == 3
     sen.add(pysma.Sensor("key1_1", "frequency_1", ""))
     assert mock_warn.call_count == 3
示例#4
0
 def test_null(self):
     sens = pysma.Sensor('s_null', '6100_40263F00', 'W')
     assert sens.extract_value(
         {"result": {"_": {"6100_40263F00": {"val": None}}}}) \
         is False
     assert sens.value is None
     assert sens.extract_value(
         {"result": {"_": {"6100_40263F00": {"1": [{"val": None}]}}}}) \
         is False
     assert sens.value is None
     assert sens.extract_value(
         {"result": {"_": {}}}) \
         is False
     assert sens.value is None
示例#5
0
def _parse_legacy_options(entry: ConfigEntry, sensor_def: pysma.Sensors) -> list[str]:
    """Parse legacy configuration options.

    This will parse the legacy CONF_SENSORS and CONF_CUSTOM configuration options
    to support deprecated yaml config from platform setup.
    """

    # Add sensors from the custom config
    sensor_def.add(
        [
            pysma.Sensor(o[CONF_KEY], n, o[CONF_UNIT], o[CONF_FACTOR], o.get(CONF_PATH))
            for n, o in entry.data.get(CONF_CUSTOM).items()
        ]
    )

    # Parsing of sensors configuration
    config_sensors = entry.data.get(CONF_SENSORS)
    if not config_sensors:
        return []

    # Support import of legacy config that should have been removed from 0.99, but was still functional
    # See also #25880 and #26306. Functional support was dropped in #48003
    if isinstance(config_sensors, dict):
        config_sensors_list = []

        for name, attr in config_sensors.items():
            config_sensors_list.append(name)
            config_sensors_list.extend(attr)

        config_sensors = config_sensors_list

    # Find and replace sensors removed from pysma
    # This only alters the config, the actual sensor migration takes place in _migrate_old_unique_ids
    for sensor in config_sensors.copy():
        if sensor in pysma.LEGACY_MAP:
            config_sensors.remove(sensor)
            config_sensors.append(pysma.LEGACY_MAP[sensor]["new_sensor"])

    # Only sensors from config should be enabled
    for sensor in sensor_def:
        sensor.enabled = sensor.name in config_sensors

    return config_sensors
示例#6
0
async def async_setup_platform(hass,
                               config,
                               async_add_entities,
                               discovery_info=None):
    """Set up SMA WebConnect sensor."""
    import pysma

    # Check config again during load - dependency available
    config = _check_sensor_schema(config)

    # Init all default sensors
    sensor_def = pysma.Sensors()

    # Sensor from the custom config
    sensor_def.add([
        pysma.Sensor(o[CONF_KEY], n, o[CONF_UNIT], o[CONF_FACTOR],
                     o.get(CONF_PATH)) for n, o in config[CONF_CUSTOM].items()
    ])

    # Use all sensors by default
    config_sensors = config[CONF_SENSORS]
    if not config_sensors:
        config_sensors = {s.name: [] for s in sensor_def}

    # Prepare all HASS sensor entities
    hass_sensors = []
    used_sensors = []
    for name, attr in config_sensors.items():
        sub_sensors = [sensor_def[s] for s in attr]
        hass_sensors.append(SMAsensor(sensor_def[name], sub_sensors))
        used_sensors.append(name)
        used_sensors.extend(attr)

    async_add_entities(hass_sensors)
    used_sensors = [sensor_def[s] for s in set(used_sensors)]

    # Init the SMA interface
    session = async_get_clientsession(hass, verify_ssl=config[CONF_VERIFY_SSL])
    grp = config[CONF_GROUP]

    url = "http{}://{}".format("s" if config[CONF_SSL] else "",
                               config[CONF_HOST])

    sma = pysma.SMA(session, url, config[CONF_PASSWORD], group=grp)

    # Ensure we logout on shutdown
    async def async_close_session(event):
        """Close the session."""
        await sma.close_session()

    hass.bus.async_listen(EVENT_HOMEASSISTANT_STOP, async_close_session)

    backoff = 0
    backoff_step = 0

    async def async_sma(event):
        """Update all the SMA sensors."""
        nonlocal backoff, backoff_step
        if backoff > 1:
            backoff -= 1
            return

        values = await sma.read(used_sensors)
        if not values:
            try:
                backoff = [1, 1, 1, 6, 30][backoff_step]
                backoff_step += 1
            except IndexError:
                backoff = 60
            return
        backoff_step = 0

        tasks = []
        for sensor in hass_sensors:
            task = sensor.async_update_values()
            if task:
                tasks.append(task)
        if tasks:
            await asyncio.wait(tasks)

    interval = config.get(CONF_SCAN_INTERVAL) or timedelta(seconds=5)
    async_track_time_interval(hass, async_sma, interval)
示例#7
0
def sensors():
    """Fixture to create some sensors."""
    yield [
        (402, True, pysma.Sensor('6400_00262200', 's_402', 'W')),
        (3514, True, pysma.Sensor('6400_00260100', 's_3514', 'W', 1000)),
    ]
示例#8
0
文件: test_init.py 项目: fitool/pysma
def sensors():
    """Fixture to create some sensors."""
    yield [
        (402, True, pysma.Sensor("6400_00262200", "s_402", "W")),
        (3514, True, pysma.Sensor("6400_00260100", "s_3514", "W", 1000)),
    ]