<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  
  <title>Blog</title>
  <subtitle>Neal Joslin&#39;s Blog</subtitle>
  <link href="https://blog.nealjoslin.com/atom.xml" rel="self" />
  <link href="https://blog.nealjoslin.com/" />
  <updated>2026-08-09T00:00:00Z</updated>
  <id>https://blog.nealjoslin.com/</id>
  <author>
    <name>Neal Joslin</name>
    <email>neal@joslin.io</email>
  </author>
  <entry>
    <title>Window Notification</title>
    <link href="https://blog.nealjoslin.com/posts/home_assistant/window_notification/" />
    <updated>2023-07-30T00:00:00Z</updated>
    <id>https://blog.nealjoslin.com/posts/home_assistant/window_notification/</id>
    <content type="html">&lt;!-- markdownlint-disable MD024 --&gt;
&lt;p&gt;I generally don&#39;t like AC, as I live in Michigan and I would like to
enjoy the heat while it&#39;s here. This does not mean I like to go upstairs
and have it feel like I&#39;ve opened up an oven&#39;s door. As an attempt to
reduce that uncomfortable feeling, I want to set up an automation to
notify me when I should open the windows.&lt;/p&gt;
&lt;p&gt;To do this there&#39;s two pre-reqs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A Thermostat&lt;/li&gt;
&lt;li&gt;A way to get the outside temperature, I use the National Weather Service integration&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;hardware&quot; tabindex=&quot;-1&quot;&gt;Hardware &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#hardware&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While I do own a Nest, there&#39;s a two problems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It requires the cloud, which I try to avoid&lt;/li&gt;
&lt;li&gt;It&#39;s downstairs&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Instead, I bought a
&lt;a href=&quot;https://a.co/d/euSU7kx&quot;&gt;Tuya compatible thermostat from Amazon&lt;/a&gt;. I also
use the HACS Plugin &lt;a href=&quot;https://github.com/rospogrigio/localtuya&quot;&gt;Local
Tuya&lt;/a&gt; to communicate with my
Tuya devices directly instead of through the cloud&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Be aware:&lt;/strong&gt; This thermostat with Local Tuya outputs in C, there is
extra HA configuration to get it as F.&lt;/p&gt;
&lt;h2 id=&quot;setup&quot; tabindex=&quot;-1&quot;&gt;Setup &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#setup&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Note #1:&lt;/strong&gt; I recommend connecting your Tuya API with Local Tuya. This
generally makes the install process a &lt;em&gt;little&lt;/em&gt; easier as it prefills
&lt;strong&gt;some&lt;/strong&gt; of the required fields, like Local Key.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note #2:&lt;/strong&gt; In the past month moved all my IoT devices into their own
VLAN, which doesn&#39;t support the Tuya API due to the discovery being
blocked, I&#39;m editing this section to have more detail. (2023-12-28)&lt;/p&gt;
&lt;p&gt;The process is the same as adding any device through Local Tuya. That
being entities are not fun, as generally it&#39;s a slightly informed
guessing game. There are three values: two numbers and a boolean.&lt;/p&gt;
&lt;h3 id=&quot;device-id-(iot-tuya)&quot; tabindex=&quot;-1&quot;&gt;Device ID (IoT Tuya) &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#device-id-(iot-tuya)&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Login to &lt;a href=&quot;https://auth.tuya.com/&quot;&gt;https://auth.tuya.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Sidebar, Cloud -&amp;gt; Development&lt;/li&gt;
&lt;li&gt;Table, Open Project&lt;/li&gt;
&lt;li&gt;Top bar, Devices&lt;/li&gt;
&lt;li&gt;Table, find Sensor&lt;/li&gt;
&lt;li&gt;Copy Device ID&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;local-key-(iot-tuya)&quot; tabindex=&quot;-1&quot;&gt;Local Key (IoT Tuya) &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#local-key-(iot-tuya)&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Login to &lt;a href=&quot;https://auth.tuya.com/&quot;&gt;https://auth.tuya.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Sidebar, Cloud -&amp;gt; API Explorer&lt;/li&gt;
&lt;li&gt;It should load into &lt;code&gt;IoT Core&lt;/code&gt;, else change in top left dropdown&lt;/li&gt;
&lt;li&gt;Sidebar, Device Management -&amp;gt; Query Device Details&lt;/li&gt;
&lt;li&gt;Paste &lt;code&gt;Device ID&lt;/code&gt; + Submit (hidden by a cookie warning)&lt;/li&gt;
&lt;li&gt;Find &lt;code&gt;local_key&lt;/code&gt; key in the JSON dictionary it returns&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;ha-local-tuya-add&quot; tabindex=&quot;-1&quot;&gt;HA Local Tuya Add &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#ha-local-tuya-add&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Name: &lt;code&gt;{anything}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Host: &lt;code&gt;{static_ip}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Device ID: &lt;code&gt;{saved from earlier}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Local Key: &lt;code&gt;{saved from earlier}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Protocol Version: &lt;code&gt;3.3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Submit&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;temperature&quot; tabindex=&quot;-1&quot;&gt;Temperature &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#temperature&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;The raw value is in &lt;strong&gt;C&lt;/strong&gt; and has a scaling factor of &lt;strong&gt;.1&lt;/strong&gt;, The
number will be an integer (no decimals) and will have three digits&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Name:&lt;/strong&gt; Upstairs Temperature&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unit of Measurement:&lt;/strong&gt; &lt;em&gt;blank&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Device Class:&lt;/strong&gt; temperature&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scaling:&lt;/strong&gt; .1&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;humidity&quot; tabindex=&quot;-1&quot;&gt;Humidity &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#humidity&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;I don&#39;t have an example of the raw value so use the process of elimination. I believe
it&#39;s either 0-100 or 0-.1&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Name:&lt;/strong&gt; Upstairs Humidity&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unit of Measurement:&lt;/strong&gt; %&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Device Class:&lt;/strong&gt; humidity&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scaling:&lt;/strong&gt; &lt;em&gt;blank&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;boolean&quot; tabindex=&quot;-1&quot;&gt;Boolean &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#boolean&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;I presume the boolean is &lt;code&gt;is_fahrenheit&lt;/code&gt;. This has no impact so I didn&#39;t add it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;fahrenheit&quot; tabindex=&quot;-1&quot;&gt;Fahrenheit &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#fahrenheit&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;As stated above, Temperature is &lt;strong&gt;always&lt;/strong&gt; being coming in a Celsius,
so I had to convert it into Fahrenheit for my own use by using a
sensor template&lt;/p&gt;
&lt;p&gt;I added this block to my main configuration, reloaded the
configuration and then the &lt;code&gt;upstairs_temperature_template&lt;/code&gt; entity
exists&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;code-header&quot;&gt;configuration.yaml&lt;/div&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;sensor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; template
   &lt;span class=&quot;token key atrule&quot;&gt;sensors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;upstairs_temperature_template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;friendly_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Upstairs Temperature&quot;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;unit_of_measurement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;°F&#39;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;value_template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;% set t = states(&#39;sensor.upstairs_temperature&#39;) &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; float %&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;((t)&lt;span class=&quot;token important&quot;&gt;*9/5)+32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&quot;main-automation&quot; tabindex=&quot;-1&quot;&gt;Main Automation &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#main-automation&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;the-trigger&quot; tabindex=&quot;-1&quot;&gt;The Trigger &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#the-trigger&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There&#39;s three potential triggers you could use:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When the outside temperature changes&lt;/li&gt;
