<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Reference on EdS</title><link>https://cdeever.github.io/eds/docs/reference/</link><description>Recent content in Reference on EdS</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://cdeever.github.io/eds/docs/reference/index.xml" rel="self" type="application/rss+xml"/><item><title>Scene Descriptor</title><link>https://cdeever.github.io/eds/docs/reference/scene-descriptor/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/reference/scene-descriptor/</guid><description>&lt;h1 id="scene-descriptor"&gt;Scene Descriptor&lt;a class="anchor" href="#scene-descriptor"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;The payload &lt;code&gt;lightd&lt;/code&gt; publishes and the LP stand renders. It is a description of&#10;&lt;em&gt;what to render&lt;/em&gt;, never a frame.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;v&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;effect&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;breathe&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;speed&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.4&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;brightness&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.8&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;palette&amp;#34;&lt;/span&gt;: [&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#f92672"&gt;&amp;#34;rgb&amp;#34;&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;232&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;77&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;], &lt;span style="color:#f92672"&gt;&amp;#34;weight&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.5594&lt;/span&gt; },&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#f92672"&gt;&amp;#34;rgb&amp;#34;&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;182&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;159&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;], &lt;span style="color:#f92672"&gt;&amp;#34;weight&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.3661&lt;/span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Field&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Type&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Meaning&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;v&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;int&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Contract version. Currently &lt;code&gt;1&lt;/code&gt;.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;effect&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;string&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;solid&lt;/code&gt;, &lt;code&gt;breathe&lt;/code&gt;, &lt;code&gt;sweep&lt;/code&gt;, &lt;code&gt;morph&lt;/code&gt;, &lt;code&gt;chase&lt;/code&gt; or &lt;code&gt;scanner&lt;/code&gt;.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;speed&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;float&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;0..1&lt;/code&gt; dial, not a frequency.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;brightness&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;float&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;0..1&lt;/code&gt;, applied before gamma on the device.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;palette&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;array&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Colors already corrected for the strip, ranked by weight.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;palette[].rgb&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;[int, int, int]&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;sRGB, 0–255. Gamma is &lt;strong&gt;not&lt;/strong&gt; applied.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;palette[].weight&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;float&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Share of the scene. Renormalized after filtering.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="version-handling"&gt;Version handling&lt;a class="anchor" href="#version-handling"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;A scene carrying a different &lt;code&gt;v&lt;/code&gt; is &lt;strong&gt;refused, not guessed at&lt;/strong&gt;. A scene that is&#10;malformed or unparseable is &lt;strong&gt;ignored&lt;/strong&gt;, and the previously rendering scene&#10;keeps running — a stand that goes dark on a bad payload is worse than one that&#10;ignores it.&lt;/p&gt;</description></item><item><title>Palette API</title><link>https://cdeever.github.io/eds/docs/reference/palette-api/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/reference/palette-api/</guid><description>&lt;h1 id="palette-api"&gt;Palette API&lt;a class="anchor" href="#palette-api"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;&lt;code&gt;POST /v1/palette&lt;/code&gt; — image bytes in, ranked color swatches out.&lt;/p&gt;&#10;&lt;p&gt;Accepts either a multipart upload or a raw body. Both return the same result:&#10;multipart is what a person uses, the raw body is what &lt;code&gt;lightd&lt;/code&gt; uses.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl -F image&lt;span style="color:#f92672"&gt;=&lt;/span&gt;@jacket.jpg &lt;span style="color:#e6db74"&gt;&amp;#39;http://localhost:8731/v1/palette?n=5&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl --data-binary @jacket.jpg -H &lt;span style="color:#e6db74"&gt;&amp;#39;Content-Type: image/png&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;http://localhost:8731/v1/palette&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;GET /openapi.json&lt;/code&gt; publishes the schema, which is how the contract stays&#10;honest across the Python/Go boundary.&lt;/p&gt;&#10;&lt;h2 id="parameters"&gt;Parameters&lt;a class="anchor" href="#parameters"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Name&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Type&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Default&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;n&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;int, 1–16&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;6&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Swatches to return.&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="response"&gt;Response&lt;a class="anchor" href="#response"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;v&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;swatches&amp;#34;&lt;/span&gt;: [&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#f92672"&gt;&amp;#34;rgb&amp;#34;&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;225&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;82&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;26&lt;/span&gt;], &lt;span style="color:#f92672"&gt;&amp;#34;hex&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;#e1521a&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;oklab&amp;#34;&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;0.6264&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.147&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0.1184&lt;/span&gt;],&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;weight&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.3705&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;#34;chroma&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.1888&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;#34;lightness&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.6264&lt;/span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;background_dropped&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.8855&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;fallback&amp;#34;&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;source&amp;#34;&lt;/span&gt;: { &lt;span style="color:#f92672"&gt;&amp;#34;width&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;600&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;#34;height&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;600&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;#34;format&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;jpeg&amp;#34;&lt;/span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;dl&gt;&#10;&lt;dt&gt;&lt;code&gt;weight&lt;/code&gt;&lt;/dt&gt;&#10;&lt;dd&gt;Share of clustered pixels, so swatches are ranked by how much of the sleeve&#10;they actually cover.&lt;/dd&gt;&#10;&lt;dt&gt;&lt;code&gt;background_dropped&lt;/code&gt;&lt;/dt&gt;&#10;&lt;dd&gt;Share of pixels discarded before clustering.&lt;/dd&gt;&#10;&lt;dt&gt;&lt;code&gt;fallback&lt;/code&gt;&lt;/dt&gt;&#10;&lt;dd&gt;True when filtering removed so much that the unfiltered image was used&#10;instead. Genuinely monochrome art sets this rather than returning nothing.&lt;/dd&gt;&#10;&lt;dt&gt;&lt;code&gt;chroma&lt;/code&gt;&lt;/dt&gt;&#10;&lt;dd&gt;How far the color is from neutral. &lt;strong&gt;Consumers should treat a low-chroma&#10;swatch as unfit to drive a strip regardless of its weight&lt;/strong&gt; — see below.&lt;/dd&gt;&#10;&lt;/dl&gt;&#10;&lt;h2 id="known-characteristics"&gt;Known characteristics&lt;a class="anchor" href="#known-characteristics"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;Low &lt;code&gt;n&lt;/code&gt; on busy art returns low-chroma centroids.&lt;/strong&gt; Asking for 2 swatches&#10;from a four-color sleeve forces one cluster to merge three of them, and the&#10;merged centroid is close to their average. This is arithmetic, not a bug — but&#10;it is why &lt;code&gt;chroma&lt;/code&gt; is in the contract. The default &lt;code&gt;n=6&lt;/code&gt; avoids the situation&#10;for most art.&lt;/p&gt;</description></item><item><title>MQTT Topics</title><link>https://cdeever.github.io/eds/docs/reference/mqtt-topics/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/reference/mqtt-topics/</guid><description>&lt;h1 id="mqtt-topics"&gt;MQTT Topics&lt;a class="anchor" href="#mqtt-topics"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;The topic prefix defaults to &lt;code&gt;eds&lt;/code&gt; and must match on both sides — &lt;code&gt;lightd&lt;/code&gt;&amp;rsquo;s&#10;&lt;code&gt;LIGHTD_TOPIC_PREFIX&lt;/code&gt; and the firmware&amp;rsquo;s &lt;code&gt;LP_TOPIC_PREFIX&lt;/code&gt;.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Topic&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Direction&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Retained&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/lightstand/&amp;lt;id&amp;gt;/scene&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;lightd → device&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;yes&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;what to render&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/lightstand/&amp;lt;id&amp;gt;/status&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;device → broker&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes (LWT)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;online&lt;/code&gt; / &lt;code&gt;offline&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/lightstand/&amp;lt;id&amp;gt;/state&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;device → broker&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;what it is rendering now&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/lightd/status&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;lightd → broker&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes (LWT)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the publisher&amp;rsquo;s presence&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/console/status&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;console → broker&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes (LWT)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the console&amp;rsquo;s presence; the only thing it publishes&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/log/&amp;lt;id&amp;gt;&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;device or agent Pi → broker&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;no&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;key events, for the log store: the stand&amp;rsquo;s, the cover screen&amp;rsquo;s, the power beacon&amp;rsquo;s, and the now-playing agent&amp;rsquo;s (&lt;code&gt;np-relay&lt;/code&gt;)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/nowplaying/source/&amp;lt;id&amp;gt;/…&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;a driver → nowplayd&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;what one player is doing; see &lt;a href="../now-playing/"&gt;Now Playing&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/nowplaying/current&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nowplayd → subscribers&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the one current track&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/nowplaying/current/art&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nowplayd → subscribers&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;its cover, as image bytes; lightd lights the stand from it&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/nowplaying/current/art/small&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nowplayd → subscribers&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the same cover at 240 pixels, as a baseline JPEG; the cover screen shows it&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/nowplaying/command&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;a controller → nowplayd&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;never&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;a button press, for whatever is current; see &lt;a href="../now-playing/#commands#commands"&gt;Now Playing&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/nowplaying/source/&amp;lt;id&amp;gt;/command&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nowplayd → a driver&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;never&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the same press, passed to the current source; &lt;code&gt;play_album&lt;/code&gt; to &lt;code&gt;NP_ALBUM_SOURCE&lt;/code&gt; whatever is current (ADR-0040)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/voice/&amp;lt;device&amp;gt;/utterance&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;device → voiced&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;never&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;what followed the wake word: a WAV, 16 kHz 16-bit mono, at most 15 s (ADR-0042)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/voice/&amp;lt;device&amp;gt;/woken&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;device → voiced&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;never&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;{&amp;quot;v&amp;quot;:1}&lt;/code&gt;: the wake word was just heard, so the music is turned down (ADR-0044)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/voice/&amp;lt;device&amp;gt;/heard&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;voiced → device, console&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;never&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;{&amp;quot;v&amp;quot;:1,&amp;quot;text&amp;quot;,&amp;quot;understood&amp;quot;,&amp;quot;artist&amp;quot;,&amp;quot;album&amp;quot;,&amp;quot;reason&amp;quot;}&lt;/code&gt;: what was made of the request&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/voiced/status&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;voiced → broker&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes (LWT)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;its presence&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/screen/&amp;lt;id&amp;gt;/status&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;device → broker&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes (LWT)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the cover screen&amp;rsquo;s presence&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/beacon/&amp;lt;id&amp;gt;/status&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;device → broker&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes (LWT)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;whether the switch a beacon is on has power: &lt;code&gt;online&lt;/code&gt; while it does, the will&amp;rsquo;s &lt;code&gt;offline&lt;/code&gt; when it has not. nowplayd reads the one that speaks for the turntable (&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0023-a-source-that-is-switched-on-holds-the-stand/"&gt;ADR-0023&lt;/a&gt;)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/nowplaying/current/look&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nowplayd → lightd&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;whether that cover&amp;rsquo;s album has a look of its own, by name; see &lt;a href="../now-playing/#looks#looks"&gt;Now Playing&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds/nowplaying/stand&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;console → nowplayd&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes, as a setting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;which sources the stand is lit for: &lt;code&gt;{&amp;quot;v&amp;quot;:1,&amp;quot;sources&amp;quot;:&amp;quot;records&amp;quot;}&lt;/code&gt;, the default, or &lt;code&gt;&amp;quot;all&amp;quot;&lt;/code&gt; (&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0039-the-console-can-light-the-stand-for-every-source/"&gt;ADR-0039&lt;/a&gt;)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="the-log-topic"&gt;The log topic&lt;a class="anchor" href="#the-log-topic"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;eds/log/&amp;lt;id&amp;gt;&lt;/code&gt; is not EdS&amp;rsquo;s own layout. &lt;code&gt;&amp;lt;tenant&amp;gt;/log/&amp;lt;device&amp;gt;&lt;/code&gt; is the one&#10;topic under &lt;code&gt;log/&lt;/code&gt; Deevnet IoTaaS lets a device account publish, and its log&#10;bridge carries what arrives there into the tenant&amp;rsquo;s device log partition. The&#10;stand sends one JSON object per event — boot, network, scenes, health — at&#10;QoS 1 and &lt;strong&gt;not retained&lt;/strong&gt;: a log line replayed to every new subscriber would&#10;be an event that never happened again.&lt;/p&gt;</description></item><item><title>Configuration</title><link>https://cdeever.github.io/eds/docs/reference/configuration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/reference/configuration/</guid><description>&lt;h1 id="configuration"&gt;Configuration&lt;a class="anchor" href="#configuration"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;h2 id="lightd"&gt;lightd&lt;a class="anchor" href="#lightd"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;All environment, no config file: the broker credentials must never land on disk&#10;in a repository, and the same binary has to work under a systemd unit or a&#10;container without knowing which.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Variable&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Default&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_ADDR&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;:8732&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;listen address&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_PALETTE_URL&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;http://127.0.0.1:8731&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;palette service&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_STAND_ID&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;lp-stand-01&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;default stand&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_COVER_TOPIC&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;unset&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;a topic of cover images to light the stand from, relative to the prefix, e.g. &lt;code&gt;nowplaying/current/art&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_LOOK_TOPIC&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;unset&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;a topic that says which covers have a look of their own, e.g. &lt;code&gt;nowplaying/current/look&lt;/code&gt;. Needs &lt;code&gt;LIGHTD_COVER_TOPIC&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_SPECTRUM_EFFECT&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;sweep&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;how the &lt;code&gt;spectrum&lt;/code&gt; look moves: &lt;code&gt;sweep&lt;/code&gt;, the rainbow around the strip, or &lt;code&gt;morph&lt;/code&gt;, each color in turn. Anything else stops the daemon&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_TOPIC_PREFIX&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;eds&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;root of the topic tree&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_MQTT_URL&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;tcp://127.0.0.1:1883&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;tls://mqtt01…:8883&lt;/code&gt; in production&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_MQTT_USERNAME&lt;/code&gt; / &lt;code&gt;_PASSWORD&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;—&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;broker credentials&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_MQTT_CA_FILE&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;—&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;CA for the broker&amp;rsquo;s certificate&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_MQTT_INSECURE&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;bring-up only; never with a real cert&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_EFFECT&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;breathe&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;default effect: &lt;code&gt;solid&lt;/code&gt;, &lt;code&gt;breathe&lt;/code&gt;, &lt;code&gt;sweep&lt;/code&gt;, &lt;code&gt;morph&lt;/code&gt;, &lt;code&gt;chase&lt;/code&gt; or &lt;code&gt;scanner&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_SPEED&lt;/code&gt; / &lt;code&gt;LIGHTD_BRIGHTNESS&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;0.4&lt;/code&gt; / &lt;code&gt;0.8&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_SWATCHES&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;6&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;swatches requested from palette&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_MIN_CHROMA&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;0.05&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;below this a swatch is a gray&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_SATURATION&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;1.25&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;chroma multiplier for the strip&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;LIGHTD_MAX_COLORS&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;palette entries per scene&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;&lt;strong&gt;Invalid values stop the daemon&lt;/strong&gt; rather than lighting the room wrong quietly.&lt;/p&gt;</description></item><item><title>Now Playing</title><link>https://cdeever.github.io/eds/docs/reference/now-playing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cdeever.github.io/eds/docs/reference/now-playing/</guid><description>&lt;h1 id="now-playing"&gt;Now Playing&lt;a class="anchor" href="#now-playing"&gt;&lt;/a&gt;&lt;/h1&gt;&#10;&lt;p&gt;The contract between the programs that know what is playing and the programs&#10;that react to it. It is version &lt;strong&gt;1&lt;/strong&gt;, stamped on every message as &lt;code&gt;&amp;quot;v&amp;quot;: 1&lt;/code&gt;,&#10;and a message with any other version is refused rather than guessed at.&lt;/p&gt;&#10;&lt;p&gt;Why it is shaped this way:&#10;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0006-now-playing-bus-of-drivers/"&gt;ADR-0006&lt;/a&gt; and&#10;&lt;a href="https://cdeever.github.io/eds/docs/architecture/decisions/0008-nowplayd-arbitrates-and-enriches/"&gt;ADR-0008&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="topics"&gt;Topics&lt;a class="anchor" href="#topics"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;All under the tenant&amp;rsquo;s prefix, &lt;code&gt;eds/&lt;/code&gt;.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Topic&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;From&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Retained&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Payload&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;nowplaying/source/&amp;lt;id&amp;gt;/state&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;a driver&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;what that player is doing&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;nowplaying/source/&amp;lt;id&amp;gt;/status&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;a driver&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes (last will)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;online&lt;/code&gt; / &lt;code&gt;offline&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;nowplaying/source/&amp;lt;id&amp;gt;/art&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;a driver&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the cover, as image bytes&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;nowplaying/current&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nowplayd&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the one current track&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;nowplaying/current/art&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nowplayd&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;its cover, as image bytes&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;nowplaying/current/art/small&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nowplayd&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the same cover, small: a baseline JPEG, 240 pixels on its longer side&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;nowplaying/current/look&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nowplayd&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;whether that cover&amp;rsquo;s album has a look of its own; with no cover, whether the room is waiting for one&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;nowplaying/stand&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the console&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;which sources the stand is lit for: &lt;code&gt;records&lt;/code&gt; or &lt;code&gt;all&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;nowplaying/command&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;a controller&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;never&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;a button press, for whatever is current&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;nowplaying/source/&amp;lt;id&amp;gt;/command&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nowplayd&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;never&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;that press, passed to the current source&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;nowplaying/source/spotify/switch&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the console&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;whether the Spotify driver runs: &lt;code&gt;on&lt;/code&gt; or &lt;code&gt;off&lt;/code&gt;, and nothing is &lt;code&gt;off&lt;/code&gt; (ADR-0051)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;nowplaying/status&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nowplayd&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;yes (last will)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;online&lt;/code&gt; / &lt;code&gt;offline&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;&lt;code&gt;&amp;lt;id&amp;gt;&lt;/code&gt; names one driver deployment, such as &lt;code&gt;itunes-den&lt;/code&gt;. It is lowercase&#10;letters, digits and hyphens, at most 63 characters, starting with a letter or&#10;digit.&lt;/p&gt;</description></item></channel></rss>