Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2f3d3c4d1 | ||
|
|
16c6d5316b | ||
|
|
a558594537 |
+2
-1
@@ -7,4 +7,5 @@ node_modules
|
||||
!.env.example
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
/*.blend1
|
||||
/*.blend1
|
||||
/build
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{H as f,s as y,a8 as m,Z as q,a9 as w}from"./index.f09c780f.js";const o=[];function z(n,i){return{subscribe:A(n,i).subscribe}}function A(n,i=f){let u;const t=new Set;function a(e){if(y(n,e)&&(n=e,u)){const r=!o.length;for(const s of t)s[1](),o.push(s,n);if(r){for(let s=0;s<o.length;s+=2)o[s][0](o[s+1]);o.length=0}}}function l(e){a(e(n))}function b(e,r=f){const s=[e,r];return t.add(s),t.size===1&&(u=i(a)||f),e(n),()=>{t.delete(s),t.size===0&&(u(),u=null)}}return{set:a,update:l,subscribe:b}}function H(n,i,u){const t=!Array.isArray(n),a=t?[n]:n,l=i.length<2;return z(u,b=>{let e=!1;const r=[];let s=0,d=f;const g=()=>{if(s)return;d();const c=i(t?r[0]:r,b);l?b(c):d=w(c)?c:f},_=a.map((c,p)=>m(c,h=>{r[p]=h,s&=~(1<<p),e&&g()},()=>{s|=1<<p}));return e=!0,g(),function(){q(_),d()}})}export{H as d,A as w};
|
||||
@@ -1 +0,0 @@
|
||||
import{w as u}from"./index.faf1c53d.js";var _;const v=((_=globalThis.__sveltekit_1k9l1nc)==null?void 0:_.base)??"";var g;const k=((g=globalThis.__sveltekit_1k9l1nc)==null?void 0:g.assets)??v,m="1697835102898",R="sveltekit:snapshot",T="sveltekit:scroll",y="sveltekit:index",f={tap:1,hover:2,viewport:3,eager:4,off:-1};function I(e){let t=e.baseURI;if(!t){const n=e.getElementsByTagName("base");t=n.length?n[0].href:e.URL}return t}function S(){return{x:pageXOffset,y:pageYOffset}}function c(e,t){return e.getAttribute(`data-sveltekit-${t}`)}const d={...f,"":f.hover};function h(e){let t=e.assignedSlot??e.parentNode;return(t==null?void 0:t.nodeType)===11&&(t=t.host),t}function x(e,t){for(;e&&e!==t;){if(e.nodeName.toUpperCase()==="A"&&e.hasAttribute("href"))return e;e=h(e)}}function O(e,t){let n;try{n=new URL(e instanceof SVGAElement?e.href.baseVal:e.href,document.baseURI)}catch{}const o=e instanceof SVGAElement?e.target.baseVal:e.target,l=!n||!!o||E(n,t)||(e.getAttribute("rel")||"").split(/\s+/).includes("external"),r=(n==null?void 0:n.origin)===location.origin&&e.hasAttribute("download");return{url:n,external:l,target:o,download:r}}function U(e){let t=null,n=null,o=null,l=null,r=null,a=null,s=e;for(;s&&s!==document.documentElement;)o===null&&(o=c(s,"preload-code")),l===null&&(l=c(s,"preload-data")),t===null&&(t=c(s,"keepfocus")),n===null&&(n=c(s,"noscroll")),r===null&&(r=c(s,"reload")),a===null&&(a=c(s,"replacestate")),s=h(s);function i(b){switch(b){case"":case"true":return!0;case"off":case"false":return!1;default:return null}}return{preload_code:d[o??"off"],preload_data:d[l??"off"],keep_focus:i(t),noscroll:i(n),reload:i(r),replace_state:i(a)}}function p(e){const t=u(e);let n=!0;function o(){n=!0,t.update(a=>a)}function l(a){n=!1,t.set(a)}function r(a){let s;return t.subscribe(i=>{(s===void 0||n&&i!==s)&&a(s=i)})}return{notify:o,set:l,subscribe:r}}function w(){const{set:e,subscribe:t}=u(!1);let n;async function o(){clearTimeout(n);try{const l=await fetch(`${k}/_app/version.json`,{headers:{pragma:"no-cache","cache-control":"no-cache"}});if(!l.ok)return!1;const a=(await l.json()).version!==m;return a&&(e(!0),clearTimeout(n)),a}catch{return!1}}return{subscribe:t,check:o}}function E(e,t){return e.origin!==location.origin||!e.pathname.startsWith(t)}function L(e){e.client}const N={url:p({}),page:p({}),navigating:u(null),updated:w()};export{y as I,f as P,T as S,R as a,O as b,U as c,N as d,v as e,x as f,I as g,L as h,E as i,S as s};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{S as i,i as _,s as m,y as c,z as $,A as f,g as r,d as l,B as u,C as p,D as g,E as d,F as S}from"../chunks/index.f09c780f.js";import{S as x,a as h,M as C}from"../chunks/SelectContext.07ce997f.js";const b=!0,q=Object.freeze(Object.defineProperty({__proto__:null,prerender:b},Symbol.toStringTag,{value:"Module"}));function v(a){let t;const o=a[0].default,e=p(o,a,a[1],null);return{c(){e&&e.c()},l(n){e&&e.l(n)},m(n,s){e&&e.m(n,s),t=!0},p(n,s){e&&e.p&&(!t||s&2)&&g(e,o,n,n[1],t?S(o,n[1],s,null):d(n[1]),null)},i(n){t||(r(e,n),t=!0)},o(n){l(e,n),t=!1},d(n){e&&e.d(n)}}}function w(a){let t,o;return t=new C({props:{$$slots:{default:[v]},$$scope:{ctx:a}}}),{c(){c(t.$$.fragment)},l(e){$(t.$$.fragment,e)},m(e,n){f(t,e,n),o=!0},p(e,n){const s={};n&2&&(s.$$scope={dirty:n,ctx:e}),t.$set(s)},i(e){o||(r(t.$$.fragment,e),o=!0)},o(e){l(t.$$.fragment,e),o=!1},d(e){u(t,e)}}}function y(a){let t,o;return t=new h({props:{$$slots:{default:[w]},$$scope:{ctx:a}}}),{c(){c(t.$$.fragment)},l(e){$(t.$$.fragment,e)},m(e,n){f(t,e,n),o=!0},p(e,n){const s={};n&2&&(s.$$scope={dirty:n,ctx:e}),t.$set(s)},i(e){o||(r(t.$$.fragment,e),o=!0)},o(e){l(t.$$.fragment,e),o=!1},d(e){u(t,e)}}}function M(a){let t,o;return t=new x({props:{$$slots:{default:[y]},$$scope:{ctx:a}}}),{c(){c(t.$$.fragment)},l(e){$(t.$$.fragment,e)},m(e,n){f(t,e,n),o=!0},p(e,[n]){const s={};n&2&&(s.$$scope={dirty:n,ctx:e}),t.$set(s)},i(e){o||(r(t.$$.fragment,e),o=!0)},o(e){l(t.$$.fragment,e),o=!1},d(e){u(t,e)}}}function j(a,t,o){let{$$slots:e={},$$scope:n}=t;return a.$$set=s=>{"$$scope"in s&&o(1,n=s.$$scope)},[e,n]}class A extends i{constructor(t){super(),_(this,t,j,M,m,{})}}export{A as component,q as universal};
|
||||
@@ -1 +0,0 @@
|
||||
import{S,i as q,s as x,k as _,q as f,a as H,l as d,m as g,r as h,h as u,c as k,b as m,G as v,u as $,H as E,I as y}from"../chunks/index.f09c780f.js";import{d as C}from"../chunks/singletons.6d605789.js";const G=()=>{const s=C;return{page:{subscribe:s.page.subscribe},navigating:{subscribe:s.navigating.subscribe},updated:s.updated}},I={subscribe(s){return G().page.subscribe(s)}};function P(s){var b;let t,r=s[0].status+"",o,n,i,c=((b=s[0].error)==null?void 0:b.message)+"",l;return{c(){t=_("h1"),o=f(r),n=H(),i=_("p"),l=f(c)},l(e){t=d(e,"H1",{});var a=g(t);o=h(a,r),a.forEach(u),n=k(e),i=d(e,"P",{});var p=g(i);l=h(p,c),p.forEach(u)},m(e,a){m(e,t,a),v(t,o),m(e,n,a),m(e,i,a),v(i,l)},p(e,[a]){var p;a&1&&r!==(r=e[0].status+"")&&$(o,r),a&1&&c!==(c=((p=e[0].error)==null?void 0:p.message)+"")&&$(l,c)},i:E,o:E,d(e){e&&u(t),e&&u(n),e&&u(i)}}}function j(s,t,r){let o;return y(s,I,n=>r(0,o=n)),[o]}let A=class extends S{constructor(t){super(),q(this,t,j,P,x,{})}};export{A as component};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
{"version":"1697835102898"}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 173 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 45 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,68 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="./favicon.png" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="darkreader" content="we've already gone dark" />
|
||||
<style>
|
||||
body, html {
|
||||
background: #111114;
|
||||
color: #ccc;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link href="./_app/immutable/assets/2.8d52c342.css" rel="stylesheet">
|
||||
<link rel="modulepreload" href="./_app/immutable/entry/start.08a3b3b3.js">
|
||||
<link rel="modulepreload" href="./_app/immutable/chunks/index.f09c780f.js">
|
||||
<link rel="modulepreload" href="./_app/immutable/chunks/singletons.6d605789.js">
|
||||
<link rel="modulepreload" href="./_app/immutable/chunks/index.faf1c53d.js">
|
||||
<link rel="modulepreload" href="./_app/immutable/entry/app.16612d08.js">
|
||||
<link rel="modulepreload" href="./_app/immutable/nodes/0.202e929e.js">
|
||||
<link rel="modulepreload" href="./_app/immutable/chunks/SelectContext.07ce997f.js">
|
||||
<link rel="modulepreload" href="./_app/immutable/nodes/2.2ea37eba.js">
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="page svelte-170wh9b"></div>
|
||||
|
||||
<form novalidate></form>
|
||||
<form novalidate></form>
|
||||
<form novalidate></form>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
{
|
||||
__sveltekit_1k9l1nc = {
|
||||
base: new URL(".", location).pathname.slice(0, -1),
|
||||
env: {}
|
||||
};
|
||||
|
||||
const element = document.currentScript.parentElement;
|
||||
|
||||
const data = [null,null];
|
||||
|
||||
Promise.all([
|
||||
import("./_app/immutable/entry/start.08a3b3b3.js"),
|
||||
import("./_app/immutable/entry/app.16612d08.js")
|
||||
]).then(([kit, app]) => {
|
||||
kit.start(app, element, {
|
||||
node_ids: [0, 2],
|
||||
data,
|
||||
form: null,
|
||||
error: null
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
@@ -19,7 +19,7 @@
|
||||
}
|
||||
|
||||
let percentage: number
|
||||
$: percentage = Math.max(Math.min((value || 0) * 100, 100), 0);
|
||||
$: percentage = Math.round(Math.max(Math.min((value || 0) * 100, 100), 0));
|
||||
$: update(percentage);
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { runCommand } from "$lib/client/lucifer";
|
||||
import AssignmentState from "$lib/components/scripting/ScriptAssignmentState.svelte";
|
||||
import Button from "$lib/components/Button.svelte";
|
||||
import Checkbox from "$lib/components/Checkbox.svelte";
|
||||
import type { DeviceIconName } from "$lib/components/DeviceIcon.svelte";
|
||||
@@ -17,12 +16,11 @@
|
||||
import { getStateContext } from "$lib/contexts/StateContext.svelte";
|
||||
import { toEffectRaw, type EffectRaw, fromEffectRaw } from "$lib/models/assignment";
|
||||
import type { DeviceEditOp } from "$lib/models/device";
|
||||
import { iconName } from "@fortawesome/free-solid-svg-icons/faQuestion";
|
||||
import ScriptAssignmentState from "$lib/components/scripting/ScriptAssignmentState.svelte";
|
||||
|
||||
const { modal } = getModalContext();
|
||||
const { selectedMasks, selectedMap, selectedList } = getSelectedContext();
|
||||
const { deviceList, assignmentList } = getStateContext();
|
||||
const { deviceList, state, assignmentList } = getStateContext();
|
||||
|
||||
let show: boolean = false;
|
||||
let match: string = "";
|
||||
@@ -151,13 +149,28 @@
|
||||
await runCommand({assign: { match, effect: fromEffectRaw(newEffect) }});
|
||||
}
|
||||
if (enableRoom) {
|
||||
await runCommand({addAlias: { match, alias: `lucifer:room:${newRoom || customRoom}` }});
|
||||
if (newRoom || customRoom) {
|
||||
await runCommand({addAlias: { match, alias: `lucifer:room:${newRoom || customRoom}` }});
|
||||
} else {
|
||||
const group = $selectedList.flatMap(id => $state.devices[id].aliases).find(a => a.startsWith("lucifer:room:"));
|
||||
if (group != null) {
|
||||
await runCommand({removeAlias: { match, alias: group }});
|
||||
}
|
||||
}
|
||||
|
||||
enableRoom = false;
|
||||
shouldWait = match.startsWith("lucifer:room:");
|
||||
newRoom = newRoom || customRoom;
|
||||
}
|
||||
if (enableGroup && (newGroup || customGroup)) {
|
||||
await runCommand({addAlias: { match, alias: `lucifer:group:${newGroup || customGroup}` }});
|
||||
if (enableGroup) {
|
||||
if (newGroup || customGroup) {
|
||||
await runCommand({addAlias: { match, alias: `lucifer:group:${newGroup || customGroup}` }});
|
||||
} else {
|
||||
const group = $selectedList.flatMap(id => $state.devices[id].aliases).find(a => a.startsWith("lucifer:group:"));
|
||||
if (group != null) {
|
||||
await runCommand({removeAlias: { match, alias: group }});
|
||||
}
|
||||
}
|
||||
enableGroup = false;
|
||||
shouldWait = match.startsWith("lucifer:group:");
|
||||
newGroup = newGroup || customGroup;
|
||||
@@ -302,21 +315,23 @@
|
||||
</HSplitPart>
|
||||
</HSplit>
|
||||
</ModalSection>
|
||||
<ModalSection bind:expanded={enableRename} title="Rename">
|
||||
<label for="name">New Name</label>
|
||||
<input type="text" name="name" bind:value={newName} />
|
||||
</ModalSection>
|
||||
{#if $selectedList.length === 1}
|
||||
<ModalSection bind:expanded={enableRename} title="Rename">
|
||||
<label for="name">New Name</label>
|
||||
<input type="text" name="name" bind:value={newName} />
|
||||
</ModalSection>
|
||||
{/if}
|
||||
<ModalSection bind:expanded={enableRoom} title="Change Room">
|
||||
<label for="newRoom">Select Room</label>
|
||||
<select bind:value={newRoom}>
|
||||
{#each roomOptions as roomOption}
|
||||
<option value={roomOption}>{roomOption}</option>
|
||||
{/each}
|
||||
<option value="">Create Room</option>
|
||||
<option value="">Other Room / Clear</option>
|
||||
</select>
|
||||
{#if newRoom == ""}
|
||||
<label for="customRoom">New Room</label>
|
||||
<input type="text" name="customRoom" bind:value={customRoom} />
|
||||
<input type="text" name="customRoom" placeholder="Leave blank to clear room." bind:value={customRoom} />
|
||||
{/if}
|
||||
</ModalSection>
|
||||
<ModalSection bind:expanded={enableGroup} title="Change Group">
|
||||
@@ -325,11 +340,11 @@
|
||||
{#each groupOptions as groupOption}
|
||||
<option value={groupOption}>{groupOption}</option>
|
||||
{/each}
|
||||
<option value="">Create Group</option>
|
||||
<option value="">Other Group / Clear</option>
|
||||
</select>
|
||||
{#if newGroup == ""}
|
||||
<label for="customGroup">New Group</label>
|
||||
<input type="text" name="customGroup" bind:value={customGroup} />
|
||||
<input type="text" name="customGroup" placeholder="Leave blank to clear group." bind:value={customGroup} />
|
||||
{/if}
|
||||
</ModalSection>
|
||||
<ModalSection bind:expanded={enableIcon} title="Change Icon">
|
||||
|
||||
@@ -18,31 +18,34 @@ export type Effect =
|
||||
| { gradient: { states: State[], animationMs: number, reverse: boolean, interpolate: boolean } }
|
||||
| { pattern: { states: State[], animationMs: number } }
|
||||
| { random: { states: State[], animationMs: number, interpolate: boolean } }
|
||||
| { vrange: { states: State[], variable: string, min: number, max: number } }
|
||||
| { vrange: { states: State[], variable: string, min: number, max: number, interpolate: boolean } }
|
||||
|
||||
export function toEffectRaw(effect?: Effect): EffectRaw {
|
||||
let effectRaw: EffectRaw = { kind: "manual", states: [{color: null, intensity: null, power: null, temperature: null}], animationMs: 0, reverse: false, interpolate: false, min: 30, max: 300, variable: "motion.min", interleave: 0 };
|
||||
|
||||
if (effect != null) {
|
||||
if ("manual" in effect) {
|
||||
return { kind: "solid", states: [effect.manual], animationMs: 0, reverse: false, interpolate: true, min: 30, max: 300, variable: "motion.min", interleave: 0 }
|
||||
}
|
||||
if ("solid" in effect) {
|
||||
return { kind: "solid", ...effect.solid, min: 30, max: 300, variable: "motion.min", interpolate: true, reverse: false}
|
||||
}
|
||||
if ("gradient" in effect) {
|
||||
return { kind: "gradient", ...effect.gradient, min: 30, max: 300, variable: "motion.min", interleave: 0 }
|
||||
}
|
||||
if ("pattern" in effect) {
|
||||
return { kind: "pattern", ...effect.pattern, reverse: false, interpolate: true, min: 30, max: 300, variable: "motion.min", interleave: 0 }
|
||||
}
|
||||
if ("random" in effect) {
|
||||
return { kind: "random", ...effect.random, reverse: false, min: 30, max: 300, variable: "motion.min", interleave: 0 }
|
||||
}
|
||||
if ("vrange" in effect) {
|
||||
return { kind: "vrange", ...effect.vrange, animationMs: 0, interpolate: true, reverse: false, interleave: 0 }
|
||||
effectRaw = { kind: "solid", states: [effect.manual], animationMs: 0, reverse: false, interpolate: true, min: 30, max: 300, variable: "motion.min", interleave: 0 }
|
||||
} else if ("solid" in effect) {
|
||||
effectRaw = { kind: "solid", ...effect.solid, min: 30, max: 300, variable: "motion.min", interpolate: true, reverse: false}
|
||||
} else if ("gradient" in effect) {
|
||||
effectRaw = { kind: "gradient", ...effect.gradient, min: 30, max: 300, variable: "motion.min", interleave: 0 }
|
||||
} else if ("pattern" in effect) {
|
||||
effectRaw = { kind: "pattern", ...effect.pattern, reverse: false, interpolate: true, min: 30, max: 300, variable: "motion.min", interleave: 0 }
|
||||
} else if ("random" in effect) {
|
||||
effectRaw = { kind: "random", ...effect.random, reverse: false, min: 30, max: 300, variable: "motion.min", interleave: 0 }
|
||||
} else if ("vrange" in effect) {
|
||||
effectRaw = { kind: "vrange", ...effect.vrange, animationMs: 0, reverse: false, interleave: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
return { kind: "manual", states: [{color: null, intensity: null, power: null, temperature: null}], animationMs: 0, reverse: false, interpolate: false, min: 30, max: 300, variable: "motion.min", interleave: 0 }
|
||||
effectRaw.states.forEach(state => {
|
||||
if (state.intensity !== null) {
|
||||
state.intensity = Math.floor(state.intensity * 100) / 100;
|
||||
}
|
||||
})
|
||||
|
||||
return effectRaw;
|
||||
}
|
||||
|
||||
export function fromEffectRaw(raw: EffectRaw): Effect {
|
||||
|
||||
@@ -143,12 +143,12 @@ export function toEditableScriptLine(line: ScriptLine): ScriptLineEditable {
|
||||
not: line.if.condition.not || false,
|
||||
value: line.if.condition.value || "",
|
||||
};
|
||||
base.then = line.if.then.map(toEditableScriptLine);
|
||||
base.else = line.if.else.map(toEditableScriptLine);
|
||||
base.then = (line.if.then||[]).map(toEditableScriptLine);
|
||||
base.else = (line.if.else||[]).map(toEditableScriptLine);
|
||||
} else if ("select" in line) {
|
||||
base.kind = "select";
|
||||
Object.assign(base, toMatchKindValue(line.select.match));
|
||||
base.then = line.select.then.map(toEditableScriptLine);
|
||||
base.then = (line.select.then||[]).map(toEditableScriptLine);
|
||||
} else if ("set" in line) {
|
||||
base.kind = "set";
|
||||
base.key = line.set.key
|
||||
|
||||
Binary file not shown.
@@ -348,7 +348,7 @@ func (b *Bridge) SetStates(patch map[string]device.State) {
|
||||
func (b *Bridge) Run(ctx context.Context, bus *lucifer3.EventBus) interface{} {
|
||||
hwEvents, err := b.RefreshAll()
|
||||
if err != nil {
|
||||
return errors.New("failed to connect to bridge")
|
||||
return fmt.Errorf("failed to connect to bridge: %s", err)
|
||||
}
|
||||
|
||||
bus.RunEvent(events.Log{
|
||||
|
||||
Reference in New Issue
Block a user