Skip to content

Instantly share code, notes, and snippets.

@llandsmeer
Created February 15, 2022 16:34
Show Gist options
  • Save llandsmeer/e5de4f21923733281123543a5f70fd37 to your computer and use it in GitHub Desktop.
Save llandsmeer/e5de4f21923733281123543a5f70fd37 to your computer and use it in GitHub Desktop.
<!doctype html>
<meta charset="utf-8">
<div id=live style='overflow-wrap: break-word; font-family: monospace'></div>
<script>
class Controller {
constructor(ip) {
this.ip = ip
this.connect()
this.send_queue = []
// internal beliefs about led states - not actual if others are updating
this.old_led_state = {}
this.new_led_state = {}
setInterval(this._send_leds_update.bind(this), 10)
}
connect() {
this.socket = new WebSocket(`ws://${this.ip}/ws`)
this.socket.onopen = this.socket_onopen.bind(this)
this.socket.onmessage = this.socket_onmessage.bind(this)
this.socket.onclose = this.socket_onclose.bind(this)
this.socket.onerror = this.socket_onerror.bind(this)
this.recv_info = {}
this.recv_state = {}
this.recv_leds = {}
this.on_info = () => undefined
this.on_state = () => undefined
this.on_leds = () => undefined
this.connected = false
}
send(data) {
// {"seg":{"i":[[255,0,0], [0,255,0], [0,0,255]]}}
// {"seg":{"i":[0,[255,0,0], 2,[0,255,0], 4,[0,0,255]]}}
// {"seg":{"i":[0,8,[255,0,0], 10,18,[0,0,255]]}}
if (this.connected) {
this.socket.send(JSON.stringify(data))
} else {
this.send_queue.push(JSON.stringify(data))
}
}
set_live(is_live) {
this.send({"lv":!!is_live})
}
setf(seg, idx, r, g, b) {
this.set(seg, idx, r*255, g*255, b*255)
}
on() {
this.send({"on":true,"bri":64})
}
off() {
this.send({"on":false})
}
set(seg, idx, r, g, b) {
seg = 'seg'
// state.seg[idx].len
function clip(x, a, b) {
if (x <= a) return a;
if (x >= b) return b;
return x
}
r = clip(r|0, 0, 255)
g = clip(g|0, 0, 255)
b = clip(b|0, 0, 255)
if (!this.old_led_state[seg]) this.old_led_state[seg] = {}
let oldrgb = this.old_led_state[seg][idx]
if (!oldrgb || oldrgb[0] != r || oldrgb[1] != g || oldrgb[2] != b) {
if (!this.new_led_state[seg]) this.new_led_state[seg] = new Map()
this.new_led_state[seg].set(idx, [r, g, b])
this.old_led_state[seg][idx] = [r, g, b]
}
}
_send_leds_update() {
if (!this.new_led_state['seg']) {
return
}
let seg = []
let remove = []
for (let [idx, rgb] of this.new_led_state['seg']) {
remove.push(idx)
seg.push(idx)
seg.push(rgb)
if (remove.length >= 3) {
break
}
}
if (remove.length == 0) return
remove.forEach(idx => {
this.new_led_state['seg'].delete(idx)
})
let message = {'seg': {'i': seg}}
this.send(message)
}
socket_onopen(event) {
this.connected = true
this.send_queue.forEach(message => {
this.socket.send(message)
})
}
socket_onmessage(event) {
let data = JSON.parse(event.data)
if (data.info) {
this.recv_info = {}
this.on_info(data.info)
}
if (data.state) {
this.recv_state = {}
this.on_state(data.state)
}
if (data.leds) {
this.recv_leds = {}
this.on_leds(data.leds)
}
}
socket_onclose(event) {
this.connected = false
if (event.wasClean) {
console.warn(event)
} else {
console.error(event)
setTimeout(this.connect.bind(this), 1000)
}
}
socket_onerror(event) {
this.connected = false
console.error(event)
}
}
let wled = new Controller('192.168.1.92')
wled.on_leds = leds => {
let root = document.getElementById('live')
root.innerHTML = leds.map(c => `<span style="background-color: #${c}">${c}</span>`).join('')
wled.set_live(false)
}
wled.on()
let t = 0;
setInterval(() => {
for (let i = 0; i < 150; i+=1) {
let j = i + t
let r = Math.pow(Math.sin(j/150*6*1.1), 20)
let g = Math.pow(Math.sin(j/150*6*1.5), 20)
let b = Math.pow(Math.sin(j/150*6*1.4), 20)
if (r < 0.24) r = 0
if (g < 0.24) g = 0
if (b < 0.24) b = 0
wled.setf(0, i, r, g, b)
}
t = t + 1.5;
} , 1000 / 60)
//wled.send({"seg":{"i":[0,[255,255,255], 2,[255,255,255], 4,[0,0,255]]}})
console.log(wled)
// {"seg":{"i":[0,[255,255,255],2,[255,255,255],4,[0,0,255]]}}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment