Esempio n. 1
0
    async def delete(self, request) -> web.Response:
        """Delete a scene"""
        data = await request.json()

        scene_id = data.get("id")
        if scene_id is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "scene_id" was not provided',
            }
            return web.json_response(data=response, status=500)

        if scene_id not in self._ledfx.config["scenes"].keys():
            response = {
                "status": "failed",
                "reason": "Scene {} does not exist".format(scene_id),
            }
            return web.json_response(data=response, status=500)

        # Delete the scene from configuration
        del self._ledfx.config["scenes"][scene_id]

        # Save the config
        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        response = {"status": "success"}
        return web.json_response(data=response, status=200)
Esempio n. 2
0
    async def delete(self, request) -> web.Response:
        """Delete an integration, erasing all its configuration
        NOTE: THIS DOES NOT TURN OFF THE INTEGRATION, IT DELETES IT!
        USE PUT TO TOGGLE!"""
        data = await request.json()
        integration_id = data.get("id")
        if integration_id is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "id" was not provided',
            }
            return web.json_response(data=response, status=500)

        integration = self._ledfx.integrations.get(integration_id)
        if integration is None:
            response = {"not found": 404}
            return web.Response(text=json.dumps(response), status=404)

        self._ledfx.integrations.destroy(integration_id)

        self._ledfx.config["integrations"] = [
            integration for integration in self._ledfx.config["integrations"]
            if integration["id"] != integration_id
        ]

        # Save the config
        save_config(config=self._ledfx.config,
                    config_dir=self._ledfx.config_dir)

        response = {"status": "success"}
        return web.json_response(data=response, status=200)
Esempio n. 3
0
    async def post(self, request) -> web.Response:
        data = await request.json()

        virtuals = data.get("virtuals")
        if virtuals is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "virtuals" was not provided',
            }
            return web.json_response(data=response, status=500)

        virtuals_list = virtuals["list"]

        _LOGGER.info(f"Adding virtuals list to config: {virtuals_list}")

        # Update and save the configuration
        self._ledfx.config["virtuals"] = virtuals_list

        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        response = {
            "status": "success",
        }

        return web.json_response(data=response, status=200)
Esempio n. 4
0
    async def put(self, request) -> web.Response:
        """Set graphics quality setting"""
        data = await request.json()
        graphics_quality = data.get("graphics_quality")

        if graphics_quality is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "graphics_quality" was not provided',
            }
            return web.json_response(data=response, status=500)

        if graphics_quality not in ["low", "medium", "high", "ultra"]:
            response = {
                "status": "failed",
                "reason": "Invalid graphics_quality [{}]".format(
                    graphics_quality
                ),
            }
            return web.json_response(data=response, status=500)

        # Update and save config
        self._ledfx.config["graphics_quality"] = graphics_quality

        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        # reopen all websockets with new graphics settings

        response = {"status": "success"}
        return web.json_response(data=response, status=200)
Esempio n. 5
0
    async def put(self, request) -> web.Response:
        """Set audio device to use as input"""
        data = await request.json()
        index = data.get("index")

        info = self._audio.get_host_api_info_by_index(0)
        if index is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "index" was not provided',
            }
            return web.json_response(data=response, status=500)

        if index not in range(0, info.get("deviceCount")):
            response = {
                "status": "failed",
                "reason": "Invalid device index [{}]".format(index),
            }
            return web.json_response(data=response, status=500)

        # Update and save config
        new_config = self._ledfx.config.get("audio", {})
        new_config["device_index"] = int(index)
        self._ledfx.config["audio"] = new_config

        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        if self._ledfx.audio:
            self._ledfx.audio.update_config(new_config)

        response = {"status": "success"}
        return web.json_response(data=response, status=200)
Esempio n. 6
0
    async def delete(self, request) -> web.Response:
        """Delete a scene"""
        data = await request.json()

        scene_id = data.get('id')
        if scene_id is None:
            response = {
                'status': 'failed',
                'reason': 'Required attribute "scene_id" was not provided'
            }
            return web.json_response(data=response, status=500)

        if not scene_id in self._ledfx.config['scenes'].keys():
            response = {
                'status': 'failed',
                'reason': 'Scene {} does not exist'.format(scene_id)
            }
            return web.json_response(data=response, status=500)

        # Delete the scene from configuration
        del self._ledfx.config['scenes'][scene_id]

        # Save the config
        save_config(config=self._ledfx.config,
                    config_dir=self._ledfx.config_dir)

        response = {'status': 'success'}
        return web.json_response(data=response, status=200)
