Exemple #1
0
async def test_autobrightness_restore_saved_values(mock_aiohttp,
                                                   mock_never_lock):
    # arrange
    learning_storage = LearningStorage(copy.deepcopy(LEARNED_S100_G254))

    # act
    async with Govee(API_KEY, learning_storage=learning_storage) as govee:
        # request devices list
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                json={"data": {
                    "devices": [copy.deepcopy(JSON_DEVICE_H6163)]
                }},
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices",
            ))
        # call
        lamps, err = await govee.get_devices()
        # assert
        assert mock_aiohttp_responses.empty()
        assert not err
        assert len(lamps) == 1
        assert learning_storage.read_test_data == {
            DUMMY_DEVICE_H6163.device:
            GoveeLearnedInfo(
                set_brightness_max=100,
                get_brightness_max=254,  # this we learned from brightness state
            )
        }
        assert learning_storage.read_call_count == 1
        assert learning_storage.write_call_count == 0
 async def turn_on_and_get_state():
     async with Govee(API_KEY) as govee:
         # inject a device for testing
         govee._devices = {DUMMY_DEVICE_H6163.device: DUMMY_DEVICE_H6163}
         await govee.turn_on(DUMMY_DEVICE_H6163)
         # getting state to early (2s after switching)
         return await govee.get_states()
 async def getDevices():
     async with Govee(API_KEY) as govee:
         # inject devices for testing
         govee._devices = DUMMY_DEVICES
         # for dev in DUMMY_DEVICES:
         #    results_per_device[dev], errors_per_device[dev] = await govee.get_state(dev)
         states = await govee.get_states()
         return states
 async def get_devices():
     async with Govee(API_KEY) as govee:
         assert govee.rate_limit_on == 5
         assert govee.rate_limit_total == 100
         assert govee.rate_limit_reset == 0
         assert govee.rate_limit_remaining == 100
         # first run uses defaults, so ping returns immediatly
         return await govee.get_devices()
Exemple #5
0
async def test_turnonbeforebrightness_brightness0_setbrihtness0(
        mock_aiohttp, mock_never_lock):
    """
    It's not possible to learn before_set_brightness_turn_on,
    but you can set this in the learning data.
    Setting brightness to 0 will still only send brightness 0.
    """
    # arrange
    learning_storage = LearningStorage(
        copy.deepcopy(LEARNED_TURN_BEFORE_BRIGHTNESS))

    # act
    async with Govee(API_KEY, learning_storage=learning_storage) as govee:
        # request devices list
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                json={"data": {
                    "devices": [copy.deepcopy(JSON_DEVICE_H6163)]
                }},
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices",
            ))
        # call
        lamps, err = await govee.get_devices()
        # assert
        assert mock_aiohttp_responses.empty()
        assert not err
        assert len(lamps) == 1

        # set brightness to 1 (minimum for turning on)
        # then it will set brightness
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                status=200,
                json={
                    "code": 200,
                    "message": "Success",
                    "data": {}
                },
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices/control" and
                kwargs["json"] == {
                    "cmd": {
                        "name": "brightness",
                        "value": 0
                    },
                    "device": "40:83:FF:FF:FF:FF:FF:FF",
                    "model": "H6163",
                },
            ))
        # call
        success, err = await govee.set_brightness(DUMMY_DEVICE_H6163.device, 0)
        # assert
        assert mock_aiohttp_responses.empty()
        assert success
        assert not err
        assert govee.device(DUMMY_DEVICE_H6163.device).power_state == False
        assert govee.device(DUMMY_DEVICE_H6163.device).brightness == 0
