wiki-plugin-mech 0.1.2 → 0.1.4
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/client/mech.js +69 -19
- package/factory.json +1 -1
- package/package.json +1 -1
package/client/mech.js
CHANGED
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
for (part of more) {
|
|
37
37
|
const key = `${unique}.${path.join('.')}`
|
|
38
38
|
part.key = key
|
|
39
|
-
if(part
|
|
39
|
+
if('command' in part)
|
|
40
40
|
html.push(`<span id=${key}>${expand(part.command)}</span>`)
|
|
41
|
-
else
|
|
41
|
+
else
|
|
42
42
|
html.push(`<div id=${key} style="padding-left:15px">${block(part,[...path,0])}</div> `)
|
|
43
43
|
path[path.length-1]++
|
|
44
44
|
}
|
|
@@ -48,52 +48,102 @@
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
function trouble(elem,message) {
|
|
51
|
+
if(elem.innerText.match(/✖︎/)) return
|
|
51
52
|
elem.innerHTML += `<button style="border-width:0;color:red;">✖︎</button>`
|
|
52
53
|
elem.querySelector('button').addEventListener('click',event => {
|
|
53
54
|
elem.outerHTML += `<span style="width:80%;color:gray;">${message}</span>` })
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
function click_emit (elem) {
|
|
57
|
+
function click_emit ({elem,body,state}) {
|
|
57
58
|
if(elem.innerHTML.match(/button/)) return
|
|
58
|
-
|
|
59
|
-
if (!body.length) return trouble(elem,'CLICK expects indented blocks to follow.')
|
|
59
|
+
if (!body?.length) return trouble(elem,'CLICK expects indented blocks to follow.')
|
|
60
60
|
elem.innerHTML += '<button style="border-width:0;">◉</button>'
|
|
61
|
-
elem.querySelector('button').addEventListener('click',event =>
|
|
61
|
+
elem.querySelector('button').addEventListener('click',event => {
|
|
62
|
+
state.debug = event.shiftKey
|
|
63
|
+
run(body,state)
|
|
64
|
+
})
|
|
62
65
|
}
|
|
63
66
|
|
|
64
|
-
function
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
function hello_emit (elem,what) {
|
|
68
|
-
const want = what == 'world' ? ' 🌎' : ' 😀'
|
|
67
|
+
function hello_emit ({elem,args}) {
|
|
68
|
+
const want = args[0] == 'world' ? ' 🌎' : ' 😀'
|
|
69
69
|
elem.innerHTML += want
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
function
|
|
72
|
+
function from_emit ({elem,args,body,state}) {
|
|
73
|
+
const line = elem.innerHTML
|
|
74
|
+
elem.innerHTML = line + ' ⏳'
|
|
75
|
+
fetch(`//${args[0]}.json`)
|
|
76
|
+
.then(res => res.json())
|
|
77
|
+
.then(page => {
|
|
78
|
+
state.page = page
|
|
79
|
+
elem.innerHTML = line + ' ⌛'
|
|
80
|
+
run(body,state)
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function sensor_emit ({elem,args,body,state}) {
|
|
85
|
+
const line = elem.innerHTML.replaceAll(/ ⌛/g,'')
|
|
86
|
+
if(!('page' in state)) return trouble(elem,`Expect "page" as with FROM.`)
|
|
87
|
+
const datalog = state.page.story.find(item => item.type == 'datalog')
|
|
88
|
+
if(!datalog) return trouble(elem, `Expect Datalog plugin in the page.`)
|
|
89
|
+
const want = args[0]
|
|
90
|
+
if(!want) return trouble(elem, 'SENSOR needs a sensor name.')
|
|
91
|
+
const sensor = datalog.text.split(/\n/)
|
|
92
|
+
.map(line => line.split(/ +/))
|
|
93
|
+
.filter(fields => fields[0] == 'SENSOR')
|
|
94
|
+
.find(fields => fields[1] == want)
|
|
95
|
+
if(!sensor) return trouble(elem, `Expect to find "${want}" in Datalog.`)
|
|
96
|
+
const url = sensor[2]
|
|
97
|
+
|
|
98
|
+
const f = c => 9/5*(c/16)+32
|
|
99
|
+
const avg = a => a.reduce((s,e)=>s+e,0)/a.length
|
|
100
|
+
elem.innerHTML = line + ' ⏳'
|
|
101
|
+
fetch(url)
|
|
102
|
+
.then (res => res.json())
|
|
103
|
+
.then (data => {
|
|
104
|
+
if(state.debug) console.log({sensor,data})
|
|
105
|
+
elem.innerHTML = line + ' ⌛'
|
|
106
|
+
const value = f(avg(Object.values(data)))
|
|
107
|
+
state.temperature = `${value.toFixed(2)}°F`
|
|
108
|
+
run(body,state)
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function report_emit ({elem,command,state}) {
|
|
113
|
+
const value = state?.temperature
|
|
114
|
+
if (!value) return trouble(elem,`Expect data, as from SENSOR.`)
|
|
115
|
+
elem.innerHTML = command + `<br><font face=Arial size=32>${value}</font>`
|
|
73
116
|
}
|
|
74
117
|
|
|
75
118
|
const blocks = {
|
|
76
|
-
CLICK: {emit:click_emit, bind:
|
|
77
|
-
HELLO: {emit:hello_emit, bind:
|
|
119
|
+
CLICK: {emit:click_emit, bind:null},
|
|
120
|
+
HELLO: {emit:hello_emit, bind:null},
|
|
121
|
+
FROM: {emit:from_emit, bind:null},
|
|
122
|
+
SENSOR: {emit:sensor_emit, bind:null},
|
|
123
|
+
REPORT: {emit:report_emit, bind:null}
|
|
78
124
|
}
|
|
79
125
|
|
|
80
|
-
function run (nest) {
|
|
126
|
+
function run (nest,state={}) {
|
|
81
127
|
const scope = nest.slice()
|
|
82
128
|
while (scope.length) {
|
|
83
129
|
const code = scope.shift()
|
|
84
|
-
if (code
|
|
130
|
+
if ('command' in code) {
|
|
131
|
+
const command = code.command
|
|
85
132
|
const elem = document.getElementById(code.key)
|
|
86
133
|
const [op, ...args] = code.command.split(/ +/)
|
|
87
|
-
const
|
|
134
|
+
const next = scope[0]
|
|
135
|
+
const body = next && ('command' in next) ? null : scope.shift()
|
|
136
|
+
const stuff = {command,op,args,body,elem,state}
|
|
137
|
+
if(state.debug) console.log(stuff)
|
|
88
138
|
if (blocks[op])
|
|
89
|
-
blocks[op].emit.apply(
|
|
139
|
+
blocks[op].emit.apply(null,[stuff])
|
|
90
140
|
else
|
|
91
141
|
if (op.match(/^[A-Z]+$/))
|
|
92
142
|
trouble(elem,`${op} doesn't name a block we know.`)
|
|
93
143
|
else if (code.command.match(/\S/))
|
|
94
144
|
trouble(elem, `Expected line to begin with all-caps keyword.`)
|
|
95
145
|
} else if(typeof code == 'array') {
|
|
96
|
-
run(code)
|
|
146
|
+
run(code,state)
|
|
97
147
|
}
|
|
98
148
|
}
|
|
99
149
|
}
|
package/factory.json
CHANGED