Esempio n. 7
0
    async def delete(self, request) -> web.Response:
        """Delete a preset"""
        data = await request.json()

        preset_id = data.get('id')
        if preset_id is None:
            response = {
                'status': 'failed',
                'reason': 'Required attribute "preset_id" was not provided'
            }
            return web.Response(text=json.dumps(response), status=500)

        if not preset_id in self._ledfx.config['presets'].keys():
            response = {
                'status': 'failed',
                'reason': 'Preset {} does not exist'.format(preset_id)
            }
            return web.Response(text=json.dumps(response), status=500)

        # Delete the preset from configuration
        del self._ledfx.config['presets'][preset_id]

        # Save the config
        save_config(config=self._ledfx.config,
                    config_dir=self._ledfx.config_dir)

        response = {'status': 'success'}
        return web.Response(text=json.dumps(response), status=200)
Esempio n. 8
0
    async def put(self, device_id, request) -> web.Response:
        device = self._ledfx.devices.get(device_id)
        if device is None:
            response = {'not found': 404}
            return web.Response(text=json.dumps(response), status=404)

        data = await request.json()
        device_config = data.get('config')
        if device_config is None:
            response = {
                'status': 'failed',
                'reason': 'Required attribute "config" was not provided'
            }
            return web.Response(text=json.dumps(response), status=500)

        # TODO: Support dynamic device configuration updates. For now
        # remove the device and re-create it
        _LOGGER.info(("Updating device {} with config {}").format(
            device_id, device_config))
        self._ledfx.devices.destroy(device_id)
        device = self._ledfx.devices.create(config=device_config,
                                            id=device_id,
                                            name=device_config.get('type'))

        # Update and save the configuration
        for device in self._ledfx.config['devices']:
            if (device['id'] == device_id):
                device['config'] = device_config
                break
        save_config(config=self._ledfx.config,
                    config_dir=self._ledfx.config_dir)

        response = {'status': 'success'}
        return web.Response(text=json.dumps(response), status=500)
Esempio n. 9
0
    async def put(self, request) -> web.Response:
        """Set audio device to use as input. Requires restart for changes to take effect"""
        data = await request.json()
        index = data.get('index')

        info = self._audio.get_host_api_info_by_index(0)
        if index is None:
            response = {
                'status': 'failed',
                'reason': 'Required attribute "index" was not provided'
            }
            return web.Response(text=json.dumps(response), status=500)

        if index not in range(0, info.get('deviceCount')):
            response = {
                'status': 'failed',
                'reason': 'Invalid device index [{}]'.format(index)
            }
            return web.Response(text=json.dumps(response), status=500)

        # Update and save config
        new_config = self._ledfx.config.get('audio', {})
        new_config['device_index'] = int(index)
        self._ledfx.config['audio'] = new_config

        save_config(config=self._ledfx.config,
                    config_dir=self._ledfx.config_dir)

        if self._ledfx.audio:
            self._ledfx.audio.update_config(new_config)

        response = {'status': 'success'}
        return web.Response(text=json.dumps(response), status=200)
Esempio n. 10
0
    async def async_stop(self, exit_code=0):
        if not self.loop:
            return

        print('Stopping LedFx.')

        # Fire a shutdown event and flush the loop
        self.events.fire_event(LedFxShutdownEvent())
        await asyncio.sleep(0, loop=self.loop)

        await self.http.stop()

        # Cancel all the remaining task and wait
        tasks = [task for task in asyncio.Task.all_tasks() if task is not
             asyncio.tasks.Task.current_task()] 
        list(map(lambda task: task.cancel(), tasks))
        results = await asyncio.gather(*tasks, return_exceptions=True)

        # Save the configuration before shutting down
        save_config(config=self.config, config_dir=self.config_dir)

        await self.flush_loop()
        self.executor.shutdown()
        self.exit_code = exit_code
        self.loop.stop()
