Browse Source

fix hue, some ui tweaks.

beelzebub 0.1.1
Gisle Aune 1 year ago
parent
commit
f00575fd7f
  1. 6
      frontend/src/lib/components/DeviceIcon.svelte
  2. 2
      frontend/src/lib/components/Icon.svelte
  3. 4
      frontend/src/lib/components/Lamp.svelte
  4. 8
      frontend/src/lib/components/bforms/BFormButtonOption.svelte
  5. 17
      frontend/src/lib/components/icons/generic_pendulum_01.svg
  6. 10
      frontend/src/lib/components/icons/hue_ensis_down.svg
  7. 10
      frontend/src/lib/components/icons/hue_ensis_up.svg
  8. 12
      frontend/src/lib/components/scripting/ScriptLine.svelte
  9. 23
      frontend/src/lib/components/scripting/ScriptLineBlock.svelte
  10. 2
      frontend/src/lib/modals/TriggerModal.svelte
  11. 33
      services/hue/bridge.go
  12. 2
      services/uistate/data.go

6
frontend/src/lib/components/DeviceIcon.svelte

@ -3,6 +3,7 @@
import generic_boob from "./icons/generic_boob.svg?raw"; import generic_boob from "./icons/generic_boob.svg?raw";
import generic_ball from "./icons/generic_ball.svg?raw"; import generic_ball from "./icons/generic_ball.svg?raw";
import generic_strip from "./icons/generic_strip.svg?raw"; import generic_strip from "./icons/generic_strip.svg?raw";
import generic_pendulum_01 from "./icons/generic_pendulum_01.svg?raw";
import hue_signe from "./icons/hue_signe.svg?raw"; import hue_signe from "./icons/hue_signe.svg?raw";
import hue_dimmerswitch from "./icons/hue_dimmerswitch.svg?raw"; import hue_dimmerswitch from "./icons/hue_dimmerswitch.svg?raw";
import hue_motionsensor from "./icons/hue_motionsensor.svg?raw"; import hue_motionsensor from "./icons/hue_motionsensor.svg?raw";
@ -15,6 +16,8 @@
import shape_square from "./icons/shape_square.svg?raw"; import shape_square from "./icons/shape_square.svg?raw";
import shape_hexagon from "./icons/shape_hexagon.svg?raw"; import shape_hexagon from "./icons/shape_hexagon.svg?raw";
import shape_triangle from "./icons/shape_triangle.svg?raw"; import shape_triangle from "./icons/shape_triangle.svg?raw";
import hue_ensis_up from "./icons/hue_ensis_up.svg?raw";
import hue_ensis_down from "./icons/hue_ensis_down.svg?raw";
export const deviceIconMap = Object.seal({ export const deviceIconMap = Object.seal({
generic_lamp, generic_lamp,
@ -27,12 +30,15 @@
hue_lightbulb_e27, hue_lightbulb_e27,
hue_lightbulb_e14, hue_lightbulb_e14,
hue_lightbulb_gu10, hue_lightbulb_gu10,
generic_pendulum_01,
hue_adore_tube, hue_adore_tube,
hue_playbar, hue_playbar,
shape_square, shape_square,
shape_hexagon, shape_hexagon,
shape_triangle, shape_triangle,
hue_go, hue_go,
hue_ensis_up,
hue_ensis_down,
}); });
export const deviceIconList = Object.seal(Object.keys(deviceIconMap).sort()) as DeviceIconName[]; export const deviceIconList = Object.seal(Object.keys(deviceIconMap).sort()) as DeviceIconName[];

2
frontend/src/lib/components/Icon.svelte