&lt;li&gt;When the  upstairs temperature changes&lt;/li&gt;
&lt;li&gt;On a timer&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After some thought I will go with a timer. The Tuya Thermostat updates
too often and the outside temperature updates every 10 minutes. Using a
timer, or &lt;code&gt;Time Pattern&lt;/code&gt; in HomeAssistant terms, is more natural to me
as it&#39;s works the same as a Cron.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Trigger, &lt;strong&gt;Time Pattern&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hours:&lt;/strong&gt; *&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Minutes:&lt;/strong&gt; /10&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Seconds:&lt;/strong&gt; &lt;em&gt;blank&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This will run every 10 minutes&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Changed to a hardcoded Time trigger in the&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_forecast#another-main-automation-change&quot;&gt;next post&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;the-conditions&quot; tabindex=&quot;-1&quot;&gt;The Conditions &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#the-conditions&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To make this more difficult on myself, &lt;em&gt;joking&lt;/em&gt;, I have specific
specifications when I want the notification:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a. Once per day
b. When the upstairs temperature is above 75F
c. When the outside temperature is below the upstairs temperature
d. &lt;strong&gt;Not&lt;/strong&gt; in the middle of the night&lt;/p&gt;
&lt;h3 id=&quot;a.-once-per-day&quot; tabindex=&quot;-1&quot;&gt;a. Once Per Day &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#a.-once-per-day&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;I made a &lt;code&gt;toggle&lt;/code&gt; helper entity, inside setting &amp;gt; devices &amp;amp; services
helpers, and named it &lt;strong&gt;Temperature Alert&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Condition, &lt;strong&gt;State&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Entity:&lt;/strong&gt; input_boolean.temperature_alert&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attribute:&lt;/strong&gt; &lt;em&gt;blank&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;State:&lt;/strong&gt; Off&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;b.-upstairs-is-above-75f&quot; tabindex=&quot;-1&quot;&gt;b. Upstairs is above 75F &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#b.-upstairs-is-above-75f&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Condition, &lt;strong&gt;Numerical State&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Entity:&lt;/strong&gt; sensor.upstairs_temperature_template&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Above:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Fixed Number&lt;/li&gt;
&lt;li&gt;75&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Below:&lt;/strong&gt; &lt;em&gt;blank&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;c.-outside-is-below-upstairs&quot; tabindex=&quot;-1&quot;&gt;c. Outside is below Upstairs &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#c.-outside-is-below-upstairs&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Condition, &lt;strong&gt;Template Condition&lt;/strong&gt;&lt;/p&gt;
&lt;!-- markdownlint-disable MD013 --&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; states(&#39;sensor.upstairs_temperature_template&#39;) &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt; states(&#39;sensor.KMOP_temperature&#39;) &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;!-- markdownlint-enable MD013 --&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;d.-not-in-the-middle-of-the-night&quot; tabindex=&quot;-1&quot;&gt;d. Not in the Middle of the Night &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#d.-not-in-the-middle-of-the-night&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Condition, &lt;strong&gt;Time&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;After&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Fixed Time&lt;/li&gt;
&lt;li&gt;4:30pm&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Before&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Fixed Time&lt;/li&gt;
&lt;li&gt;11:59pm&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- markdownlint-disable MD013 --&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Removed in the
&lt;a href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_forecast#another-main-automation-change&quot;&gt;next post&lt;/a&gt;&lt;/p&gt;
&lt;!-- markdownlint-enable MD013 --&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;the-actions&quot; tabindex=&quot;-1&quot;&gt;The Actions &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#the-actions&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Two actions need to happen:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a. My iPhone should get a notification through the HomeAssistant App
b. The Temperature Alert boolean should be toggle on&lt;/p&gt;
&lt;h3 id=&quot;a.-notification&quot; tabindex=&quot;-1&quot;&gt;a. Notification &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#a.-notification&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Action, &lt;strong&gt;Call a Service&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Service:&lt;/strong&gt; Notifications: Send Notification via &lt;code&gt;phone_entity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Message:&lt;/strong&gt; Open the Windows&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;a.-boolean&quot; tabindex=&quot;-1&quot;&gt;a. Boolean &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#a.-boolean&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Action, &lt;strong&gt;Call a Service&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Service:&lt;/strong&gt; Input Boolean: Turn On&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Targets:&lt;/strong&gt; input_boolean.temperature_alert&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.nealjoslin.com/files/home_assistant/window_notification/main_automation&quot;&gt;Raw YAML&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;reset-boolean-automation&quot; tabindex=&quot;-1&quot;&gt;Reset Boolean Automation &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#reset-boolean-automation&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We need to reset the Temperature Alert boolean everyday, this is easy in
comparison to the main automation&lt;/p&gt;
&lt;h3 id=&quot;the-trigger-1&quot; tabindex=&quot;-1&quot;&gt;The Trigger &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#the-trigger-1&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Trigger, &lt;strong&gt;Time&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fixed Time&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Time:&lt;/strong&gt; 1:30am&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;the-action&quot; tabindex=&quot;-1&quot;&gt;The Action &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#the-action&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Action, &lt;strong&gt;Call a Service&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Service:&lt;/strong&gt; Input Boolean: Turn Off&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Targets:&lt;/strong&gt; input_boolean.temperature_alert&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.nealjoslin.com/files/home_assistant/window_notification/reset_boolean_automation&quot;&gt;Raw YAML&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;switch&quot; tabindex=&quot;-1&quot;&gt;Switch &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#switch&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After swapping all my devices to a VLAN, I&#39;ve had to re-add all my LocalTuya
devices without help from their Discovery. Here were my steps.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; this pre-assumes you&#39;ve done the work to get the normal
Tuya integration set up. That is have a iot.tuya account and app.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While the general idea works there is room for improvement; Mainly
because I don&#39;t want to open my windows when the temperature is dropping
to 51F, which happens a lot in Michigan. I&#39;ve made this a series and
will hopefully re-visit this idea.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; markdownlint, textlint and meta TOML -&amp;gt; YAML&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
  <entry>
    <title>Window Forecast</title>
    <link href="https://blog.nealjoslin.com/posts/home_assistant/window_forecast/" />
    <updated>2023-08-05T00:00:00Z</updated>
    <id>https://blog.nealjoslin.com/posts/home_assistant/window_forecast/</id>
    <content type="html">&lt;p&gt;As stated in the previous post of this series, the notification is
missing one thing: taking the forecast into account. This feature would
be good because if the weather is dropping down to 52F during the
night I do not want to be opening the windows. My current solution is
to double the weather on my phone, but it would be nice to have this
automated.&lt;/p&gt;
&lt;h2 id=&quot;problem&quot; tabindex=&quot;-1&quot;&gt;Problem &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_forecast/#problem&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The National Weather Service Integration &lt;em&gt;doesn&#39;t&lt;/em&gt; actually have an assessable
&lt;strong&gt;forecast&lt;/strong&gt; entity, but the lovelace card shows it so I know the data is there.&lt;/p&gt;
&lt;p&gt;My first step is checking the &lt;em&gt;states&lt;/em&gt; in the Developer Tools section.
This is what I see for the &lt;code&gt;weather.kmop_daynight&lt;/code&gt; entity:&lt;/p&gt;
&lt;!-- markdownlint-disable MD013 --&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;temperature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;76&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;temperature_unit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; °F
&lt;span class=&quot;token key atrule&quot;&gt;humidity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;53&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# etc..&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;forecast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;detailed_description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Partly sunny&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; with a high near 80. East southeast wind around 10 mph.
    &lt;span class=&quot;token key atrule&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2023-08-05T12:00:00-05:00&#39;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;daytime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cloudy
    &lt;span class=&quot;token key atrule&quot;&gt;precipitation_probability&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;wind_bearing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;112.5&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;temperature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;wind_speed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;detailed_description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Partly cloudy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; with a low around 57. East northeast wind 5 to 10 mph.
    &lt;span class=&quot;token key atrule&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2023-08-05T18:00:00-05:00&#39;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;daytime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; partlycloudy
    &lt;span class=&quot;token key atrule&quot;&gt;precipitation_probability&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;wind_bearing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;67.5&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;temperature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;57&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;wind_speed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7.5&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# etc..&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;!-- markdownlint-enable MD013 --&gt;
&lt;p&gt;Playing around with the &lt;em&gt;template&lt;/em&gt; section in the
Developer Tools section I have come up with this,
&lt;code&gt;{{ state_attr(&amp;quot;weather.kmop_daynight&amp;quot;, &amp;quot;forecast&amp;quot;) }}&lt;/code&gt;, which has the
output of:&lt;/p&gt;
&lt;!-- markdownlint-disable MD013 --&gt;
&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;detailed_description&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Partly sunny, with a high near 80. East southeast wind around 10 mph.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;datetime&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2023-08-05T13:00:00-05:00&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;daytime&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;condition&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;cloudy&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;precipitation_probability&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;wind_bearing&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;112.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;temperature&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;wind_speed&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10.0&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;detailed_description&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Partly cloudy, with a low around 57. East northeast wind 5 to 10 mph.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;datetime&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;2023-08-05T18:00:00-05:00&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;daytime&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;condition&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;partlycloudy&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;precipitation_probability&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;wind_bearing&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;67.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;temperature&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;57&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&#39;wind_speed&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7.5&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# etc&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;!-- markdownlint-enable MD013 --&gt;
&lt;p&gt;From what I can see with this output is that&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;daynight&lt;/strong&gt; is to determine if it&#39;s a Night forecast&lt;/li&gt;
&lt;li&gt;The future items are at 6AM and 6PM&lt;/li&gt;
&lt;li&gt;The first item seems to be closer to the current time&#39;s forecast and not 6AM/PM&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-entity&quot; tabindex=&quot;-1&quot;&gt;The Entity &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_forecast/#the-entity&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: See the edited and final version at the bottom of this post&lt;/p&gt;
&lt;p&gt;My first idea is this
&lt;code&gt;{{ state_attr(&amp;quot;weather.kmop_daynight&amp;quot;, &amp;quot;forecast&amp;quot;).1.temperature }}&lt;/code&gt;, Which
would be the simplest way of accomplishing what I want.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;code-header&quot;&gt;configuration.yaml&lt;/div&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;sensor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; template
   &lt;span class=&quot;token key atrule&quot;&gt;sensors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;forecast_temperature_template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;friendly_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Next Temperature Forecast&quot;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;unit_of_measurement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;°F&#39;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;value_template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; state_attr(&quot;weather.kmop_daynight&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &quot;forecast&quot;).1.temperature &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;A quick reload later and the entity exists!&lt;/p&gt;
&lt;h2 id=&quot;main-automation-change&quot; tabindex=&quot;-1&quot;&gt;Main Automation Change &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_forecast/#main-automation-change&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;ve added a new condition for the
&lt;a href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification/#main-automation&quot;&gt;Main Automation&lt;/a&gt;
created in the
&lt;a href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_notification&quot;&gt;previous post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Condition, &lt;strong&gt;Numerical State&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Entity:&lt;/strong&gt; sensor.forecast_temperature_template&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Above:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Fixed Number&lt;/li&gt;
&lt;li&gt;62&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Below:&lt;/strong&gt; &lt;em&gt;blank&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- markdownlint-disable MD013 --&gt;
&lt;p&gt;Updated Raw YAML in &lt;a href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_forecast/#another-main-automation-change&quot;&gt;Another Main Automation Change&lt;/a&gt;&lt;/p&gt;
&lt;!-- markdownlint-enable MD013 --&gt;
&lt;hr&gt;
&lt;h2 id=&quot;the-updated-entity&quot; tabindex=&quot;-1&quot;&gt;The Updated Entity &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_forecast/#the-updated-entity&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When the clock hits 6PM the next forecast element is the next day&#39;s 6AM,
This will not work because the next day&#39;s 6AM isn&#39;t the expected temperature
&lt;strong&gt;at&lt;/strong&gt; 6AM, but the high for that day.&lt;/p&gt;
&lt;p&gt;This is the updated version that picks the different forecasts depending
on the day; 18 being 6PM in 24-hour time&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;code-header&quot;&gt;configuration.yaml&lt;/div&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;sensor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; template
   &lt;span class=&quot;token key atrule&quot;&gt;sensors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;forecast_temperature_template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;friendly_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Next Temperature Forecast&quot;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;unit_of_measurement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;°F&#39;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;value_template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;% if now().hour &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;= 18 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;%&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; state_attr(&quot;weather.kmop_daynight&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &quot;forecast&quot;).0.temperature &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;%&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; else &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;%&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; state_attr(&quot;weather.kmop_daynight&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &quot;forecast&quot;).1.temperature &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;%&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; endif %&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id=&quot;another-main-automation-change&quot; tabindex=&quot;-1&quot;&gt;Another Main Automation Change &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_forecast/#another-main-automation-change&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After real world use, and weirdly cold nights in Michigan, I&#39;ve
noticed the behavior that the National Weather Service isn&#39;t reliably
updating the forecast at 6pm. Instead of adding more complexity to the
&lt;code&gt;forecast_temperature_template&lt;/code&gt; entity, I will skip the 6PM check.&lt;/p&gt;
&lt;p&gt;To do this I will replace the Time Pattern trigger with hardcoded times
and the Time trigger, This will also remove the 4:30pm-11:59pm time
condition. I was avoiding this because it would be a lot of fields to
enter, &lt;strong&gt;but&lt;/strong&gt; I&#39;m going to write it in YAML&lt;/p&gt;
&lt;p&gt;Trigger: &lt;strong&gt;Time&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;click 3 dots + Edit in YAML&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Paste contents of code block&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; time
&lt;span class=&quot;token key atrule&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;16:30:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;16:40:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;16:50:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;17:00:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;17:10:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;17:20:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;17:30:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;17:40:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;17:50:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;18:10:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;18:20:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;18:30:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;18:40:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;18:50:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;19:00:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;19:10:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;19:20:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;19:30:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;19:40:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;19:50:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;20:00:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;20:10:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;20:20:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;20:30:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;20:40:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;20:50:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;21:00:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;21:10:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;21:20:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;21:30:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;21:40:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;21:50:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;22:00:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;22:10:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;22:20:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;22:30:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;22:40:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;22:50:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;23:00:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;23:10:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;23:20:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;23:30:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;23:40:00&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;23:50:00&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.nealjoslin.com/files/home_assistant/window_forecast/main_automation&quot;&gt;Updated Raw YAML&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; markdownlint, textlint and meta TOML -&amp;gt; YAML&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
  <entry>
    <title>FreePBX Announcement</title>
    <link href="https://blog.nealjoslin.com/posts/freepbx_announcement/" />
    <updated>2023-08-14T00:00:00Z</updated>
    <id>https://blog.nealjoslin.com/posts/freepbx_announcement/</id>
    <content type="html">&lt;p&gt;This will be a general outline of how to setup a Digital Acoustics
Intercom and Paging device as an stand-alone Sip extension. This may not
work in all FreePBX configurations, but this is how I got to work in
it&#39;s most basic form; This should will work for all IP7 devices.&lt;/p&gt;
&lt;h2 id=&quot;hardware&quot; tabindex=&quot;-1&quot;&gt;Hardware &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/freepbx_announcement/#hardware&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This are the parts I was given for this project&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Intercom: &lt;a href=&quot;https://www.digitalacoustics.com/product/20-watt-ip-paging-amplifier/&quot;&gt;Digital Acoustics IP7-SS20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Speaker: &lt;a href=&quot;https://www.amazon.com/Nippon-Tc55-100w-Power-Tc-55/dp/B00TO6XLRU&quot;&gt;Nippon Tc55 100w Power Horn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.digikey.com/en/products/detail/adam-tech/EBKA-02-B/9830662?utm_adgroup=General&amp;amp;utm_source=google&amp;amp;utm_medium=cpc&amp;amp;utm_campaign=PMax%20Shopping_Product_Zombie%20SKUs&amp;amp;utm_term=&amp;amp;utm_content=General&amp;amp;gclid=Cj0KCQjwoeemBhCfARIsADR2QCteywDsNN9o5If2KFofJ8YrgufhDgfZ1Nd1y3J307OJZqrA6VkJ3gcaAkB5EALw_wcB&quot;&gt;1 3.81mm centers 2 pin DIN connector&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;For connecting speaker to intercom&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.com/Amazon-Basics-External-Gold-Plated-Connectors/dp/B00NH11KIK/ref=sr_1_1_ffob_sspa?keywords=usb-b&amp;amp;qid=1692051851&amp;amp;sr=8-1-spons&amp;amp;sp_csd=d2lkZ2V0TmFtZT1zcF9hdGY&amp;amp;psc=1&quot;&gt;USB-A to USB-B Connector&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;For connecting intercom to PC for Flashing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My intercom came with the power adapter.&lt;/p&gt;
&lt;h2 id=&quot;intercom-software-update&quot; tabindex=&quot;-1&quot;&gt;Intercom Software Update &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/freepbx_announcement/#intercom-software-update&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My hardware&#39;s software was out of date, ~&lt;code&gt;v5.3.3.4&lt;/code&gt;, and eSip
doesn&#39;t seem to be an option until &lt;code&gt;v6.3.4.23&lt;/code&gt; on the SS20.&lt;/p&gt;
&lt;p&gt;Most of Digital Acoustics&#39; documentation
tries to push you into using the [TalkMaster
Suite](&lt;a href=&quot;https://www.digitalacoustics.com/talkmaster-focus-software-downlo&quot;&gt;https://www.digitalacoustics.com/talkmaster-focus-software-downlo&lt;/a&gt;
ad/) of tools. I personally had no luck updating using &lt;strong&gt;Firmware
Management Console&lt;/strong&gt;, which is supposed to update the firmware over
a network connection. Instead I downloaded the Stand Alone Firmware
installer (SAFMA) found in section &lt;strong&gt;7&lt;/strong&gt; of the &lt;a href=&quot;https://www.digitalacoustics.com/troubleshooting/&quot;&gt;troubleshooting
page&lt;/a&gt; ([Direct
Download](&lt;a href=&quot;https://www.digitalacoustics.com/wp-content/uploads/software/S&quot;&gt;https://www.digitalacoustics.com/wp-content/uploads/software/S&lt;/a&gt;
AFMA.exe))&lt;/p&gt;
&lt;p&gt;The firmware files can be found
&lt;a href=&quot;https://www.digitalacoustics.com/ip7-firmware-download/&quot;&gt;ip7-firmware-download&lt;/a&gt;,
it&#39;s packaged into an &lt;code&gt;exe&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; must be updated to &lt;code&gt;v5.3.5.4&lt;/code&gt; &lt;strong&gt;first&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The manual for SAFMA is located
&lt;a href=&quot;https://www.digitalacoustics.com/ip7-firmware-download/&quot;&gt;ip7-firmware-download&lt;/a&gt;,
generally it&#39;s self explanatory:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open software&lt;/li&gt;
&lt;li&gt;Select Firmware&lt;/li&gt;
&lt;li&gt;Plugin Device using USB-A to USB-B Connector&lt;/li&gt;
&lt;li&gt;Select COM port &lt;em&gt;(may auto do it)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Reset device with &lt;strong&gt;Reset&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Remove and Replace USB-B Connector from device&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Start&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I found step &lt;strong&gt;6&lt;/strong&gt; wouldn&#39;t re-register the device and would prompt to
restart again, which would fail. Doing a factory reset and trying again
fixed this issue, but you would have to restart this process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Factory Reset:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Unplug device from power&lt;/li&gt;
&lt;li&gt;Hold Volume up and down&lt;/li&gt;
&lt;li&gt;Reattach to power&lt;/li&gt;
&lt;li&gt;Wait until beep &lt;em&gt;(it will be at full volume)&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This took me 6-7 factory resets to update it. I&#39;m not sure what the
problem was.&lt;/p&gt;
&lt;h2 id=&quot;freepbx&quot; tabindex=&quot;-1&quot;&gt;FreePBX &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/freepbx_announcement/#freepbx&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The main point of doing the extension setup next is that the extension
user password is required during the intercom configuration. Again:
this worked in my particular case, this was the first time I used this
particular software and results may vary.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Extension&lt;/strong&gt; can be found in the &lt;strong&gt;Application&lt;/strong&gt; section in the header.
&lt;strong&gt;Once there click New Extension&lt;/strong&gt; and &lt;strong&gt;Chan_Sip&lt;/strong&gt;, Here are the
**settings I used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;General
&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;Intercom&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Extension #&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Voicemail:
&lt;ul&gt;
&lt;li&gt;No change, all disabled&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Advanced
&lt;ul&gt;
&lt;li&gt;can reinvite: update&lt;/li&gt;
&lt;li&gt;host: &lt;code&gt;{Static IP}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Default user: &lt;code&gt;{extension #}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;NAT Mode: No&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now &lt;strong&gt;Save&lt;/strong&gt;, but &lt;strong&gt;don&#39;t&lt;/strong&gt; apply config:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go back to General&lt;/li&gt;
&lt;li&gt;Scroll to User Section&lt;/li&gt;
&lt;li&gt;Click &lt;code&gt;Linked to user {ext#}&lt;/code&gt; &lt;em&gt;(page link)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Change user password and take note of it&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;Now&lt;/em&gt; &lt;strong&gt;Apply Config&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;intercom-setup&quot; tabindex=&quot;-1&quot;&gt;Intercom Setup &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/freepbx_announcement/#intercom-setup&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Instead of using the [TalkMaster
Suite](&lt;a href=&quot;https://www.digitalacoustics.com/talkmaster-focus-software-downlo&quot;&gt;https://www.digitalacoustics.com/talkmaster-focus-software-downlo&lt;/a&gt;
ad/) Admin Console, I used the &lt;a href=&quot;https://www.digitalacoustics.com/ip7-firmware-download/&quot;&gt;eSIP Configuration
Utility&lt;/a&gt;
instead. You might be able to do it through TalkMaster, but these
instruction will be in the context of eSip Utility.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you installed TalkMaster and you want to configure using
eSip, the TalkMaster service must be stopped as they both use port 3000.
This is how you can do that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open CMD &lt;em&gt;(as Admin)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Run: &lt;code&gt;netstat -ano | findstr :3000&lt;/code&gt; (pid will be last column)&lt;/li&gt;
&lt;li&gt;Run: &lt;code&gt;talkkill /PID {enter_pid} /F&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;esip-configuration&quot; tabindex=&quot;-1&quot;&gt;eSip Configuration &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/freepbx_announcement/#esip-configuration&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I was unable to find the eSIP Configuration manual, but
&lt;a href=&quot;https://www.digitalacoustics.com/wp-content/uploads/ApplicationNotes/Application%20Note%20-%20eSIP%20Standalone%20Configuration.pdf&quot;&gt;eSIP Standalone Configuration&lt;/a&gt;
is the Admin Console&#39;s&lt;/p&gt;
&lt;p&gt;The first step is setting the Static IP. I presume this can be done
through the Utility, but I prefer reservations. I took note of the
device&#39;s IP in the discovery, went to my DHCP server, found that IP,
made a reservation with that MAC and reset the device.&lt;/p&gt;
&lt;p&gt;Using the Utility, there are the settings I put in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;General
&lt;ul&gt;
&lt;li&gt;Standalone Sip&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sip
&lt;ul&gt;
&lt;li&gt;peer-to-peer&lt;/li&gt;
&lt;li&gt;SIP + RTP &lt;em&gt;(checked)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;extension + auth is extension #&lt;/li&gt;
&lt;li&gt;pass is extension &lt;strong&gt;user&lt;/strong&gt; password&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Advanced
&lt;ul&gt;
&lt;li&gt;Activate on PPT&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The manuals show using &lt;code&gt;SIP Extension Only&lt;/code&gt;, but I was
unable to get this to work as the device would always appear as
&lt;strong&gt;unreachable&lt;/strong&gt;. The way I found success was using &lt;code&gt;peer-to-peer&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;freepbx-validating&quot; tabindex=&quot;-1&quot;&gt;FreePBX Validating &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/freepbx_announcement/#freepbx-validating&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here are where the Sip logs can be found:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Reports&lt;/strong&gt; in the header&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Astrisk Info&lt;/strong&gt; in the dropdown&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chan_sip Info&lt;/strong&gt; on the list to the right&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Scrolling down to &lt;strong&gt;Chan_Sip Peers&lt;/strong&gt; you should see the new extension
and the furthest column on the right &lt;strong&gt;should&lt;/strong&gt; say &lt;code&gt;OK ({x} ms)&lt;/code&gt;.
Generally looking at this page is faster than dialing the extension on
the phone.&lt;/p&gt;
&lt;h2 id=&quot;fin&quot; tabindex=&quot;-1&quot;&gt;Fin &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/freepbx_announcement/#fin&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When calling the extension the IP7-SS20 automatically picks up and plays
the caller&#39;s voice through the speakers.&lt;/p&gt;
&lt;p&gt;More work needs to be done this for it to be set up properly; Possibly
a passcode or blocking specific phones from calling it, but neither are
concerns in this setup right now.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; markdownlint, textlint and meta TOML -&amp;gt; YAML&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
  <entry>
    <title>Omada, New Switch</title>
    <link href="https://blog.nealjoslin.com/posts/home_network/new_main_switch/" />
    <updated>2023-12-27T00:00:00Z</updated>
    <id>https://blog.nealjoslin.com/posts/home_network/new_main_switch/</id>
    <content type="html">&lt;p&gt;I received a new switch, that is compatible with Omada Controllers. This is
how I made it my &#39;Main Switch&#39; and swapped out the old non-compatible switch&lt;/p&gt;
&lt;h2 id=&quot;hardware&quot; tabindex=&quot;-1&quot;&gt;Hardware &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_network/new_main_switch/#hardware&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;New Switch: &lt;a href=&quot;https://www.amazon.com/TP-Link-TL-SG2008P-Jetstream-Integrated-Protection/dp/B08J9ZQ7HC&quot;&gt;TP-Link TL-SG2008P&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Old Switch: &lt;a href=&quot;https://www.amazon.com/gp/product/B01BW0AD1W/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&amp;amp;th=1&quot;&gt;TP-Link TL-SG108PE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;APs: &lt;a href=&quot;https://www.amazon.com/gp/product/B07NMZR3F1/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&amp;amp;th=1&quot;&gt;TP-Link EAP245 V3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My Omada Controller is running in a Virtual Machine on my Server&lt;/p&gt;
&lt;h2 id=&quot;existing-setup&quot; tabindex=&quot;-1&quot;&gt;Existing Setup &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_network/new_main_switch/#existing-setup&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;omada&quot; tabindex=&quot;-1&quot;&gt;Omada &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_network/new_main_switch/#omada&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Inside of Settings &amp;gt; Wireless Networks &amp;gt; WLAN, I have two entries:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Loading...&lt;/code&gt;, VLAN 1 &lt;strong&gt;(Default)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IoT&lt;/code&gt;, VLAN 10&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Inside of Settings &amp;gt; Wired Networks &amp;gt; LAN, I had one entry:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;LAN&lt;/code&gt;, interface, VLAN 1&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IoT&lt;/code&gt;, interface, VLAN 10&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;switch&quot; tabindex=&quot;-1&quot;&gt;Switch &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_network/new_main_switch/#switch&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;I have both APs connected to Port 1 &amp;amp; 2 on the TL-SG108PE, Port 8 going to
PfSense and other misc Ethernet connections on some other Ports. I have
attempted to get VLANs working with Omada &amp;amp; PfSense in the past, so the
&lt;code&gt;802.1Q VLAN&lt;/code&gt; settings look like:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN ID&lt;/th&gt;
&lt;th&gt;VLAN NAME&lt;/th&gt;
&lt;th&gt;Member Ports&lt;/th&gt;
&lt;th&gt;Tagged Ports&lt;/th&gt;
&lt;th&gt;Untagged Ports&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Default&lt;/td&gt;
&lt;td&gt;1-8&lt;/td&gt;
&lt;td&gt;1-2, 8&lt;/td&gt;
&lt;td&gt;3-7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;IoT&lt;/td&gt;
&lt;td&gt;1-2, 8&lt;/td&gt;
&lt;td&gt;1-2, 8&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; These settings were a working checkpoint: Default worked.
Something was wrong with IoT, It might have been PfSense settings I&#39;m
not sure. I thought I&#39;d mention that in case somebody decides to
use that.&lt;/p&gt;
&lt;h2 id=&quot;initial-attempt&quot; tabindex=&quot;-1&quot;&gt;Initial Attempt &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_network/new_main_switch/#initial-attempt&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My first attempt was to plug and play, a 1-to-1 replacement. This did
not work as the controller would not accept the Access Points and one of
two issues would happen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The Access Point would say &amp;quot;Disconnected&amp;quot;&lt;/li&gt;
&lt;li&gt;The Access Point would get stuck in the &amp;quot;Adopting&amp;quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Either way, I found that the Access Points could not be pinged while
attached to the new switch. Being dinner time, my temporary fix was to
plug in my APs to the old switch and plug the old switch into the new
switch.&lt;/p&gt;
&lt;h2 id=&quot;trail-an-error&quot; tabindex=&quot;-1&quot;&gt;Trail an Error &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_network/new_main_switch/#trail-an-error&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I narrowed down the problem to the VLANs, but I was unable to revert
everything back to a non-VLAN setup from before my previous attempt.
Through Googling, I found a tidbit that mentioned that Omada doesn&#39;t
handle &lt;strong&gt;untagged&lt;/strong&gt; traffic well. That person was suggesting moving
everything to a VLAN so that all traffic was being tagged, but that&#39;s a
radical change for my network and would screw up my Home Assistant.&lt;/p&gt;
&lt;h2 id=&quot;port-profiles&quot; tabindex=&quot;-1&quot;&gt;Port Profiles &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_network/new_main_switch/#port-profiles&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Port profiles are the root of the problem. Unlike my previous switch
that let me explicitly tag ports with VLANs, the Omada software doesn&#39;t
allow that to happen with the new switch. Instead there is a &lt;code&gt;Native Network&lt;/code&gt; (untagged) and then &lt;code&gt;Tagged Networks&lt;/code&gt; (tagged). There must
always be a Native Network and the Native Network cannot also be put
into the Tagged Networks.&lt;/p&gt;
&lt;h2 id=&quot;dummy-vlan-(solution)&quot; tabindex=&quot;-1&quot;&gt;Dummy VLAN (Solution) &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_network/new_main_switch/#dummy-vlan-(solution)&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To get around this I made a &lt;em&gt;dummy&lt;/em&gt; VLAN that can be used as a Native
Network, which would allow me to tag all my actual traffic.&lt;/p&gt;
&lt;h3 id=&quot;creating&quot; tabindex=&quot;-1&quot;&gt;Creating &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_network/new_main_switch/#creating&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Settings &amp;gt; Wired Networks &amp;gt; LAN: &lt;strong&gt;Create New LAN&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Name: &lt;strong&gt;AP&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Purpose: &lt;strong&gt;VLAN&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;VLAN: &lt;strong&gt;4090&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Save&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;profile&quot; tabindex=&quot;-1&quot;&gt;Profile &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_network/new_main_switch/#profile&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Settings &amp;gt; Wired Networks &amp;gt; LAN &amp;gt;| Profile: &lt;strong&gt;Create New Port Profile&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Name: &lt;strong&gt;Access Point Port&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Native Network: &lt;strong&gt;AP&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Tagged Networks: &lt;strong&gt;LAN&lt;/strong&gt;, &lt;strong&gt;IoT&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Save&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;setting-profile&quot; tabindex=&quot;-1&quot;&gt;Setting Profile &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_network/new_main_switch/#setting-profile&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Devices &amp;gt;| SG2008P &amp;gt;| Ports&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;Edit&lt;/strong&gt; Icon in the Action column for the correct port&lt;/li&gt;
&lt;li&gt;Profile: &lt;strong&gt;Access Point Port&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apply&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After being applied the Access Points snapped on!&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_network/new_main_switch/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This was way more fiddly than it should be. I 100% understand that
untagged traffic should automatically go to the Default &lt;code&gt;LAN&lt;/code&gt;, but that
wasn&#39;t happening. I may have did something wrong in my previous attempt,
I have no idea. &lt;strong&gt;But!-&lt;/strong&gt; through my trails and errors my WLANs and
VLANs are now working, so now I can start separating my IoT devices!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; markdownlint, textlint and meta TOML -&amp;gt; YAML&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
  <entry>
    <title>Rest Framework (Custom User + TokenAuthentication)</title>
    <link href="https://blog.nealjoslin.com/posts/django/rest_custom_authtoken/" />
    <updated>2024-01-26T00:00:00Z</updated>
    <id>https://blog.nealjoslin.com/posts/django/rest_custom_authtoken/</id>
    <content type="html">&lt;p&gt;I&#39;ve overrode Django&#39;s default user model to use &lt;code&gt;email&lt;/code&gt; instead. When I tried
to use this with Django-Rest-Framework&#39;s
&lt;a href=&quot;https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication&quot;&gt;TokenAuthentication&lt;/a&gt;
it did not work. This is how I overrode &lt;strong&gt;that&lt;/strong&gt; as well&lt;/p&gt;
&lt;h2 id=&quot;serializer&quot; tabindex=&quot;-1&quot;&gt;Serializer &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/django/rest_custom_authtoken/#serializer&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;code-header&quot;&gt;myapp/serializers.py&lt;/div&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; django&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contrib&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;auth &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; authenticate
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; django&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;utils&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;translation &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; gettext_lazy &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; _

&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; rest_framework &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; serializers

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EmailAuthTokenSerializer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;serializers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Serializer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    email &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; serializers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CharField&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        label&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        write_only&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    password &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; serializers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CharField&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        label&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Password&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;input_type&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;password&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        trim_whitespace&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        write_only&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    token &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; serializers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CharField&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        label&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Token&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        read_only&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attrs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        email &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; attrs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;email&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        password &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; attrs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;password&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; email &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; password&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; authenticate&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;request&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                                email&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;password&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;# The authenticate call simply returns None for is_active=False&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;# users. (Assuming the default ModelBackend authentication&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;# backend.)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; user&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                msg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; _&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Unable to log in with provided credentials.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; serializers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ValidationError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;authorization&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            msg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; _&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Must include &quot;email&quot; and &quot;password&quot;.&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; serializers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ValidationError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;authorization&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        attrs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;user&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; user
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; attrs&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h2 id=&quot;view&quot; tabindex=&quot;-1&quot;&gt;View &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/django/rest_custom_authtoken/#view&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;code-header&quot;&gt;myapp/view.py&lt;/div&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; rest_framework&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;authtoken&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;views &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; ObtainAuthToken

&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;serializers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; EmailAuthTokenSerializer

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EmailObtainAuthToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ObtainAuthToken&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    serializer_class &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; EmailAuthTokenSerializer

obtain_auth_token &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; EmailObtainAuthToken&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;as_view&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h2 id=&quot;urls&quot; tabindex=&quot;-1&quot;&gt;URLs &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/django/rest_custom_authtoken/#urls&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;code-header&quot;&gt;myapp/urls.py&lt;/div&gt;&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; django&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;urls &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; path

&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; views

urlpatterns &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
    path&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;api-token-auth/&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; views&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;obtain_auth_token&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;p&gt;Pretty basic but thought I should jot it down as my initial google
search wasn&#39;t fruitful. I didn&#39;t spend too much time looking&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; markdownlint, textlint and meta TOML -&amp;gt; YAML&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
  <entry>
    <title>HA Forecast v2</title>
    <link href="https://blog.nealjoslin.com/posts/home_assistant/forecast_action/" />
    <updated>2025-07-13T00:00:00Z</updated>
    <id>https://blog.nealjoslin.com/posts/home_assistant/forecast_action/</id>
    <content type="html">&lt;p&gt;I have been lackadaisical with my Home Assistant updates, but when
I updated it late December of 2024 I&#39;ve broken all my forecast
automations. I had for a short while swapped to openweathermap, but now
that even seems to be broken. With summer heat at an all time peak I
would like to get this working again. I&#39;ve moderate research on this...
and it&#39;s a nightmare. As of writing my instance is &lt;code&gt;2025.6.2&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;problem&quot; tabindex=&quot;-1&quot;&gt;Problem &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/forecast_action/#problem&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;{{ state_attr(&amp;quot;weather.kmop_daynight&amp;quot;, &amp;quot;forecast&amp;quot;) }}&lt;/code&gt; has now been
deprecated and now you have to manually call to get the forecast.
From the 3-4 threads I have read, this requires a template, with a
trigger and an action. The major problem right off the bat was testing
&lt;strong&gt;anything&lt;/strong&gt;. The forums described &amp;quot;Developer Tools&amp;quot; and the &amp;quot;Services&amp;quot;
tab, I don&#39;t have any of that.&lt;/p&gt;
&lt;h2 id=&quot;testing&quot; tabindex=&quot;-1&quot;&gt;Testing &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/forecast_action/#testing&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After plenty of failures, &amp;quot;Services&amp;quot; has now been renamed to &amp;quot;Actions&amp;quot;.
Going there a simple test is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Select &lt;code&gt;weather.get_forecasts&lt;/code&gt; in the search&lt;/li&gt;
&lt;li&gt;Select the &lt;code&gt;KMOP&lt;/code&gt; entity&lt;/li&gt;
&lt;li&gt;Forecast Type: &lt;code&gt;Twice Daily&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is the YAML for the call&lt;/p&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; weather.get_forecasts
&lt;span class=&quot;token key atrule&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; twice_daily
&lt;span class=&quot;token key atrule&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;entity_id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; weather.kmop_daynight
&lt;span class=&quot;token key atrule&quot;&gt;response_variable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; response&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Clicking to preform action outputs it in this format&lt;/p&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;weather.kmop_daynight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;forecast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;precipitation_probability&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;is_daytime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# etc&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Scrolling down you can click the &lt;code&gt;COPY TO CLIPBOARD (TEMPLATE)&lt;/code&gt; button
and this data can then be used inside the Template tab. This is also
where you see that the response_variable is &lt;strong&gt;in fact&lt;/strong&gt; being set to
&lt;code&gt;response&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;automating&quot; tabindex=&quot;-1&quot;&gt;Automating &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/forecast_action/#automating&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is where the template part comes in. I created a new file &lt;code&gt;templates.yaml&lt;/code&gt;
and added this line &lt;code&gt;template: !include templates.yaml&lt;/code&gt; in my main configuration&lt;/p&gt;
&lt;p&gt;I&#39;ve found this file was specific on &lt;code&gt;action&lt;/code&gt; and &lt;code&gt;sensor&lt;/code&gt; &lt;strong&gt;not&lt;/strong&gt; having a dash&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;code-header&quot;&gt;templates.yaml,&lt;/div&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; time_pattern
    &lt;span class=&quot;token key atrule&quot;&gt;minutes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/15&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; weather.get_forecasts
      &lt;span class=&quot;token key atrule&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; twice_daily
      &lt;span class=&quot;token key atrule&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;entity_id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; weather.kmop_daynight
      &lt;span class=&quot;token key atrule&quot;&gt;response_variable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; response
  &lt;span class=&quot;token key atrule&quot;&gt;sensor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Weather Forecast
      &lt;span class=&quot;token key atrule&quot;&gt;unique_id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; weather_forecast
      &lt;span class=&quot;token key atrule&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{{ now() }}&quot;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;forecast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{{ response[&#39;weather.kmop_daynight&#39;].forecast }}&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;After creating this and resetting Home Assistant this new sensor appeared as
&lt;code&gt;unknown&lt;/code&gt;. I am hoping that it will configure after 15 minutes.
&lt;strong&gt;Which happened!&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;converting&quot; tabindex=&quot;-1&quot;&gt;Converting &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/forecast_action/#converting&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now to update the entity created in the
&lt;a href=&quot;https://blog.nealjoslin.com/posts/home_assistant/window_forecast#the-updated-entity&quot;&gt;previous post&lt;/a&gt;&lt;/p&gt;
&lt;!-- markdownlint-disable MD013 --&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;code-header&quot;&gt;configuration.yaml&lt;/div&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;sensor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; template
   &lt;span class=&quot;token key atrule&quot;&gt;sensors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;forecast_temperature_template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;friendly_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Next Temperature Forecast&quot;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;unit_of_measurement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;°F&#39;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;value_template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;% if states(&quot;sensor.weather_forecast&quot;) &lt;span class=&quot;token tag&quot;&gt;!=&lt;/span&gt; &quot;unavailable&quot; %&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;% if now().hour &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;= 18 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;%&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
              &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; state_attr(&quot;sensor.weather_forecast&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &quot;forecast&quot;).0.temperature &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;%&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; else &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;%&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
              &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; state_attr(&quot;sensor.weather_forecast&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &quot;forecast&quot;).1.temperature &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;%&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; endif %&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;% else %&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            unavailable
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;% endif %&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;!-- markdownlint-enable MD013 --&gt;
&lt;blockquote&gt;
&lt;p&gt;I had added an &amp;quot;unavailable&amp;quot; if to all my templates to avoid error logs&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;next&quot; tabindex=&quot;-1&quot;&gt;Next &lt;a class=&quot;header-anchor&quot; href=&quot;https://blog.nealjoslin.com/posts/home_assistant/forecast_action/#next&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My current plans is to keep this running for a week or two to check
that it&#39;s working and then changed the trigger to a &lt;code&gt;time&lt;/code&gt; platform. This would
lower the amount of requests.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>InsightHome Modbus RTU</title>
    <link href="https://blog.nealjoslin.com/posts/solar/insighthome_rtu/" />
    <updated>2025-10-07T00:00:00Z</updated>
    <id>https://blog.nealjoslin.com/posts/solar/insighthome_rtu/</id>
    <content type="html">&lt;p&gt;I&#39;ve been playing with an InsightHome Inverter Hub from Schinder Electric.
It has a Modbus RTU interface which I have connected with using an RS485 to USB
dongle, the results have always been timeouts. My assumption is that the
device is actually the Master/Client of the Modbus system and is not
compatible as a Slave/Server.&lt;/p&gt;
&lt;p&gt;Going another route, I&#39;ve created a Modbus Slave/Server using the 502
(SunSpec) standard. I validated all the registers with the
&lt;a href=&quot;https://github.com/sunspec/pysunspec2&quot;&gt;pysunspec2&lt;/a&gt; package. During the
device detection my device is found, there are no errors, but there is
no further registration process and my device doesn&#39;t appear. Checking
the Network Log, the hub replies that the device &amp;quot;Type&amp;quot; as &amp;quot;unknown&amp;quot; and
a &amp;quot;isDead&amp;quot; attribute is &amp;quot;N/a&amp;quot;&lt;/p&gt;
&lt;p&gt;Here are commands the Hub runs during the Discovery process, in order:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Addr&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Schema&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;503&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;503&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;40020&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;502&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;503&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;40020&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;502&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;40020&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;502&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_INPUT&lt;/td&gt;
&lt;td&gt;4999&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_INPUT&lt;/td&gt;
&lt;td&gt;4999&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_INPUT&lt;/td&gt;
&lt;td&gt;4999&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;40020&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;502&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;3085&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;32001&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_HOLD&lt;/td&gt;
&lt;td&gt;1014&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_INPUT&lt;/td&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_INPUT&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;503&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;READ_INPUT&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;503&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Looking at the known mappings, it&#39;s checking for Device/Model names
and, I presume, checking it against an internal list of supported
devices. Which.. is a shame!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: As a debugging process I cross referenced all these requests with my
Schinder devices to make sure my Slave/Server is responding the same to each.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This entire process has been nonsensical. I wanted to share as I haven&#39;t
found a similar attempt online. I&#39;d recommend to stick to Modbus TCP, if
you are working with these.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;NOTE(neal@2026-08-09): I have had more experiences with solar inverters
in the past year and &lt;strong&gt;this&lt;/strong&gt; was the real &amp;quot;issue&amp;quot; I ran into with
Schinder&#39;s Inverters. They did a wonderful job with this product and I
enjoyed working with them. These inverters do not seem to be as popular
as they once were, due to being undersized for today&#39;s market and built
as a modular system. I hope they release a higher kW &amp;quot;all-in-one&amp;quot;
version with similar software capabilities.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Blog Refactor</title>
    <link href="https://blog.nealjoslin.com/posts/blog-refactor/" />
    <updated>2026-08-09T00:00:00Z</updated>
    <id>https://blog.nealjoslin.com/posts/blog-refactor/</id>
    <content type="html">&lt;p&gt;This blog was originally made using &lt;a href=&quot;https://gohugo.io/&quot;&gt;Hugo&lt;/a&gt;, I had made the
theme myself and it looked ugly. This year at my work we moved away from
WordPress to a static site. When it came to porting the news section (mainly for
less broken links) we tried &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;Eleventy&lt;/a&gt;. This was
mainly due to this cool idea of mashing template languages in a flexible
way, which would be good idea with potential future editors. I liked
it!&lt;/p&gt;
&lt;p&gt;I decided to refactor this website to use Eleventy too. I&#39;ve removed
features such as comments and some posts that were not that good. I also
did a major cosmetic overhaul, via Claude, to more match my terminal
aesthetic I was going for. This is the colorscheme I use everywhere; desktop,
terminal, editor. This shift is still a work in progress.&lt;/p&gt;
&lt;p&gt;In lieu of comments, please contact me directly via my email:
&lt;a href=&quot;mailto:neal@joslin.io&quot;&gt;neal@joslin.io&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
</feed>