Esempio n. 11
0
    async def delete(self, integration_id, request) -> web.Response:
        """ Delete a Spotify song trigger """
        integration = self._ledfx.integrations.get(integration_id)
        if (integration is None) or (integration.type != "spotify"):
            response = {"not found": 404}
            return web.json_response(data=response, status=404)

        data = await request.json()
        trigger_id = data.get("trigger_id")

        if trigger_id is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "trigger_id" was not provided',
            }
            return web.json_response(data=response, status=500)

        integration.delete_trigger(trigger_id)

        # Update and save the config
        save_config(config=self._ledfx.config,
                    config_dir=self._ledfx.config_dir)

        response = {"status": "success"}
        return web.json_response(data=response, status=200)
Esempio n. 12
0
    async def post(self, integration_id, request) -> web.Response:
        """Add a new QLC event listener or update an existing one"""
        integration = self._ledfx.integrations.get(integration_id)
        if (integration is None) or (integration.type != "qlc"):
            response = {"not found": 404}
            return web.json_response(data=response, status=404)

        data = await request.json()
        event_type = data.get("event_type")
        event_filter = data.get("event_filter")
        qlc_payload = data.get("qlc_payload")

        if event_type is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "event_type" was not provided',
            }
            return web.json_response(data=response, status=500)

        if event_filter is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "event_filter" was not provided',
            }
            return web.json_response(data=response, status=500)

        if type(event_filter) is not dict:
            response = {
                "status":
                "failed",
                "reason":
                f'Invalid filter "{event_filter}", should be dictionary eg. {{ "scene_name" : "my scene" }} ',
            }
            return web.json_response(data=response, status=500)

        if qlc_payload is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "qlc_payload" was not provided',
            }
            return web.json_response(data=response, status=500)

        # Create a link between ledfx event and sending the payload
        integration.create_event(event_type, event_filter, True, qlc_payload)

        # Update and save the configuration
        for _integration in self._ledfx.config["integrations"]:
            if _integration["id"] == integration_id:
                _integration["data"] = integration.data
                break
        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        response = {"status": "success"}
        return web.json_response(data=response, status=200)
Esempio n. 13
0
    async def post(self, request) -> web.Response:
        data = await request.json()

        device_config = data.get("config")
        if device_config is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "config" was not provided',
            }
            return web.json_response(data=response, status=500)

        device_type = data.get("type")
        if device_type is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "type" was not provided',
            }
            return web.json_response(data=response, status=500)

        device_id = generate_id(device_config.get("name"))
        # Remove the device it if already exist?

        # Create the device
        _LOGGER.info(
            "Adding device of type {} with config {}".format(
                device_type, device_config
            )
        )
        device = self._ledfx.devices.create(
            id=device_id,
            type=device_type,
            config=device_config,
            ledfx=self._ledfx,
        )

        # Update and save the configuration
        self._ledfx.config["devices"].append(
            {
                "id": device.id,
                "type": device.type,
                "config": device.config,
            }
        )
        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        response = {
            "status": "success",
            "device": {
                "type": device.type,
                "config": device.config,
                "id": device.id,
            },
        }
        return web.json_response(data=response, status=200)
Esempio n. 14
0
    async def put(self, integration_id, request) -> web.Response:
        """Toggle a QLC event listener"""
        integration = self._ledfx.integrations.get(integration_id)
        if (integration is None) or (integration.type != "qlc"):
            response = {"not found": 404}
            return web.json_response(data=response, status=404)

        data = await request.json()
        event_type = data.get("event_type")
        event_filter = data.get("event_filter")

        if event_type is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "event_type" was not provided',
            }
            return web.json_response(data=response, status=500)

        if event_filter is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "event_filter" was not provided',
            }
            return web.json_response(data=response, status=500)

        if type(event_filter) is not dict:
            response = {
                "status":
                "failed",
                "reason":
                f'Invalid filter "{event_filter}", should be dictionary eg. {{ "scene_name" : "my scene" }} ',
            }
            return web.json_response(data=response, status=500)

        # toggle the event listener
        if not integration.toggle_event(event_type, event_filter):
            response = {
                "status":
                "failed",
                "reason":
                f"Could not find event with type {event_type} and filter {event_filter}",
            }
            return web.json_response(data=response, status=500)

        # Save the configuration (integration will handle modifying "data")
        for _integration in self._ledfx.config["integrations"]:
            if _integration["id"] == integration_id:
                _integration["data"] = integration.data
                break
        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        response = {"status": "success"}
        return web.json_response(data=response, status=200)
Esempio n. 15
0
    def add_service(self, zeroconf_obj, type, name):
        # DMX universe_size
        c = 510
        d = 512
        info = zeroconf_obj.get_service_info(type, name)

        if info:
            address = socket.inet_ntoa(info.addresses[0])
            url = f"http://{address}/json/info"
            # For each WLED device found, based on the WLED IPv4 address, do a GET requests
            response = requests.get(url)
            b = response.json()
            # For each WLED json response, format from WLED payload to LedFx payload.
            # Note, set universe_size to 510 if LED 170 or less, If you have more than 170 LED, set universe_size to 510
            wledled = b["leds"]
            wledname = b["name"]
            wledcount = wledled["count"]
            
            if wledcount > 170:
                unisize = c
            else:
                unisize = d

            device_id = generate_id(wledname)
            device_type = "e131"
            device_config = {
                "max_brightness": 1,
                "refresh_rate": 60,
                "universe": 1,
                "universe_size": unisize,
                "name": wledname,
                "pixel_count": wledcount,
                "ip_address": address
            }

            # Check this device doesn't share IP with any other device
            for device in self._ledfx.devices.values():
                if device.config["ip_address"] == address:
                    return

            # Create the device
            _LOGGER.info("Adding device of type {} with config {}".format(device_type, device_config))
            device = self._ledfx.devices.create(
                id = device_id,
                type = device_type,
                config = device_config,
                ledfx = self._ledfx)

            # Update and save the configuration
            self._ledfx.config['devices'].append({'id': device.id, 'type': device.type, 'config': device.config })
            save_config(
                config = self._ledfx.config, 
                config_dir = self._ledfx.config_dir)
Esempio n. 16
0
    async def put(self, request) -> web.Response:
        """Set audio device to use as input"""
        data = await request.json()
        index = data.get("index")

        if self._audio is None:
            self._audio = pyaudio.PyAudio()

        if index is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "index" was not provided',
            }
            return web.json_response(data=response, status=500)

        try:
            deviceInfo = self._audio.get_device_info_by_index(index)
        except OSError:
            response = {
                "status": "failed",
                "reason": "Invalid device index [{}]".format(index),
            }
            return web.json_response(data=response, status=500)

        # Update and save config
        new_config = self._ledfx.config.get("audio", {})
        new_config["host_api"] = deviceInfo["hostApi"]
        new_config["device_name"] = deviceInfo["name"]
        new_config["device_index"] = int(index)

        if (deviceInfo["defaultSampleRate"]) > 44000.0:
            # if the sample rate is larger then 48000, we need to increase
            # the fft_size and mic_rate otherwise the pipline will not start
            new_config["mic_rate"] = mic = int(deviceInfo["defaultSampleRate"])
            min_size = int((mic / 44000.0) * 1024)
            new_config["fft_size"] = 1 << (min_size - 1).bit_length()

        self._ledfx.config["audio"] = new_config

        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        if self._ledfx.audio:
            self._ledfx.audio.update_config(new_config)

        response = {"status": "success"}
        return web.json_response(data=response, status=200)
Esempio n. 17
0
    async def post(self, request) -> web.Response:
        data = await request.json()

        device_config = data.get('config')
        if device_config is None:
            response = {
                'status': 'failed',
                'reason': 'Required attribute "config" was not provided'
            }
            return web.Response(text=json.dumps(response), status=500)

        device_type = data.get('type')
        if device_type is None:
            response = {
                'status': 'failed',
                'reason': 'Required attribute "type" was not provided'
            }
            return web.Response(text=json.dumps(response), status=500)

        device_id = generate_id(device_config.get('name'))
        # Remove the device it if already exist?

        # Create the device
        _LOGGER.info("Adding device of type {} with config {}".format(
            device_type, device_config))
        device = self._ledfx.devices.create(id=device_id,
                                            type=device_type,
                                            config=device_config,
                                            ledfx=self._ledfx)

        # Update and save the configuration
        self._ledfx._config['devices'].append({
            'id': device.id,
            'type': device.type,
            'config': device.config
        })
        save_config(config=self._ledfx._config,
                    config_dir=self._ledfx._config_dir)

        response = {
            'status': 'success',
            'device': {
                'type': device.type,
                'config': device.config,
                'id': device.id
            }
        }
        return web.Response(text=json.dumps(response), status=200)
