Hey @BennyTheBassman, welcome to the forum!
The way around this is to track the state yourself in a shared variable, and have one button flip that variable and fire the command at the same time. That means switching your button from OSC to Script.
Script on Press
// Flip our own state, then toggle the override
setShared("lineOverride", !shared("lineOverride", false));
sendOsc("/devices/setLineOverride", "all", "toggle");
Dynamic Background Color
Enable the Dynamic toggle under Background Color, then paste this in:
${shared("lineOverride", false) ? "red-600" : "green-800"}
That’s your ternary — just checking the shared variable instead of an osc() call.
One small thing: green-850 isn’t a valid shade. The steps are 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950, so green-800 or green-900 is what you’re after.
Optional: dynamic label
The Label field takes the same templating, so the button can say what it’s doing:
${shared("lineOverride", false) ? "Pinned" : "Follow"}
Ready-made button
If you’d rather not build it by hand, copy this and paste it straight into your canvas:
[{"type":"button","buttonType":"script","label":"${shared(\"lineOverride\", false) ? \"Pinned\" : \"Follow\"}","textColor":{"type":"preset","color":"white"},"backgroundColor":{"type":"dynamic","template":"${shared(\"lineOverride\", false) ? \"red-600\" : \"green-800\"}"},"font":{"size":32},"width":200,"height":200,"x":100,"y":100,"zIndex":10,"scriptOnPress":"setShared(\"lineOverride\", !shared(\"lineOverride\", false));\nsendOsc(\"/devices/setLineOverride\", \"all\", \"toggle\");"}]
This behaves exactly like the anchor button in the Lyrics view, with the color following along.
Keep in mind that the shared variable only hears about toggles that go through this button. If you also pin lines with ⇧M or the anchor button inside the Lyrics view, the button’s color can end up showing the opposite of the real state. So in this case it’s recommended to make this button your only way of toggling it.
One last heads-up if you ever try the 3.2 beta: the Canvas Lyrics element gains a Line Override field there that accepts a template, controlling the same override. That opens up some nicer options than the shared-variable approach, so it’s worth a look once you’re on it.
Would that work for your use case?