import { h } from 'preact'; import { useState, useEffect } from 'preact/hooks'; import { getSignalStore } from '../lib/stores'; import type { Widget, SignalValue } from '../lib/types'; const DEFAULT_VALUE: SignalValue = { value: null, quality: 'unknown', ts: null }; function getBit(val: number, bit: number): boolean { return (val & (1 << bit)) !== 0; } interface Props { widget: Widget; onContextMenu?: (e: MouseEvent) => void; } export default function MultiLed({ widget, onContextMenu }: Props) { const sigRef = widget.signals[0]; const [sv, setSv] = useState(DEFAULT_VALUE); useEffect(() => { if (!sigRef) return; const unsub = getSignalStore(sigRef).subscribe(setSv); return unsub; }, [sigRef?.ds, sigRef?.name]); const bits = parseInt(widget.options['bits'] ?? '8', 10); const labelsRaw = widget.options['labels'] ?? ''; const colorsTrueRaw = widget.options['colorsTrue'] ?? ''; const colorsFalseRaw = widget.options['colorsFalse'] ?? ''; const labelArr = labelsRaw ? labelsRaw.split(',') : []; const colorsTrueArr = colorsTrueRaw ? colorsTrueRaw.split(',') : []; const colorsFalseArr = colorsFalseRaw ? colorsFalseRaw.split(',') : []; const quality = sv.quality; const isUncertain = quality === 'uncertain' || quality === 'unknown'; const rawV = sv.value; const intValue = rawV === null || rawV === undefined ? 0 : typeof rawV === 'number' ? Math.floor(rawV) : parseInt(String(rawV), 10); const bitStates = Array.from({ length: bits }, (_, i) => getBit(intValue, i)); return (
{bitStates.map((on, i) => { const trueColor = colorsTrueArr[i] ?? '#22c55e'; const falseColor = colorsFalseArr[i] ?? '#ef4444'; const color = on ? trueColor : falseColor; const bitLabel = labelArr[i] ?? String(i); return (
{bitLabel}
); })}
); }