Esempio n. 18
0
    async def delete(self, device_id) -> web.Response:
        device = self._ledfx.devices.get(device_id)
        if device is None:
            response = { 'not found': 404 }
            return web.Response(text=json.dumps(response), status=404)

        self._ledfx.devices.destroy(device_id)

        # Update and save the configuration
        self._ledfx._config['devices'] = [device for device in self._ledfx._config['devices'] if device['id'] != device_id]
        save_config(
            config = self._ledfx._config, 
            config_dir = self._ledfx._config_dir)

        response = { 'status' : 'success' }
        return web.Response(text=json.dumps(response), status=200)
Esempio n. 19
0
    async def post(self, device_id, request) -> web.Response:
        device = self._ledfx.devices.get(device_id)
        if device is None:
            response = {"not found": 404}
            return web.json_response(data=response, status=404)

        data = await request.json()
        effect_type = data.get("type")
        if effect_type is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "type" was not provided',
            }
            return web.json_response(data=response, status=500)

        effect_config = data.get("config")
        if effect_config is None:
            effect_config = {}

        # Create the effect and add it to the device
        effect = self._ledfx.effects.create(ledfx=self._ledfx,
                                            type=effect_type,
                                            config=effect_config)
        device.set_effect(effect)

        # Update and save the configuration
        for device in self._ledfx.config["devices"]:
            if device["id"] == device_id:
                # if not ('effect' in device):
                device["effect"] = {}
                device["effect"]["type"] = effect_type
                device["effect"]["config"] = effect_config
                break
        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        effect_response = {}
        effect_response["config"] = effect.config
        effect_response["name"] = effect.name
        effect_response["type"] = effect.type

        response = {"status": "success", "effect": effect_response}
        return web.json_response(data=response, status=200)
Esempio n. 20
0
    async def delete(self, device_id) -> web.Response:
        device = self._ledfx.devices.get(device_id)
        if device is None:
            response = {'not found': 404}
            return web.Response(text=json.dumps(response), status=404)

        # Clear the effect
        device.clear_effect()

        for device in self._ledfx.config['devices']:
            if (device['id'] == device_id):
                del device['effect']
                break
        save_config(config=self._ledfx.config,
                    config_dir=self._ledfx.config_dir)

        response = {'status': 'success', 'effect': {}}
        return web.Response(text=json.dumps(response), status=200)
Esempio n. 21
0
    async def post(self, device_id, request) -> web.Response:
        device = self._ledfx.devices.get(device_id)
        if device is None:
            response = {'not found': 404}
            return web.Response(text=json.dumps(response), status=404)

        data = await request.json()
        effect_type = data.get('type')
        if effect_type is None:
            response = {
                'status': 'failed',
                'reason': 'Required attribute "type" was not provided'
            }
            return web.Response(text=json.dumps(response), status=500)

        effect_config = data.get('config')
        if effect_config is None:
            effect_config = {}

        # Create the effect and add it to the device
        effect = self._ledfx.effects.create(ledfx=self._ledfx,
                                            type=effect_type,
                                            config=effect_config)
        device.set_effect(effect)

        # Update and save the configuration
        for device in self._ledfx.config['devices']:
            if (device['id'] == device_id):
                #if not ('effect' in device):
                device['effect'] = {}
                device['effect']['type'] = effect_type
                device['effect']['config'] = effect_config
                break
        save_config(config=self._ledfx.config,
                    config_dir=self._ledfx.config_dir)

        effect_response = {}
        effect_response['config'] = effect.config
        effect_response['name'] = effect.name
        effect_response['type'] = effect.type

        response = {'status': 'success', 'effect': effect_response}
        return web.Response(text=json.dumps(response), status=200)