@ -42,6 +42,7 @@
import { faLightbulb } from "@fortawesome/free-solid-svg-icons/faLightbulb"; import { faLightbulb } from "@fortawesome/free-solid-svg-icons/faLightbulb";
import { faChevronRight } from "@fortawesome/free-solid-svg-icons/faChevronRight"; import { faChevronRight } from "@fortawesome/free-solid-svg-icons/faChevronRight";
import { faChevronDown } from "@fortawesome/free-solid-svg-icons/faChevronDown"; import { faChevronDown } from "@fortawesome/free-solid-svg-icons/faChevronDown";
import { faChevronUp } from "@fortawesome/free-solid-svg-icons/faChevronUp";
import { faTrash } from "@fortawesome/free-solid-svg-icons/faTrash"; import { faTrash } from "@fortawesome/free-solid-svg-icons/faTrash";
import { faCheckToSlot } from "@fortawesome/free-solid-svg-icons/faCheckToSlot"; import { faCheckToSlot } from "@fortawesome/free-solid-svg-icons/faCheckToSlot";
import { faEye } from "@fortawesome/free-solid-svg-icons/faEye"; import { faEye } from "@fortawesome/free-solid-svg-icons/faEye";
@ -83,6 +84,7 @@
"search": faSearch, "search": faSearch,
"chevron_right": faChevronRight, "chevron_right": faChevronRight,
"chevron_down": faChevronDown, "chevron_down": faChevronDown,
"chevron_up": faChevronUp,
"trash": faTrash, "trash": faTrash,
"check_slot": faCheckToSlot, "check_slot": faCheckToSlot,
"eye": faEye, "eye": faEye,

4
frontend/src/lib/components/Lamp.svelte