Exemple #6
0
async def all_examples(api_key, your_learning_storage):
    ### using as async content manager
    async with Govee(api_key, learning_storage=your_learning_storage) as govee:
        # i will explain that learning_storage below.

        # check connection: never fails, just tells if we can connect the API. no auth needed.
        online = await govee.check_connection()
        # you may also register for an event, when api is going offline/online
        govee.events.online += lambda is_online: print(
            f"API is online: {is_online}")
        # you may also ask if the client was online the last time it tried to connect:
        last_online_state = govee.online
        # ping endpoint in Govee API (also uses no auth/api_key)
        ping_ms, err = await govee.ping()
        # get devices list - this is mandatory, you need to successfully get the devices first!
        devices, err = await govee.get_devices()
        # get states
        devices = (
            await govee.get_states()
        )  # yes, states returns the same object containing device and state info
        # once you have called get_devices() once, you can get this list from cache:
        cache_devices = govee.devices
        # or a specific device from cache
        cache_device = govee.device(
            devices[0].device)  # .device returns device-ID
        # turn a device on/off (using device-object or device-id works for all calls)
        success, err = await govee.turn_on(cache_device)
        success, err = await govee.turn_off(cache_device.device)
        # set brightness of a device (we scale all ranges to 0-254, Govee uses 0-100 sometimes)
        success, err = await govee.set_brightness(cache_device, 254)
        # set color temperature (2000-9000)
        success, err = await govee.set_color_temp(cache_device, 6000)
        # set color in RGB (each 0-255)
        red = 0
        green = 0
        blue = 255
        success, err = await govee.set_color(cache_device, (red, green, blue))

        ### rate limiting:
        # set requests left before the rate limiter stops us
        govee.rate_limit_on = 5  # 5 requests is the default
        current_rate_limit_on = govee.rate_limit_on
        # see also these properties:
        total = govee.rate_limit_total
        remaining = govee.rate_limit_remaining
        reset = govee.rate_limit_reset  # ... or more readable:
        reset_seconds = govee.rate_limit_reset_seconds

    ### without async content manager:
    govee = await Govee.create(api_key, learning_storage=your_learning_storage)
    ping_ms, err = await govee.ping()  # all commands as above
    # don't forget the mandatory get_devices!
    devices, err = await govee.get_devices()
    # let's turn off the light at the end
    success, err = await govee.turn_off(cache_device.device)
    await govee.close()
 async def get_devices():
     async with Govee(API_KEY) as govee:
         govee.rate_limit_on = 4
         assert govee.rate_limit_on == 4  # set did work
         # first run uses defaults, so ping returns immediatly
         start = time()
         _, err1 = await govee.get_devices()
         delay1 = start - time()
         # second run, doesn't rate limit either
         _, err2 = await govee.get_devices()
         delay2 = start - time()
         return delay1, err1, delay2, err2
async def foo(api_key):
    # this is for testing bug #72
    async with Govee(api_key) as govee:
        devices, err = await govee.get_devices()
        while True:
            for dev in devices:
                # configure each device to turn on before seting brightness
                dev.before_set_brightness_turn_on = True
                dev.learned_set_brightness_max = 100
                # turn and set bright
                success, err = await govee.set_brightness(dev, 254)
                print("set")
            await asyncio.sleep(5)
Exemple #9
0
async def validate_api_key(hass: core.HomeAssistant, user_input):
    """Validate the user input allows us to connect.

    Return info that you want to store in the config entry.
    """
    api_key = user_input[CONF_API_KEY]
    async with Govee(api_key, learning_storage=GoveeNoLearningStorage()) as hub:
        _, error = await hub.get_devices()
        if error:
            raise CannotConnect(error)

    # Return info that you want to store in the config entry.
    return user_input
Exemple #10
0
async def validate_input(hass: core.HomeAssistant, data):
    """Validate the user input allows us to connect.

    Return info that you want to store in the config entry.
    """
    api_key = data[CONF_API_KEY]
    async with Govee(api_key) as hub:
        _, error = await hub.get_devices()
        if error:
            raise CannotConnect(error)

    # Return info that you want to store in the config entry.
    return data
Exemple #11
0
async def validate_disabled_attribute_updates(hass: core.HomeAssistant, user_input):
    """Validate format of the ignore_device_attributes parameter string

    Return info that you want to store in the config entry.
    """
    disable_str = user_input[CONF_DISABLE_ATTRIBUTE_UPDATES]
    if disable_str:
        # we have something to check, connect without API key
        async with Govee("", learning_storage=GoveeNoLearningStorage()) as hub:
            # this will throw an GoveeError if something fails
            hub.ignore_device_attributes(disable_str)

    # Return info that you want to store in the config entry.
    return user_input
 async def get_devices():
     async with Govee(API_KEY) as govee:
         assert govee.rate_limit_on == 5
         assert govee.rate_limit_total == 100
         assert govee.rate_limit_reset == 0
         assert govee.rate_limit_remaining == 100
         # first run uses defaults, so ping returns immediatly
         _, err1 = await govee.get_devices()
         assert mock_sleep.call_count == 0
         assert govee.rate_limit_remaining == 5
         assert govee.rate_limit_reset == sleep_until
         # second run, rate limit sleeps until the second is over
         _, err2 = await govee.get_devices()
         assert mock_sleep.call_count == 1
         return err1, err2
Exemple #13
0
    async def some_light_commands(api_key: str,
                                  storage: GoveeAbstractLearningStorage):
        """We get the device list, set them to max brightness, sleep, get device state."""
        async with Govee(api_key, learning_storage=storage) as govee:
            devices, err = await govee.get_devices()

            # once setting the state > 100 we learn if we need to set in the range of 0-254 or 0-100
            for device in devices:
                success, err = await govee.set_brightness(device, 254)

            # we sleep to get a live status - client is blocking immediate status request after control
            # because they return invalid values. A calculated state is available before that.
            await asyncio.sleep(5)

            # once getting state we guess how to interpret the result.
            # if brightness reaches >100 one time we know we are in range of 0-254 instead of 0-100
            # some devices do not support state, in this case every state is calculated from known values
            await govee.get_states()
            print(f"See {storage._filename} for leaned configuration.")
 async def set_color():
     async with Govee(API_KEY) as govee:
         # inject a device for testing
         govee._devices = {DUMMY_DEVICE_H6163.device: DUMMY_DEVICE_H6163}
         return await govee.set_color(DUMMY_DEVICE_H6163.device, (42, 43, 44))
 async def getDevices():
     async with Govee(API_KEY) as govee:
         return await govee.get_devices()
 async def getDevices():
     async with Govee(API_KEY) as govee:
         result, err = await govee.get_devices()
         assert not err
         cache = govee.devices
         return result, cache
 async def getDevices():
     async with Govee("INVALIDAPI_KEY") as govee:
         return await govee.get_devices()
Exemple #18
0
async def test_globalOfflineIsOffConfig_off(mock_aiohttp, mock_never_lock):
    """
    Device is on, and going offline. Computed state is configured to be OFF when offline.
    config_offline_is_off=True
    """
    # arrange
    learning_storage = LearningStorage(copy.deepcopy(LEARNED_S100_G254))

    # act
    async with Govee(API_KEY, learning_storage=learning_storage) as govee:
        # request devices list
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                json={"data": {
                    "devices": [copy.deepcopy(JSON_DEVICE_H6163)]
                }},
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices",
            ))
        # call
        lamps, err = await govee.get_devices()
        # assert
        assert mock_aiohttp_responses.empty()
        assert not err
        assert len(lamps) == 1

        ### set global config_offline_is_off
        govee.config_offline_is_off = True

        # turn on
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                status=200,
                json={
                    "code": 200,
                    "message": "Success",
                    "data": {}
                },
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices/control" and
                kwargs["json"] == {
                    "cmd": {
                        "name": "turn",
                        "value": "on"
                    },
                    "device": "40:83:FF:FF:FF:FF:FF:FF",
                    "model": "H6163",
                },
            ))
        # call
        success, err = await govee.turn_on(DUMMY_DEVICE_H6163.device)
        # assert
        assert mock_aiohttp_responses.empty()
        assert success
        assert not err
        assert govee.device(DUMMY_DEVICE_H6163.device).power_state == True
        assert govee.device(DUMMY_DEVICE_H6163.device).online == True

        # get state - but device is offline
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                status=200,
                json=copy.deepcopy(JSON_DEVICE_STATE_OFFLINE),
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices/state" and kwargs[
                    "params"] == {
                        "device": "40:83:FF:FF:FF:FF:FF:FF",
                        "model": "H6163",
                    },
            ))
        # call
        await govee.get_states()
        # assert
        assert mock_aiohttp_responses.empty()
        assert success
        assert not err
        assert govee.device(DUMMY_DEVICE_H6163.device).power_state == False
        assert govee.device(DUMMY_DEVICE_H6163.device).online == False
 async def ping():
     async with Govee(API_KEY) as govee:
         return await govee.ping()
