Symptom

KrillApp.Trigger.Color nodes never fired downstream observers regardless of whether the observed COLOR DataPoint’s value fell inside the configured RGB bounding box. Static threshold triggers (HighThreshold, LowThreshold) worked correctly.

Root cause

ServerTriggerProcessor.process() opened with val meta = node.meta as TriggerMetaData. For a Color trigger, node.meta is ColorTriggerMetaData — a different data class that also implements SourceMetaData but is not a subtype of TriggerMetaData. The cast throws ClassCastException, which launchProcessing catches and routes to nodeManager.failed() — the trigger silently enters NodeState.ERROR on every invocation and never calls succeeded(). The when (node.type) block with its else -> {} arm was never reached.

Fix

In server/src/jvmMain/kotlin/krill/zone/server/krillapp/trigger/ServerTriggerProcessor.kt: added an early-return branch at the top of the launchProcessing block that handles KrillApp.Trigger.Color before the TriggerMetaData cast. The branch casts node.meta to ColorTriggerMetaData, reads the source node’s snapshot.value as a packed-RGB Long (0xRRGGBB decimal string), unpacks the R/G/B channels via bit shifts, and calls nodeManager.succeeded(node) when all three channels fall within their configured [min, max] ranges. Added import krill.zone.shared.krillapp.trigger.color.* to the processor’s imports.

Prevention