@ -57,7 +57,7 @@
deviceTitle = device.hwState.internalName; deviceTitle = device.hwState.internalName;
} }
if (hasColor && (!hasPower || device.desiredState.power)) {
if (hasColor && (!hasPower || device.desiredState?.power)) {
iconColor = device.desiredColorRgb; iconColor = device.desiredColorRgb;
} else { } else {
iconColor = null; iconColor = null;
@ -70,7 +70,7 @@
if (sflags & SupportFlags.Temperature) { if (sflags & SupportFlags.Temperature) {
barColor = rgb(1.000,0.2,0.2); barColor = rgb(1.000,0.2,0.2);
barFraction = Math.min(1, Math.max(0, (device.desiredState.temperature||0) - 5) / 35) * 1;
barFraction = Math.min(1, Math.max(0, (device.desiredState?.temperature||0) - 5) / 35) * 1;
} }
if (sflags & SupportFlags.Intensity) { if (sflags & SupportFlags.Intensity) {

8
frontend/src/lib/components/bforms/BFormButtonOption.svelte

@ -0,0 +1,8 @@
<script lang="ts">
import BFormOption from "./BFormOption.svelte";
import type { IconName } from "../Icon.svelte";
export let icon: IconName;
</script>
<BFormOption on:click state icon={icon}></BFormOption>

17
frontend/src/lib/components/icons/generic_pendulum_01.svg

@ -0,0 +1,17 @@
<?xml version='1.0' encoding='ascii'?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="320" height="320">
<g id="View Layer_LineSet" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" inkscape:groupmode="lineset" inkscape:label="View Layer_LineSet">
<g xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" inkscape:groupmode="layer" id="strokes" inkscape:label="strokes">
<path style="fill:#ff0000;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 103.892, 120.570 98.382, 122.830 93.861, 125.585 90.410, 128.009 86.667, 131.511 84.205, 135.508 81.748, 139.558 80.914, 143.792 80.000, 148.766 80.000, 154.675 80.000, 164.675 80.000, 174.675 80.000, 184.675 80.000, 194.675 80.000, 204.675 80.000, 214.675 80.000, 224.675 80.000, 226.259 80.914, 231.233 81.748, 235.467 84.205, 239.516 86.667, 243.514 90.410, 247.016 93.861, 249.440 98.382, 252.195 103.892, 254.455 110.177, 256.135 116.998, 257.170 124.468, 257.538 134.468, 257.538 144.468, 257.538 154.468, 257.538 164.468, 257.538 174.468, 257.538 184.468, 257.538 194.468, 257.538 195.532, 257.538 203.002, 257.170 209.823, 256.135 216.108, 254.455 221.618, 252.195 226.139, 249.440 229.590, 247.016 233.333, 243.514 235.795, 239.516 238.252, 235.467 239.086, 231.233 240.000, 226.259 240.000, 216.259 240.000, 206.259 240.000, 196.259 240.000, 186.259 240.000, 176.259 240.000, 166.259 240.000, 156.259 240.000, 154.675 240.000, 148.766 239.086, 143.792 238.252, 139.558 235.795, 135.508 233.333, 131.511 229.590, 128.009 226.139, 125.585 221.618, 122.830 216.108, 120.570 " />
<path style="fill:#ff0000;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 99.714, 129.357 99.595, 130.436 99.595, 140.436 99.595, 141.548 " />
<path style="fill:#ff0000;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 216.108, 120.570 213.203, 120.447 209.982, 122.066 213.820, 123.641 216.970, 125.560 219.310, 127.750 220.286, 129.357 220.752, 130.125 221.329, 133.055 221.329, 138.047 220.752, 140.976 220.405, 141.548 219.310, 143.352 216.970, 145.542 213.820, 147.461 209.982, 149.036 205.603, 150.206 200.851, 150.927 194.992, 151.215 184.992, 151.215 174.992, 151.215 164.992, 151.215 154.992, 151.215 144.992, 151.215 134.992, 151.215 125.008, 151.215 119.149, 150.927 114.397, 150.206 110.018, 149.036 106.180, 147.461 103.030, 145.542 100.690, 143.352 99.595, 141.548 99.248, 140.976 98.671, 138.047 98.671, 133.055 99.248, 130.125 99.714, 129.357 100.690, 127.750 103.030, 125.560 106.180, 123.641 110.018, 122.066 106.797, 120.447 103.892, 120.570 " />
<path style="fill:#ff0000;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 220.405, 141.548 220.405, 131.548 220.405, 130.436 220.286, 129.357 " />
<path style="fill:#0000ff;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 220.752, 140.976 221.329, 138.047 221.329, 128.047 221.329, 126.608 221.329, 121.616 220.752, 118.687 219.310, 116.311 216.970, 114.121 213.820, 112.202 209.982, 110.627 205.603, 109.457 200.851, 108.736 194.992, 108.448 184.992, 108.448 174.992, 108.448 164.992, 108.448 154.992, 108.448 144.992, 108.448 134.992, 108.448 125.008, 108.448 119.149, 108.736 114.397, 109.457 110.018, 110.627 106.180, 112.202 103.030, 114.121 100.690, 116.311 99.248, 118.687 98.671, 121.616 98.671, 126.608 98.671, 136.608 98.671, 138.047 99.248, 140.976 100.690, 143.352 103.030, 145.542 106.180, 147.461 110.018, 149.036 114.397, 150.206 119.149, 150.927 125.008, 151.215 135.008, 151.215 145.008, 151.215 155.008, 151.215 165.008, 151.215 175.008, 151.215 185.008, 151.215 194.992, 151.215 200.851, 150.927 205.603, 150.206 209.982, 149.036 213.820, 147.461 216.970, 145.542 219.310, 143.352 220.752, 140.976 " />
<path style="fill:#0000ff;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 98.671, 126.608 99.248, 129.538 100.690, 131.913 103.030, 134.103 106.180, 136.022 110.018, 137.597 114.397, 138.767 119.149, 139.488 125.008, 139.777 135.008, 139.777 145.008, 139.777 155.008, 139.777 165.008, 139.777 175.008, 139.777 185.008, 139.777 194.992, 139.777 200.851, 139.488 205.603, 138.767 209.982, 137.597 213.820, 136.022 216.970, 134.103 219.310, 131.913 220.752, 129.538 221.329, 126.608 " />
<path style="fill:#0000ff;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 156.434, 128.417 158.182, 128.682 160.000, 128.772 161.818, 128.682 163.566, 128.417 165.178, 127.986 166.590, 127.407 167.749, 126.701 168.610, 125.895 169.140, 125.021 169.319, 124.112 169.319, 114.112 169.319, 104.112 169.319, 94.112 169.319, 84.112 169.319, 74.112 169.319, 66.269 169.140, 65.360 168.610, 64.486 167.749, 63.680 166.590, 62.974 165.178, 62.395 163.566, 61.964 161.818, 61.699 160.000, 61.609 158.182, 61.699 156.434, 61.964 154.822, 62.395 153.410, 62.974 152.251, 63.680 151.390, 64.486 150.860, 65.360 150.681, 66.269 150.681, 76.269 150.681, 86.269 150.681, 96.269 150.681, 106.269 150.681, 116.269 150.681, 124.112 150.860, 125.021 151.390, 125.895 152.251, 126.701 153.410, 127.407 154.822, 127.986 156.434, 128.417 " />
<path style="fill:#0000ff;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 169.319, 66.269 169.140, 67.178 168.610, 68.052 167.749, 68.858 166.590, 69.564 165.178, 70.143 163.566, 70.574 161.818, 70.839 160.000, 70.929 158.182, 70.839 156.434, 70.574 154.822, 70.143 153.410, 69.564 152.251, 68.858 151.390, 68.052 150.860, 67.178 150.681, 66.269 " />
</g>
</g>
</svg>

10
frontend/src/lib/components/icons/hue_ensis_down.svg

@ -0,0 +1,10 @@
<?xml version='1.0' encoding='ascii'?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="320" height="320">
<g id="View Layer_LineSet" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" inkscape:groupmode="lineset" inkscape:label="View Layer_LineSet">
<g xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" inkscape:groupmode="layer" id="strokes" inkscape:label="strokes">
<path style="fill:#0000ff;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 61.025, 138.173 60.000, 140.748 60.000, 150.748 60.000, 160.748 60.000, 170.748 60.000, 177.711 60.000, 179.252 61.025, 181.827 63.942, 184.011 68.309, 185.469 73.460, 185.982 83.460, 185.982 93.460, 185.982 103.460, 185.982 113.460, 185.982 123.460, 185.982 133.460, 185.982 143.460, 185.982 153.460, 185.982 163.460, 185.982 173.460, 185.982 183.460, 185.982 193.460, 185.982 203.460, 185.982 213.460, 185.982 223.460, 185.982 233.460, 185.982 243.460, 185.982 246.540, 185.982 251.691, 185.469 256.058, 184.011 258.975, 181.827 260.000, 179.252 260.000, 177.711 260.000, 167.711 260.000, 157.711 260.000, 147.711 260.000, 140.748 258.975, 138.173 256.058, 135.989 251.691, 134.531 246.540, 134.018 236.540, 134.018 226.540, 134.018 216.540, 134.018 206.540, 134.018 196.540, 134.018 186.540, 134.018 176.540, 134.018 166.540, 134.018 156.540, 134.018 146.540, 134.018 136.540, 134.018 126.540, 134.018 116.540, 134.018 106.540, 134.018 96.540, 134.018 86.540, 134.018 76.540, 134.018 73.460, 134.018 68.309, 134.531 63.942, 135.989 61.025, 138.173 " />
<path style="fill:#0000ff;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 60.000, 177.711 61.025, 175.136 63.942, 172.953 68.309, 171.494 73.460, 170.982 83.460, 170.982 93.460, 170.982 103.460, 170.982 113.460, 170.982 123.460, 170.982 133.460, 170.982 143.460, 170.982 153.460, 170.982 163.460, 170.982 173.460, 170.982 183.460, 170.982 193.460, 170.982 203.460, 170.982 213.460, 170.982 223.460, 170.982 233.460, 170.982 243.460, 170.982 246.540, 170.982 251.691, 171.494 256.058, 172.953 258.975, 175.136 260.000, 177.711 " />
<path style="fill:#ff0000;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 255.651, 177.926 255.651, 179.038 254.879, 180.979 252.923, 182.443 249.994, 183.421 246.112, 183.807 236.112, 183.807 226.112, 183.807 216.112, 183.807 206.112, 183.807 196.112, 183.807 186.112, 183.807 176.112, 183.807 166.112, 183.807 156.112, 183.807 146.112, 183.807 136.112, 183.807 126.112, 183.807 116.112, 183.807 106.112, 183.807 96.112, 183.807 86.112, 183.807 76.112, 183.807 73.888, 183.807 70.006, 183.421 67.077, 182.443 65.121, 180.979 64.349, 179.038 64.349, 177.926 65.121, 175.984 67.077, 174.520 70.006, 173.542 73.888, 173.156 83.888, 173.156 93.888, 173.156 103.888, 173.156 113.888, 173.156 123.888, 173.156 133.888, 173.156 143.888, 173.156 153.888, 173.156 163.888, 173.156 173.888, 173.156 183.888, 173.156 193.888, 173.156 203.888, 173.156 213.888, 173.156 223.888, 173.156 233.888, 173.156 243.888, 173.156 246.112, 173.156 249.994, 173.542 252.923, 174.520 254.879, 175.984 255.651, 177.926 " />
</g>
</g>
</svg>

10
frontend/src/lib/components/icons/hue_ensis_up.svg

@ -0,0 +1,10 @@
<?xml version='1.0' encoding='ascii'?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="320" height="320">
<g id="View Layer_LineSet" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" inkscape:groupmode="lineset" inkscape:label="View Layer_LineSet">
<g xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" inkscape:groupmode="layer" id="strokes" inkscape:label="strokes">
<path style="fill:#0000ff;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 258.975, 181.827 260.000, 179.252 260.000, 169.252 260.000, 159.252 260.000, 149.252 260.000, 142.289 260.000, 140.748 258.975, 138.173 256.058, 135.989 251.691, 134.531 246.540, 134.018 236.540, 134.018 226.540, 134.018 216.540, 134.018 206.540, 134.018 196.540, 134.018 186.540, 134.018 176.540, 134.018 166.540, 134.018 156.540, 134.018 146.540, 134.018 136.540, 134.018 126.540, 134.018 116.540, 134.018 106.540, 134.018 96.540, 134.018 86.540, 134.018 76.540, 134.018 73.460, 134.018 68.309, 134.531 63.942, 135.989 61.025, 138.173 60.000, 140.748 60.000, 142.289 60.000, 152.289 60.000, 162.289 60.000, 172.289 60.000, 177.711 60.000, 179.252 61.025, 181.827 63.942, 184.011 68.309, 185.469 73.460, 185.982 83.460, 185.982 93.460, 185.982 103.460, 185.982 113.460, 185.982 123.460, 185.982 133.460, 185.982 143.460, 185.982 153.460, 185.982 163.460, 185.982 173.460, 185.982 183.460, 185.982 193.460, 185.982 203.460, 185.982 213.460, 185.982 223.460, 185.982 233.460, 185.982 243.460, 185.982 246.540, 185.982 251.691, 185.469 256.058, 184.011 258.975, 181.827 " />
<path style="fill:#0000ff;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 260.000, 142.289 258.975, 144.864 256.058, 147.047 251.691, 148.506 246.540, 149.018 236.540, 149.018 226.540, 149.018 216.540, 149.018 206.540, 149.018 196.540, 149.018 186.540, 149.018 176.540, 149.018 166.540, 149.018 156.540, 149.018 146.540, 149.018 136.540, 149.018 126.540, 149.018 116.540, 149.018 106.540, 149.018 96.540, 149.018 86.540, 149.018 76.540, 149.018 73.460, 149.018 68.309, 148.506 63.942, 147.047 61.025, 144.864 60.000, 142.289 " />
<path style="fill:#ff0000;fill-opacity:1" fill="none" stroke-width="3.0" stroke-linecap="butt" stroke-opacity="1.0" stroke="rgb(0, 0, 0)" stroke-linejoin="miter" d=" M 255.651, 142.074 255.651, 140.962 254.879, 139.021 252.923, 137.557 249.994, 136.579 246.112, 136.193 236.112, 136.193 226.112, 136.193 216.112, 136.193 206.112, 136.193 196.112, 136.193 186.112, 136.193 176.112, 136.193 166.112, 136.193 156.112, 136.193 146.112, 136.193 136.112, 136.193 126.112, 136.193 116.112, 136.193 106.112, 136.193 96.112, 136.193 86.112, 136.193 76.112, 136.193 73.888, 136.193 70.006, 136.579 67.077, 137.557 65.121, 139.021 64.349, 140.962 64.349, 142.074 65.121, 144.016 67.077, 145.480 70.006, 146.458 73.888, 146.844 83.888, 146.844 93.888, 146.844 103.888, 146.844 113.888, 146.844 123.888, 146.844 133.888, 146.844 143.888, 146.844 153.888, 146.844 163.888, 146.844 173.888, 146.844 183.888, 146.844 193.888, 146.844 203.888, 146.844 213.888, 146.844 223.888, 146.844 233.888, 146.844 243.888, 146.844 246.112, 146.844 249.994, 146.458 252.923, 145.480 254.879, 144.016 255.651, 142.074 " />
</g>
</g>
</svg>

12
frontend/src/lib/components/scripting/ScriptLine.svelte

@ -11,7 +11,9 @@
import { BLANK_STATE, copyState } from "$lib/models/device"; import { BLANK_STATE, copyState } from "$lib/models/device";
import { toEditableScriptLine, type ScriptLineEditable } from "$lib/models/script"; import { toEditableScriptLine, type ScriptLineEditable } from "$lib/models/script";
import { createEventDispatcher } from "svelte";
import type { IconName } from "../Icon.svelte"; import type { IconName } from "../Icon.svelte";
import BFormButtonOption from "../bforms/BFormButtonOption.svelte";
import BFormDeleteOption from "../bforms/BFormDeleteOption.svelte"; import BFormDeleteOption from "../bforms/BFormDeleteOption.svelte";
import BFormLine from "../bforms/BFormLine.svelte"; import BFormLine from "../bforms/BFormLine.svelte";
import BFormOption from "../bforms/BFormOption.svelte"; import BFormOption from "../bforms/BFormOption.svelte";
@ -25,6 +27,10 @@
import ScriptSet from "./ScriptSet.svelte"; import ScriptSet from "./ScriptSet.svelte";
export let value: ScriptLineEditable; export let value: ScriptLineEditable;
export let first: boolean = false;
export let last: boolean = false;
const dispatch = createEventDispatcher();
function deleteState(index: number) { function deleteState(index: number) {
value.effect.states = [ value.effect.states = [
@ -95,6 +101,12 @@
<ScriptSet bind:key={value.key} bind:scope={value.scope} bind:value={value.value} /> <ScriptSet bind:key={value.key} bind:scope={value.scope} bind:value={value.value} />
{/if} {/if}
<BFormDeleteOption on:delete /> <BFormDeleteOption on:delete />
{#if !first}
<BFormButtonOption icon="chevron_up" on:click={() => dispatch("up")} />
{/if}
{#if !last}
<BFormButtonOption icon="chevron_down" on:click={() => dispatch("down")} />
{/if}
</BFormLine> </BFormLine>
{#if value.kind === "assign"} {#if value.kind === "assign"}
<ScriptBlock on:add={addState} add label="States"> <ScriptBlock on:add={addState} add label="States">

23
frontend/src/lib/components/scripting/ScriptLineBlock.svelte

@ -7,6 +7,20 @@
export let value: ScriptLineEditable[]; export let value: ScriptLineEditable[];
export let add: boolean = false; export let add: boolean = false;
function moveUp(i: number) {
value = [...value];
const temp = value[i];
value[i] = value[i - 1];
value[i - 1] = temp;
}
function moveDown(i: number) {
value = [...value];
const temp = value[i];
value[i] = value[i + 1];
value[i + 1] = temp;
}
function deleteLine(i: number) { function deleteLine(i: number) {
value = [...value.slice(0, i), ...value.slice(i + 1)]; value = [...value.slice(0, i), ...value.slice(i + 1)];
} }
@ -14,6 +28,13 @@
<ScriptBlock on:add add={add} label={label}> <ScriptBlock on:add add={add} label={label}>
{#each value as line, i} {#each value as line, i}
<ScriptLine bind:value={line} on:delete={() => deleteLine(i)} />
<ScriptLine
first={i === 0}
last={i === value.length - 1}
bind:value={line}
on:up={() => moveUp(i)}
on:down={() => moveDown(i)}
on:delete={() => deleteLine(i)}
/>
{/each} {/each}
</ScriptBlock> </ScriptBlock>

2
frontend/src/lib/modals/TriggerModal.svelte

@ -55,7 +55,7 @@
if (id !== "") { if (id !== "") {
current = toEditableTrigger($state.triggers[id]); current = toEditableTrigger($state.triggers[id]);
} else { } else {
current = newEditableTrigger($maskList[0], scriptList?.[0] || "");
current = {...current, id: null};
} }
} }

33
services/hue/bridge.go

@ -436,6 +436,8 @@ func (b *Bridge) Run(ctx context.Context, bus *lucifer3.EventBus) interface{} {
} }
func (b *Bridge) makeCongruentLoop(ctx context.Context) { func (b *Bridge) makeCongruentLoop(ctx context.Context) {
hadFirst := make(map[string]bool, 16)
for range b.triggerCongruenceCheckCh { for range b.triggerCongruenceCheckCh {
// I hate that I have to do this, but the SSE is not being reliable. // I hate that I have to do this, but the SSE is not being reliable.
_, _ = b.RefreshAll() _, _ = b.RefreshAll()
@ -473,13 +475,12 @@ func (b *Bridge) makeCongruentLoop(ctx context.Context) {
update := ResourceUpdate{} update := ResourceUpdate{}
// Handle power first // Handle power first
if desired.Power != nil && active.Power != nil && *desired.Power != *active.Power {
if desired.Power != nil && active.Power != nil && (!hadFirst[*lightID] || *desired.Power != *active.Power) {
update.Power = gentools.Ptr(*desired.Power) update.Power = gentools.Ptr(*desired.Power)
updated = true updated = true
} }
// Only do the rest if there's power. // Only do the rest if there's power.
if desired.Power == nil || *desired.Power {
if active.Color != nil && desired.Color != nil { if active.Color != nil && desired.Color != nil {
ac := *active.Color ac := *active.Color
dc := *desired.Color dc := *desired.Color
@ -496,7 +497,7 @@ func (b *Bridge) makeCongruentLoop(ctx context.Context) {
acXY, _ := ac.ToXY() acXY, _ := ac.ToXY()
dist := dc.XY.DistanceTo(*acXY.XY) dist := dc.XY.DistanceTo(*acXY.XY)
if dist > 0.0002 {
if dist > 0.0002 || !hadFirst[*lightID] {
update.ColorXY = gentools.Ptr(*dc.XY) update.ColorXY = gentools.Ptr(*dc.XY)
updated = true updated = true
} }
@ -511,14 +512,13 @@ func (b *Bridge) makeCongruentLoop(ctx context.Context) {
if ac.K != nil { if ac.K != nil {
acMirek = 1000000 / *ac.K acMirek = 1000000 / *ac.K
} }
if acMirek != dcMirek {
if acMirek != dcMirek || !hadFirst[*lightID] {
update.Mirek = &dcMirek update.Mirek = &dcMirek
updated = true updated = true
} }
} }
}
if active.Intensity != nil && desired.Intensity != nil {
if active.Intensity != nil && desired.Intensity != nil || !hadFirst[*lightID] {
if math.Abs(*active.Intensity-*desired.Intensity) >= 0.01 { if math.Abs(*active.Intensity-*desired.Intensity) >= 0.01 {
update.Brightness = gentools.Ptr(*desired.Intensity * 100) update.Brightness = gentools.Ptr(*desired.Intensity * 100)
updated = true updated = true
@ -529,11 +529,13 @@ func (b *Bridge) makeCongruentLoop(ctx context.Context) {
if updated { if updated {
update.TransitionDuration = gentools.Ptr(time.Millisecond * 101) update.TransitionDuration = gentools.Ptr(time.Millisecond * 101)
updates["light/"+*lightID] = update updates["light/"+*lightID] = update
hadFirst[*lightID] = true
} }
} }
if len(updates) > 0 { if len(updates) > 0 {
timeout, cancel := context.WithTimeout(ctx, time.Millisecond*500*time.Duration(len(updates)))
timeout, cancel := context.WithTimeout(ctx, time.Second*60)
hadPower := false
eg, ctx := errgroup.WithContext(timeout) eg, ctx := errgroup.WithContext(timeout)
for key := range updates { for key := range updates {
@ -541,8 +543,19 @@ func (b *Bridge) makeCongruentLoop(ctx context.Context) {
split := strings.SplitN(key, "/", 2) split := strings.SplitN(key, "/", 2)
link := ResourceLink{Kind: split[0], ID: split[1]} link := ResourceLink{Kind: split[0], ID: split[1]}
if update.Power != nil {
hadPower = true
}
eg.Go(func() error { eg.Go(func() error {
if update.Power != nil {
return b.client.UpdateResource(ctx, link, ResourceUpdate{
Power: update.Power,
TransitionDuration: update.TransitionDuration,
})
} else {
return b.client.UpdateResource(ctx, link, update) return b.client.UpdateResource(ctx, link, update)
}
}) })
} }
@ -551,13 +564,17 @@ func (b *Bridge) makeCongruentLoop(ctx context.Context) {
log.Println("Failed to run update", err) log.Println("Failed to run update", err)
} }
if hadPower {
b.triggerCongruenceCheck()
}
cancel() cancel()
}
// Wait the remaining time for the rate limit // Wait the remaining time for the rate limit
<-rateLimit <-rateLimit
} }
} }
}
func (b *Bridge) fullId(res ResourceData) string { func (b *Bridge) fullId(res ResourceData) string {
id := res.ID id := res.ID

2
services/uistate/data.go

@ -148,7 +148,7 @@ func (d *Data) ensureDevice(id string) Device {
if device, ok := d.Devices[id]; ok { if device, ok := d.Devices[id]; ok {
return device return device
} else { } else {
return Device{ID: id}
return Device{ID: id, Aliases: make([]string, 0)}
} }
} }

Loading…
Cancel
Save