Exemple #20
0
async def test_autobrightness_set254_get100_get254(mock_aiohttp,
                                                   mock_never_lock):
    # arrange
    learning_storage = LearningStorage(copy.deepcopy(LEARNED_NOTHING))

    # act
    async with Govee(API_KEY, learning_storage=learning_storage) as govee:
        # request devices list
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                json={"data": {
                    "devices": [copy.deepcopy(JSON_DEVICE_H6163)]
                }},
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices",
            ))
        # call
        lamps, err = await govee.get_devices()
        # assert
        assert mock_aiohttp_responses.empty()
        assert not err
        assert len(lamps) == 1

        # set brightness to 142, which is OK for a 0-254 device
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                status=200,
                json={
                    "code": 200,
                    "message": "Success",
                    "data": {}
                },
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices/control" and
                kwargs["json"] == {
                    "cmd": {
                        "name": "brightness",
                        "value": 142
                    },
                    "device": "40:83:FF:FF:FF:FF:FF:FF",
                    "model": "H6163",
                },
            ))
        # call
        success, err = await govee.set_brightness(DUMMY_DEVICE_H6163.device,
                                                  142)
        # assert
        assert mock_aiohttp_responses.empty()
        assert success
        assert not err
        assert learning_storage.write_test_data == {
            DUMMY_DEVICE_H6163.device:
            GoveeLearnedInfo(
                set_brightness_max=254,  # this we lerned y setting brightness
                get_brightness_max=None,
            )
        }

        # get state
        # we get a state <= 100 (42 in this case), we assume get range is 0-100 and show a warning with instructions
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                status=200,
                json={
                    "data": {
                        "device":
                        "40:83:FF:FF:FF:FF:FF:FF",
                        "model":
                        "H6163",
                        "properties": [
                            {
                                "online": True
                            },
                            {
                                "powerState": "on"
                            },
                            {
                                "brightness": 42
                            },
                            {
                                "color": {
                                    "r": 0,
                                    "b": 0,
                                    "g": 0
                                }
                            },
                        ],
                    },
                    "message": "Success",
                    "code": 200,
                },
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices/state" and kwargs[
                    "params"] == {
                        "device": "40:83:FF:FF:FF:FF:FF:FF",
                        "model": "H6163"
                    },
            ))
        # call
        states = await govee.get_states()
        # assert
        assert mock_aiohttp_responses.empty()
        assert states[0].source == "api"
        assert states[0].brightness == 42 * 254 // 100
        assert learning_storage.write_test_data == {
            DUMMY_DEVICE_H6163.device:
            GoveeLearnedInfo(
                set_brightness_max=254,
                get_brightness_max=
                100,  # we assume this because we got no brightness state > 100
            )
        }

        # get state
        # we get a state > 100 (142 in this case), now we know the range is 0-254
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                status=200,
                json={
                    "data": {
                        "device":
                        "40:83:FF:FF:FF:FF:FF:FF",
                        "model":
                        "H6163",
                        "properties": [
                            {
                                "online": True
                            },
                            {
                                "powerState": "on"
                            },
                            {
                                "brightness": 142
                            },
                            {
                                "color": {
                                    "r": 0,
                                    "b": 0,
                                    "g": 0
                                }
                            },
                        ],
                    },
                    "message": "Success",
                    "code": 200,
                },
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices/state" and kwargs[
                    "params"] == {
                        "device": "40:83:FF:FF:FF:FF:FF:FF",
                        "model": "H6163"
                    },
            ))
        # call
        states = await govee.get_states()
        # assert
        assert mock_aiohttp_responses.empty()
        assert states[0].source == "api"
        assert states[0].brightness == 142
        assert learning_storage.write_test_data == {
            DUMMY_DEVICE_H6163.device:
            GoveeLearnedInfo(
                set_brightness_max=254,
                get_brightness_max=254,
            )
        }
