diff --git a/front/src/routes/scene/edit-scene/actions/BlinkLightParams.jsx b/front/src/routes/scene/edit-scene/actions/BlinkLightParams.jsx index 747b285882..d0190ad4b0 100644 --- a/front/src/routes/scene/edit-scene/actions/BlinkLightParams.jsx +++ b/front/src/routes/scene/edit-scene/actions/BlinkLightParams.jsx @@ -6,14 +6,20 @@ import Select from 'react-select'; class BlinkLight extends Component { getOptions = async () => { try { - const devices = await this.props.httpClient.get('/api/v1/device', { + const lightDevices = await this.props.httpClient.get('/api/v1/device', { device_feature_category: 'light', device_feature_type: 'binary' }); - const deviceOptions = devices.map(device => ({ - value: device.selector, - label: device.name - })); + const switchDevices = await this.props.httpClient.get('/api/v1/device', { + device_feature_category: 'switch', + device_feature_type: 'binary' + }); + const deviceOptions = [...lightDevices, ...switchDevices] + .map(device => ({ + value: device.selector, + label: device.name + })) + .sort((d1, d2) => d1.label.localeCompare(d2.label)); await this.setState({ deviceOptions }); this.refreshSelectedOptions(this.props); return deviceOptions; @@ -23,8 +29,8 @@ class BlinkLight extends Component { }; handleChange = selectedOptions => { if (selectedOptions) { - const lights = selectedOptions.map(selectedOption => selectedOption.value); - this.props.updateActionProperty(this.props.columnIndex, this.props.index, 'devices', lights); + const devices = selectedOptions.map(selectedOption => selectedOption.value); + this.props.updateActionProperty(this.props.columnIndex, this.props.index, 'devices', devices); } else { this.props.updateActionProperty(this.props.columnIndex, this.props.index, 'devices', []); } @@ -39,13 +45,14 @@ class BlinkLight extends Component { refreshSelectedOptions = nextProps => { const selectedOptions = []; if (nextProps.action.devices && this.state.deviceOptions) { - nextProps.action.devices.forEach(light => { - const deviceOption = this.state.deviceOptions.find(deviceOption => deviceOption.value === light); + nextProps.action.devices.forEach(device => { + const deviceOption = this.state.deviceOptions.find(deviceOption => deviceOption.value === device); if (deviceOption) { selectedOptions.push(deviceOption); } }); } + selectedOptions.sort((d1, d2) => d1.label.localeCompare(d2.label)); this.setState({ selectedOptions }); }; constructor(props) { diff --git a/server/lib/scene/scene.actions.js b/server/lib/scene/scene.actions.js index 28352e4650..64c988a7f9 100644 --- a/server/lib/scene/scene.actions.js +++ b/server/lib/scene/scene.actions.js @@ -131,11 +131,18 @@ const actionsFunc = { await Promise.map(action.devices, async (deviceSelector) => { try { const device = self.stateManager.get('device', deviceSelector); - const deviceFeature = getDeviceFeature( + let deviceFeature = getDeviceFeature( device, DEVICE_FEATURE_CATEGORIES.LIGHT, DEVICE_FEATURE_TYPES.LIGHT.BINARY, ); + if (!deviceFeature) { + deviceFeature = getDeviceFeature( + device, + DEVICE_FEATURE_CATEGORIES.SWITCH, + DEVICE_FEATURE_TYPES.SWITCH.BINARY, + ); + } const oldValue = deviceFeature.last_value; let newValue = 0; /* eslint-disable no-await-in-loop */ diff --git a/server/test/lib/scene/actions/scene.action.blinkLights.test.js b/server/test/lib/scene/actions/scene.action.blinkDevices.test.js similarity index 83% rename from server/test/lib/scene/actions/scene.action.blinkLights.test.js rename to server/test/lib/scene/actions/scene.action.blinkDevices.test.js index 124f7595b8..f3c9998adc 100644 --- a/server/test/lib/scene/actions/scene.action.blinkLights.test.js +++ b/server/test/lib/scene/actions/scene.action.blinkDevices.test.js @@ -136,6 +136,45 @@ describe('scene.blink-lights', () => { assert.callCount(device.setValue, 12); }); + it('should blink switch in fast mode', async () => { + const stateManager = new StateManager(event); + const deviceFeature = { + category: DEVICE_FEATURE_CATEGORIES.SWITCH, + type: DEVICE_FEATURE_TYPES.SWITCH.BINARY, + last_value: 0, + }; + const device = { + setValue: fake.resolves(null), + features: { + category: DEVICE_FEATURE_CATEGORIES.SWITCH, + type: DEVICE_FEATURE_TYPES.SWITCH.BINARY, + find: fake.returns(deviceFeature), + }, + }; + + stateManager.setState('device', 'switch-1', device); + + const scope = {}; + executeActions( + { stateManager, event, device }, + [ + [ + { + type: ACTIONS.LIGHT.BLINK, + devices: ['switch-1'], + blinking_speed: 'fast', + blinking_time: 2, + }, + ], + ], + scope, + ); + await clock.tickAsync(3000); + assert.calledWithExactly(device.setValue, device, deviceFeature, 0); + assert.calledWithExactly(device.setValue, device, deviceFeature, 1); + assert.callCount(device.setValue, 12); + }); + it('should blink light in unknown mode', async () => { const stateManager = new StateManager(event); const deviceFeature = {