Esempio n. 22
0
    async def post(self, integration_id, request) -> web.Response:
        """Add Spotify song trigger"""
        integration = self._ledfx.integrations.get(integration_id)
        if (integration is None) or (integration.type != "spotify"):
            response = {"not found": 404}
            return web.json_response(data=response, status=404)

        data = await request.json()
        scene_id = data.get("scene_id")
        song_id = data.get("song_id")
        song_name = data.get("song_name")
        song_position = data.get("song_position")

        scene_id = data.get("id")
        if scene_id is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "scene_id" was not provided',
            }
            return web.json_response(data=response, status=500)

        if scene_id not in self._ledfx.config["scenes"].keys():
            response = {
                "status": "failed",
                "reason": "Scene {} does not exist".format(scene_id),
            }
            return web.json_response(data=response, status=500)

        if song_id is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "song_id" was not provided',
            }
            return web.json_response(data=response, status=500)

        integration.add_trigger(scene_id, song_id, song_name, song_position)

        save_config(
            config=self._ledfx.config, config_dir=self._ledfx.config_dir
        )

        response = {"status": "success"}
        return web.json_response(data=response, status=200)
Esempio n. 23
0
    async def post(self, request) -> web.Response:
        """Save current effects of devices as a scene"""
        data = await request.json()

        scene_name = data.get("name")
        if scene_name is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "scene_name" was not provided',
            }
            return web.json_response(data=response, status=500)

        scene_id = generate_id(scene_name)

        scene_config = {}
        scene_config["name"] = scene_name
        scene_config["devices"] = {}
        for device in self._ledfx.devices.values():
            effect = {}
            if device.active_effect:
                effect["type"] = device.active_effect.type
                effect["config"] = device.active_effect.config
                # effect['name'] = device.active_effect.name
            scene_config["devices"][device.id] = effect

        # Update the scene if it already exists, else create it
        self._ledfx.config["scenes"][scene_id] = scene_config

        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        response = {
            "status": "success",
            "scene": {
                "id": scene_id,
                "config": scene_config
            },
        }
        return web.json_response(data=response, status=200)
Esempio n. 24
0
    async def delete(self, device_id) -> web.Response:
        device = self._ledfx.devices.get(device_id)
        if device is None:
            response = {"not found": 404}
            return web.json_response(data=response, status=404)

        # Clear the effect
        device.clear_effect()

        for device in self._ledfx.config["devices"]:
            if device["id"] == device_id:
                if "effect" in device:
                    del device["effect"]
                    break
        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        response = {"status": "success", "effect": {}}
        return web.json_response(data=response, status=200)
Esempio n. 25
0
    async def post(self, request) -> web.Response:
        """Save current effects of devices as a scene"""
        data = await request.json()

        scene_name = data.get('name')
        if scene_name is None:
            response = {
                'status': 'failed',
                'reason': 'Required attribute "scene_name" was not provided'
            }
            return web.json_response(data=response, status=500)

        scene_id = generate_id(scene_name)

        scene_config = {}
        scene_config['name'] = scene_name
        scene_config['devices'] = {}
        for device in self._ledfx.devices.values():
            effect = {}
            if device.active_effect:
                effect['type'] = device.active_effect.type
                effect['config'] = device.active_effect.config
                #effect['name'] = device.active_effect.name
            scene_config['devices'][device.id] = effect

        # Update the scene if it already exists, else create it
        self._ledfx.config['scenes'][scene_id] = scene_config

        save_config(config=self._ledfx.config,
                    config_dir=self._ledfx.config_dir)

        response = {
            'status': 'success',
            'scene': {
                'id': scene_id,
                'config': scene_config
            }
        }
        return web.json_response(data=response, status=200)