Exemple #21
0
async def test_autobrightness_set100_get254(mock_aiohttp, mock_never_lock):
    # arrange
    learning_storage = LearningStorage(copy.deepcopy(LEARNED_NOTHING))

    # act
    async with Govee(API_KEY, learning_storage=learning_storage) as govee:
        # request devices list
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                json={"data": {
                    "devices": [copy.deepcopy(JSON_DEVICE_H6163)]
                }},
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices",
            ))
        # call
        lamps, err = await govee.get_devices()
        # assert
        assert mock_aiohttp_responses.empty()
        assert not err
        assert len(lamps) == 1

        # set brightness to 142, and fail because we set > 100
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                status=400,
                text="Unsupported Cmd Value",
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices/control" and
                kwargs["json"] == {
                    "cmd": {
                        "name": "brightness",
                        "value": 142
                    },
                    "device": "40:83:FF:FF:FF:FF:FF:FF",
                    "model": "H6163",
                },
            ))
        # then set brightness to 55 (142 * 100 // 254), with success
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                status=200,
                json={
                    "code": 200,
                    "message": "Success",
                    "data": {}
                },
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices/control" and
                kwargs["json"] == {
                    "cmd": {
                        "name": "brightness",
                        "value": 55
                    },
                    "device": "40:83:FF:FF:FF:FF:FF:FF",
                    "model": "H6163",
                },
            ))
        # call
        success, err = await govee.set_brightness(DUMMY_DEVICE_H6163.device,
                                                  142)
        # assert
        assert mock_aiohttp_responses.empty()
        assert success
        assert not err
        assert learning_storage.write_test_data == {
            DUMMY_DEVICE_H6163.device:
            GoveeLearnedInfo(
                set_brightness_max=100,  # this we lerned y setting brightness
                get_brightness_max=None,
            )
        }

        # get state
        # state returns a brightness of 142, we learn returning state is 0-254
        mock_aiohttp_responses.put(
            MockAiohttpResponse(
                status=200,
                json={
                    "data": {
                        "device":
                        "40:83:FF:FF:FF:FF:FF:FF",
                        "model":
                        "H6163",
                        "properties": [
                            {
                                "online": True
                            },
                            {
                                "powerState": "on"
                            },
                            {
                                "brightness": 142
                            },
                            {
                                "color": {
                                    "r": 0,
                                    "b": 0,
                                    "g": 0
                                }
                            },
                        ],
                    },
                    "message": "Success",
                    "code": 200,
                },
                check_kwargs=lambda kwargs: kwargs["url"] ==
                "https://developer-api.govee.com/v1/devices/state" and kwargs[
                    "params"] == {
                        "device": "40:83:FF:FF:FF:FF:FF:FF",
                        "model": "H6163"
                    },
            ))
        # call
        states = await govee.get_states()
        # assert
        assert mock_aiohttp_responses.empty()
        assert states[0].source == "api"
        assert states[0].brightness == 142
        assert learning_storage.write_test_data == {
            DUMMY_DEVICE_H6163.device:
            GoveeLearnedInfo(
                set_brightness_max=100,
                get_brightness_max=254,  # this we learned from brightness state
            )
        }
 async def turn_on():
     async with Govee(API_KEY) as govee:
         # inject a device for testing
         govee._devices = {DUMMY_DEVICE_H6163.device: DUMMY_DEVICE_H6163}
         return await govee.turn_on(DUMMY_DEVICE_H6163)
 async def turn_off():
     async with Govee(API_KEY) as govee:
         # inject a device for testing
         govee._devices = {DUMMY_DEVICE_H6163.device: DUMMY_DEVICE_H6163}
         # use device address here
         return await govee.turn_off(DUMMY_DEVICE_H6163.device)
 async def set_brightness():
     async with Govee(API_KEY) as govee:
         # inject a device for testing
         govee._devices = {DUMMY_DEVICE_H6163.device: DUMMY_DEVICE_H6163}
         return await govee.set_brightness(DUMMY_DEVICE_H6163, brightness)
 async def set_brightness():
     async with Govee(API_KEY) as govee:
         # inject a device for testing
         govee._devices = {DUMMY_DEVICE_H6163.device: DUMMY_DEVICE_H6163}
         success, err = await govee.set_brightness(DUMMY_DEVICE_H6163.device, 42)
         return success, err, govee.devices