@record-evolution/widget-switch 1.0.5 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/widget-switch.d.ts +1 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/widget-switch.js +34 -37
- package/dist/widget-switch.js.map +1 -1
- package/package.json +1 -1
- package/src/default-data.json +10 -20
- package/src/definition-schema.d.ts +19 -31
- package/src/definition-schema.json +29 -47
- package/src/widget-switch.ts +28 -33
package/package.json
CHANGED
package/src/default-data.json
CHANGED
|
@@ -8,19 +8,14 @@
|
|
|
8
8
|
"on": ">=1",
|
|
9
9
|
"off": "<1"
|
|
10
10
|
},
|
|
11
|
+
"value": 1,
|
|
12
|
+
"actionApp": "machineControlApp",
|
|
13
|
+
"actionDevice": 1,
|
|
14
|
+
"actionTopic": "lamp",
|
|
11
15
|
"styling": {
|
|
12
16
|
"labelColor": "#000000",
|
|
13
17
|
"valueColor": "#00cc66"
|
|
14
|
-
}
|
|
15
|
-
"data": [
|
|
16
|
-
{
|
|
17
|
-
"tsp": "2025-07-15T10:00:00.000Z",
|
|
18
|
-
"value": 1,
|
|
19
|
-
"actionApp": "machineControlApp",
|
|
20
|
-
"actionDevice": 1,
|
|
21
|
-
"actionTopic": "lamp"
|
|
22
|
-
}
|
|
23
|
-
]
|
|
18
|
+
}
|
|
24
19
|
},
|
|
25
20
|
{
|
|
26
21
|
"label": "Cooling",
|
|
@@ -28,19 +23,14 @@
|
|
|
28
23
|
"on": "COOL_ON,1",
|
|
29
24
|
"off": "COOL_OFF,0"
|
|
30
25
|
},
|
|
26
|
+
"value": "COOL_ON",
|
|
27
|
+
"actionApp": "coolingSystemApp",
|
|
28
|
+
"actionDevice": 1,
|
|
29
|
+
"actionTopic": "cooling",
|
|
31
30
|
"styling": {
|
|
32
31
|
"labelColor": "#0033cc",
|
|
33
32
|
"valueColor": "#0099ff"
|
|
34
|
-
}
|
|
35
|
-
"data": [
|
|
36
|
-
{
|
|
37
|
-
"tsp": "2025-07-15T10:05:00.000Z",
|
|
38
|
-
"value": "COOL_ON",
|
|
39
|
-
"actionApp": "coolingSystemApp",
|
|
40
|
-
"actionDevice": 1,
|
|
41
|
-
"actionTopic": "cooling"
|
|
42
|
-
}
|
|
43
|
-
]
|
|
33
|
+
}
|
|
44
34
|
}
|
|
45
35
|
]
|
|
46
36
|
}
|
|
@@ -20,33 +20,21 @@ export type ONValues = string;
|
|
|
20
20
|
*/
|
|
21
21
|
export type OFFValues = string;
|
|
22
22
|
/**
|
|
23
|
-
* Is not strictly required, but is strongly recommended to be connected to the backend column that represents the switch state. This keeps the switch state consistent with
|
|
23
|
+
* Is not strictly required, but is strongly recommended to be connected to the backend column that represents the switch state. This keeps the switch visual state consistent with its physical state.
|
|
24
24
|
*/
|
|
25
25
|
export type SwitchState = string;
|
|
26
26
|
/**
|
|
27
|
-
* The action topic that is called when clicking the switch. The arguments will be True for ON and False for OFF. Refer to
|
|
27
|
+
* The action topic that is called at the selected app at the selected device when clicking the switch. The arguments will be True for 'ON' and False for 'OFF'. Refer to the documentation of the app for available topics to call.
|
|
28
28
|
*/
|
|
29
|
-
export type
|
|
30
|
-
/**
|
|
31
|
-
* You can specify a column in the input data to autogenerate dataseries for each distinct entry in this column. E.g. if you have a table with columns [city, timestamp, temperature] and specify 'city' as split column, then you will get a value field for each city.
|
|
32
|
-
*/
|
|
33
|
-
export type SplitDataBy = string;
|
|
34
|
-
/**
|
|
35
|
-
* The data for the switch state.
|
|
36
|
-
*/
|
|
37
|
-
export type SwitchStateData = {
|
|
38
|
-
value?: SwitchState;
|
|
39
|
-
actionApp?: ActionApp;
|
|
40
|
-
actionDevice?: ActionDeviceTarget;
|
|
41
|
-
actionTopic?: ActionTopic;
|
|
42
|
-
pivot?: SplitDataBy;
|
|
43
|
-
[k: string]: unknown;
|
|
44
|
-
}[];
|
|
29
|
+
export type ActionAppTopic = string;
|
|
45
30
|
export type Switches = {
|
|
46
31
|
label?: Label;
|
|
47
32
|
stateMap?: StateMap;
|
|
33
|
+
value?: SwitchState;
|
|
34
|
+
actionDevice?: ActionDeviceTarget;
|
|
35
|
+
actionApp?: ActionApp;
|
|
36
|
+
actionTopic?: ActionAppTopic;
|
|
48
37
|
styling?: Styling;
|
|
49
|
-
data?: SwitchStateData;
|
|
50
38
|
[k: string]: unknown;
|
|
51
39
|
}[];
|
|
52
40
|
|
|
@@ -64,6 +52,18 @@ export interface StateMap {
|
|
|
64
52
|
off?: OFFValues;
|
|
65
53
|
[k: string]: unknown;
|
|
66
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* The device that should handle the click on the switch. The 'Device ID' column can be used here when using data driven mode.
|
|
57
|
+
*/
|
|
58
|
+
export interface ActionDeviceTarget {
|
|
59
|
+
[k: string]: unknown;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The app that should handle the click on the switch.
|
|
63
|
+
*/
|
|
64
|
+
export interface ActionApp {
|
|
65
|
+
[k: string]: unknown;
|
|
66
|
+
}
|
|
67
67
|
export interface Styling {
|
|
68
68
|
labelColor?: LabelColor;
|
|
69
69
|
valueColor?: ValueColor;
|
|
@@ -75,15 +75,3 @@ export interface LabelColor {
|
|
|
75
75
|
export interface ValueColor {
|
|
76
76
|
[k: string]: unknown;
|
|
77
77
|
}
|
|
78
|
-
/**
|
|
79
|
-
* The app that should handle the click on the switch.
|
|
80
|
-
*/
|
|
81
|
-
export interface ActionApp {
|
|
82
|
-
[k: string]: unknown;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* The device that should handele the click on the switch. The 'Device ID' column can be used here when using data driven mode.
|
|
86
|
-
*/
|
|
87
|
-
export interface ActionDeviceTarget {
|
|
88
|
-
[k: string]: unknown;
|
|
89
|
-
}
|
|
@@ -15,8 +15,7 @@
|
|
|
15
15
|
"dataseries": {
|
|
16
16
|
"title": "Switches",
|
|
17
17
|
"type": "array",
|
|
18
|
-
"
|
|
19
|
-
"order": 2,
|
|
18
|
+
"order": 3,
|
|
20
19
|
"items": {
|
|
21
20
|
"type": "object",
|
|
22
21
|
"properties": {
|
|
@@ -31,7 +30,7 @@
|
|
|
31
30
|
"description": "Specify the values for the ON and OFF states. Any value that does not match to either an ON or OFF state will be considered as UNKNOWN.",
|
|
32
31
|
"type": "object",
|
|
33
32
|
"required": true,
|
|
34
|
-
"order":
|
|
33
|
+
"order": 2,
|
|
35
34
|
"properties": {
|
|
36
35
|
"on": {
|
|
37
36
|
"title": "ON Values",
|
|
@@ -47,11 +46,37 @@
|
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
48
|
},
|
|
49
|
+
"value": {
|
|
50
|
+
"title": "Switch State",
|
|
51
|
+
"type": "string",
|
|
52
|
+
"description": "Is not strictly required, but is strongly recommended to be connected to the backend column that represents the switch state. This keeps the switch visual state consistent with its physical state.",
|
|
53
|
+
"required": false,
|
|
54
|
+
"order": 3
|
|
55
|
+
},
|
|
56
|
+
"actionDevice": {
|
|
57
|
+
"title": "Action Device Target",
|
|
58
|
+
"description": "The device that should handle the click on the switch. The 'Device ID' column can be used here when using data driven mode.",
|
|
59
|
+
"type": "actionDevice",
|
|
60
|
+
"order": 4
|
|
61
|
+
},
|
|
62
|
+
"actionApp": {
|
|
63
|
+
"title": "Action App",
|
|
64
|
+
"description": "The app that should handle the click on the switch.",
|
|
65
|
+
"dataDrivenDisabled": true,
|
|
66
|
+
"type": "actionApp",
|
|
67
|
+
"order": 5
|
|
68
|
+
},
|
|
69
|
+
"actionTopic": {
|
|
70
|
+
"title": "Action App Topic",
|
|
71
|
+
"description": "The action topic that is called at the selected app at the selected device when clicking the switch. The arguments will be True for 'ON' and False for 'OFF'. Refer to the documentation of the app for available topics to call.",
|
|
72
|
+
"type": "string",
|
|
73
|
+
"order": 6
|
|
74
|
+
},
|
|
50
75
|
"styling": {
|
|
51
76
|
"title": "Styling",
|
|
52
77
|
"description": "",
|
|
53
78
|
"type": "object",
|
|
54
|
-
"order":
|
|
79
|
+
"order": 9,
|
|
55
80
|
"properties": {
|
|
56
81
|
"labelColor": {
|
|
57
82
|
"title": "Label Color",
|
|
@@ -66,49 +91,6 @@
|
|
|
66
91
|
"order": 5
|
|
67
92
|
}
|
|
68
93
|
}
|
|
69
|
-
},
|
|
70
|
-
"data": {
|
|
71
|
-
"title": "Switch State Data",
|
|
72
|
-
"description": "The data for the switch state.",
|
|
73
|
-
"type": "array",
|
|
74
|
-
"order": 4,
|
|
75
|
-
"items": {
|
|
76
|
-
"type": "object",
|
|
77
|
-
"properties": {
|
|
78
|
-
"value": {
|
|
79
|
-
"title": "Switch State",
|
|
80
|
-
"type": "string",
|
|
81
|
-
"description": "Is not strictly required, but is strongly recommended to be connected to the backend column that represents the switch state. This keeps the switch state consistent with the backend data.",
|
|
82
|
-
"required": false,
|
|
83
|
-
"order": 2
|
|
84
|
-
},
|
|
85
|
-
"actionApp": {
|
|
86
|
-
"title": "Action App",
|
|
87
|
-
"description": "The app that should handle the click on the switch.",
|
|
88
|
-
"dataDrivenDisabled": true,
|
|
89
|
-
"type": "actionApp",
|
|
90
|
-
"order": 3
|
|
91
|
-
},
|
|
92
|
-
"actionDevice": {
|
|
93
|
-
"title": "Action Device Target",
|
|
94
|
-
"description": "The device that should handele the click on the switch. The 'Device ID' column can be used here when using data driven mode.",
|
|
95
|
-
"type": "actionDevice",
|
|
96
|
-
"order": 4
|
|
97
|
-
},
|
|
98
|
-
"actionTopic": {
|
|
99
|
-
"title": "Action Topic",
|
|
100
|
-
"description": "The action topic that is called when clicking the switch. The arguments will be True for ON and False for OFF. Refer to your chosen apps documentation for available topics to call.",
|
|
101
|
-
"type": "string",
|
|
102
|
-
"order": 5
|
|
103
|
-
},
|
|
104
|
-
"pivot": {
|
|
105
|
-
"title": "Split Data by",
|
|
106
|
-
"description": "You can specify a column in the input data to autogenerate dataseries for each distinct entry in this column. E.g. if you have a table with columns [city, timestamp, temperature] and specify 'city' as split column, then you will get a value field for each city.",
|
|
107
|
-
"type": "string",
|
|
108
|
-
"order": 6
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
94
|
}
|
|
113
95
|
}
|
|
114
96
|
}
|
package/src/widget-switch.ts
CHANGED
|
@@ -6,7 +6,6 @@ import '@material/web/switch/switch.js'
|
|
|
6
6
|
import { MdSwitch } from '@material/web/switch/switch.js'
|
|
7
7
|
|
|
8
8
|
type Dataseries = Exclude<InputData['dataseries'], undefined>[number] & { needleValue?: number }
|
|
9
|
-
type Data = Exclude<Dataseries['data'], undefined>[number]
|
|
10
9
|
type Theme = {
|
|
11
10
|
theme_name: string
|
|
12
11
|
theme_object: any
|
|
@@ -90,83 +89,79 @@ export class WidgetSwitch extends LitElement {
|
|
|
90
89
|
this.dataSets = new Map()
|
|
91
90
|
this.inputData?.dataseries
|
|
92
91
|
// ?.sort((a, b) => a.order - b.order)
|
|
93
|
-
?.forEach((ds) => {
|
|
92
|
+
?.forEach((ds, idx) => {
|
|
94
93
|
// pivot data
|
|
95
|
-
const distincts = [...new Set(ds.data?.map((d: Data) => d.pivot))].sort() as string[]
|
|
96
94
|
ds.selected = undefined
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
selected: this.isSelected(ds, value)
|
|
112
|
-
}
|
|
113
|
-
this.dataSets.set(pds.label ?? '', pds)
|
|
114
|
-
})
|
|
95
|
+
let label = ds.label
|
|
96
|
+
if (this.dataSets.has(label ?? '')) {
|
|
97
|
+
label += '-' + idx
|
|
98
|
+
}
|
|
99
|
+
const pds: Dataseries = {
|
|
100
|
+
label: label,
|
|
101
|
+
actionApp: ds?.actionApp,
|
|
102
|
+
actionDevice: ds?.actionDevice,
|
|
103
|
+
actionTopic: ds?.actionTopic,
|
|
104
|
+
multiChart: ds.multiChart,
|
|
105
|
+
styling: ds.styling,
|
|
106
|
+
selected: this.isSelected(ds)
|
|
107
|
+
}
|
|
108
|
+
this.dataSets.set(pds.label ?? '', pds)
|
|
115
109
|
})
|
|
116
110
|
// console.log('Value Datasets', this.dataSets)
|
|
117
111
|
}
|
|
118
112
|
|
|
119
|
-
isSelected(ds: Dataseries
|
|
120
|
-
|
|
113
|
+
isSelected(ds: Dataseries): boolean | undefined {
|
|
114
|
+
const value = ds.value
|
|
115
|
+
if (value === undefined) return undefined
|
|
121
116
|
const on = ds?.stateMap?.on
|
|
122
117
|
if (on?.startsWith('<=')) {
|
|
123
|
-
const val = parseFloat(value
|
|
118
|
+
const val = parseFloat(value ?? '')
|
|
124
119
|
const comp = parseFloat(on.substring(2))
|
|
125
120
|
return isNaN(val) || isNaN(comp) ? undefined : val <= comp
|
|
126
121
|
}
|
|
127
122
|
if (on?.startsWith('<')) {
|
|
128
|
-
const val = parseFloat(value
|
|
123
|
+
const val = parseFloat(value ?? '')
|
|
129
124
|
const comp = parseFloat(on.substring(1))
|
|
130
125
|
return isNaN(val) || isNaN(comp) ? undefined : val < comp
|
|
131
126
|
}
|
|
132
127
|
if (on?.startsWith('>=')) {
|
|
133
|
-
const val = parseFloat(value
|
|
128
|
+
const val = parseFloat(value ?? '')
|
|
134
129
|
const comp = parseFloat(on.substring(2))
|
|
135
130
|
return isNaN(val) || isNaN(comp) ? undefined : val >= comp
|
|
136
131
|
}
|
|
137
132
|
if (on?.startsWith('>')) {
|
|
138
|
-
const val = parseFloat(value
|
|
133
|
+
const val = parseFloat(value ?? '')
|
|
139
134
|
const comp = parseFloat(on.substring(1))
|
|
140
135
|
return isNaN(val) || isNaN(comp) ? undefined : val > comp
|
|
141
136
|
}
|
|
142
137
|
|
|
143
138
|
const off = ds?.stateMap?.off
|
|
144
139
|
if (off?.startsWith('<=')) {
|
|
145
|
-
const val = parseFloat(value
|
|
140
|
+
const val = parseFloat(value ?? '')
|
|
146
141
|
const comp = parseFloat(off.substring(2))
|
|
147
142
|
return isNaN(val) || isNaN(comp) ? undefined : val > comp
|
|
148
143
|
}
|
|
149
144
|
if (off?.startsWith('<')) {
|
|
150
|
-
const val = parseFloat(value
|
|
145
|
+
const val = parseFloat(value ?? '')
|
|
151
146
|
const comp = parseFloat(off.substring(1))
|
|
152
147
|
return isNaN(val) || isNaN(comp) ? undefined : val <= comp
|
|
153
148
|
}
|
|
154
149
|
if (off?.startsWith('>=')) {
|
|
155
|
-
const val = parseFloat(value
|
|
150
|
+
const val = parseFloat(value ?? '')
|
|
156
151
|
const comp = parseFloat(off.substring(2))
|
|
157
152
|
return isNaN(val) || isNaN(comp) ? undefined : val < comp
|
|
158
153
|
}
|
|
159
154
|
if (off?.startsWith('>')) {
|
|
160
|
-
const val = parseFloat(value
|
|
155
|
+
const val = parseFloat(value ?? '')
|
|
161
156
|
const comp = parseFloat(off.substring(1))
|
|
162
157
|
return isNaN(val) || isNaN(comp) ? undefined : val <= comp
|
|
163
158
|
}
|
|
164
159
|
|
|
165
160
|
const onValues = on?.split(',').map((v) => v.trim().replace('"', '').replace("'", '')) ?? []
|
|
166
|
-
if (onValues.includes(String(value
|
|
161
|
+
if (onValues.includes(String(value) ?? '')) return true
|
|
167
162
|
|
|
168
163
|
const offValues = off?.split(',').map((v) => v.trim().replace('"', '').replace("'", '')) ?? []
|
|
169
|
-
if (offValues.includes(String(value
|
|
164
|
+
if (offValues.includes(String(value) ?? '')) return false
|
|
170
165
|
|
|
171
166
|
return undefined
|
|
172
167
|
}
|