Esempio n. 26
0
    async def post(self, request) -> web.Response:
        """Save current effects of devices as a preset"""
        data = await request.json()

        preset_name = data.get('name')
        if preset_name is None:
            response = {
                'status': 'failed',
                'reason': 'Required attribute "preset_name" was not provided'
            }
            return web.Response(text=json.dumps(response), status=500)

        preset_id = generate_id(preset_name)

        preset_config = {}
        preset_config['name'] = preset_name
        preset_config['devices'] = {}
        for device in self._ledfx.devices.values():
            effect = {}
            if device.active_effect:
                effect['type'] = device.active_effect.type
                effect['config'] = device.active_effect.config
                #effect['name'] = device.active_effect.name
            preset_config['devices'][device.id] = effect

        # Update the preset if it already exists, else create it
        self._ledfx.config['presets'][preset_id] = preset_config

        save_config(config=self._ledfx.config,
                    config_dir=self._ledfx.config_dir)

        response = {
            'status': 'success',
            'preset': {
                'id': preset_id,
                'config': preset_config
            }
        }
        return web.Response(text=json.dumps(response), status=200)
Esempio n. 27
0
    async def put(self, request) -> web.Response:
        """Toggle an integration on or off"""
        data = await request.json()
        integration_id = data.get("id")
        if integration_id is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "id" was not provided',
            }
            return web.json_response(data=response, status=500)

        integration = self._ledfx.integrations.get(integration_id)
        if integration is None:
            response = {"not found": 404}
            return web.Response(text=json.dumps(response), status=404)

        # Toggle the integration
        active = integration.active

        if not active:
            await integration.activate()
        else:
            await integration.deactivate()

        # Update and save the configuration
        for _integration in self._ledfx.config["integrations"]:
            if _integration["id"] == integration.id:
                _integration["active"] = not active
                break
        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        response = {"status": "success"}
        return web.json_response(data=response, status=200)
Esempio n. 28
0
    async def put(self, request) -> web.Response:
        """Activate a preset"""
        data = await request.json()

        action = data.get('action')
        if action is None:
            response = {
                'status': 'failed',
                'reason': 'Required attribute "action" was not provided'
            }
            return web.Response(text=json.dumps(response), status=500)

        if action not in ['activate', 'rename']:
            response = {
                'status': 'failed',
                'reason': 'Invalid action "{}"'.format(action)
            }
            return web.Response(text=json.dumps(response), status=500)

        preset_id = data.get('id')
        if preset_id is None:
            response = {
                'status': 'failed',
                'reason': 'Required attribute "preset_id" was not provided'
            }
            return web.Response(text=json.dumps(response), status=500)

        if not preset_id in self._ledfx.config['presets'].keys():
            response = {
                'status': 'failed',
                'reason': 'Preset "{}" does not exist'.format(preset_id)
            }
            return web.Response(text=json.dumps(response), status=500)

        preset = self._ledfx.config['presets'][preset_id]

        if action == "activate":
            for device in self._ledfx.devices.values():
                # Check device is in preset, make no changes if it isn't
                if not device.id in preset['devices'].keys():
                    _LOGGER.info(
                        ('Device with id {} has no data in preset {}').format(
                            device.id, preset_id))
                    continue

                # Set effect of device to that saved in the preset,
                # clear active effect of device if no effect in preset
                if preset['devices'][device.id]:
                    # Create the effect and add it to the device
                    effect = self._ledfx.effects.create(
                        ledfx=self._ledfx,
                        type=preset['devices'][device.id]['type'],
                        config=preset['devices'][device.id]['config'])
                    device.set_effect(effect)
                else:
                    device.clear_effect()

        elif action == "rename":
            name = data.get('name')
            if name is None:
                response = {
                    'status': 'failed',
                    'reason': 'Required attribute "name" was not provided'
                }
                return web.Response(text=json.dumps(response), status=500)

            # Update and save config
            self._ledfx.config['presets'][preset_id]['name'] = name
            save_config(config=self._ledfx.config,
                        config_dir=self._ledfx.config_dir)

        response = {'status': 'success'}
        return web.Response(text=json.dumps(response), status=200)
Esempio n. 29
0
    async def post(self, request) -> web.Response:
        """Create a new integration, or update an existing one"""
        data = await request.json()

        integration_config = data.get("config")
        if integration_config is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "config" was not provided',
            }
            return web.json_response(data=response, status=500)

        integration_type = data.get("type")
        if integration_type is None:
            response = {
                "status": "failed",
                "reason": 'Required attribute "type" was not provided',
            }
            return web.json_response(data=response, status=500)

        integration_id = data.get("id")
        new = not bool(integration_id)
        if integration_id is None:
            # Create new integration if no id is given
            integration_id = generate_id(integration_config.get("name"))
            _LOGGER.info(("Creating {} integration with config {}").format(
                integration_type, integration_config))
        else:
            # Update existing integration if valid id is given
            existing_integration = self._ledfx.integrations.get(integration_id)

            if existing_integration is None:
                response = {
                    "status": "failed",
                    "reason":
                    f"Integration with id {integration_id} not found",
                }
                return web.json_response(data=response, status=500)

            _LOGGER.info(
                ("Updating {} integration '{}' with config {}").format(
                    integration_type, integration_id, integration_config))

            self._ledfx.integrations.destroy(integration_id)

        integration = self._ledfx.integrations.create(
            id=integration_id,
            type=integration_type,
            active=True,
            config=integration_config,
            data=None,
            ledfx=self._ledfx,
        )

        # Update and save the configuration
        if new:
            self._ledfx.config["integrations"].append({
                "id":
                integration.id,
                "type":
                integration.type,
                "active":
                integration.active,
                "data":
                integration.data,
                "config":
                integration.config,
            })
        else:
            for integration in self._ledfx.config["integrations"]:
                if integration["id"] == integration_id:
                    integration["config"] = integration_config
                    break
                    # Update and save the configuration

        save_config(
            config=self._ledfx.config,
            config_dir=self._ledfx.config_dir,
        )

        response = {"status": "success"}
        return web.json_response(data=response, status=200)
Esempio n. 30
0
    async def put(self, device_id, request) -> web.Response:
        """Update the config of the active effect of a device"""
        device = self._ledfx.devices.get(device_id)
        if device is None:
            response = { 'not found': 404 }
            return web.json_response(data=response, status=404)

        if not device.active_effect:
            response = { 'status' : 'failed', 'reason': 'Device {} has no active effect to update config'.format(device_id) }
            return web.json_response(data=response, status=500)

        data = await request.json()
        effect_config = data.get('config')
        if effect_config is None:
            response = { 'status' : 'failed', 'reason': 'Required attribute "config" was not provided' }
            return web.json_response(data=response, status=500)

        if effect_config == "RANDOMIZE":
            # Parse and break down schema for effect, in order to generate acceptable random values
            effect_config = {}
            effect_type = device.active_effect.type
            effect = self._ledfx.effects.get_class(effect_type)
            schema = effect.schema().schema
            for setting in schema.keys():
                # Booleans
                if schema[setting] is bool:
                    val = random.choice([True, False])
                # Lists
                elif type(schema[setting]) is vol.validators.In:
                    val = random.choice(schema[setting].container)
                # All (assuming coerce(float/int), range(min,max))
                # NOTE: vol.coerce(float/int) does not give enough info for a random value to be generated!
                # *** All effects should give a range! ***
                # This is also important for when sliders will be added, slider needs a start and stop
                elif type(schema[setting]) is vol.validators.All:
                    for validator in schema[setting].validators:
                        if type(validator) is vol.validators.Coerce:
                            coerce_type = validator.type
                        elif type(validator) is vol.validators.Range:
                            lower = validator.min
                            upper = validator.max
                    if coerce_type is float:
                        val = random.uniform(lower, upper)
                    elif coerce_type is int:
                        val = random.randint(lower, upper)
                effect_config[setting.schema] = val

        # Create the effect and add it to the device
        effect = self._ledfx.effects.create(
            ledfx = self._ledfx,
            type = effect_type,
            config = effect_config)
        device.set_effect(effect)

        # Update and save the configuration
        for device in self._ledfx.config['devices']:
            if (device['id'] == device_id):
                #if not ('effect' in device):
                device['effect'] = {}
                device['effect']['type'] = effect_type
                device['effect']['config'] = effect_config
                break
        save_config(
            config = self._ledfx.config, 
            config_dir = self._ledfx.config_dir)

        effect_response = {}
        effect_response['config'] = effect.config
        effect_response['name'] = effect.name
        effect_response['type'] = effect.type

        response = { 'status' : 'success', 'effect' : effect_response}
        return web.json_response(data=response, status=200)