<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Technology Archives - Alexiev Arts</title>
	<atom:link href="https://alexievarts.com/category/technology/feed/" rel="self" type="application/rss+xml" />
	<link>https://alexievarts.com/category/technology/</link>
	<description>The official travel log/blog of the Alexiev family</description>
	<lastBuildDate>Wed, 31 Dec 2025 19:55:46 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>

<image>
	<url>https://alexievarts.com/wp-content/uploads/2017/06/cropped-AlexievArts-32x32.png</url>
	<title>Technology Archives - Alexiev Arts</title>
	<link>https://alexievarts.com/category/technology/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Turning a Philips Hue Light On When Your Mac’s Camera Turns On</title>
		<link>https://alexievarts.com/technology/control-hue-lights-via-laptop-camera-changes/</link>
					<comments>https://alexievarts.com/technology/control-hue-lights-via-laptop-camera-changes/#respond</comments>
		
		<dc:creator><![CDATA[Akrion]]></dc:creator>
		<pubDate>Wed, 31 Dec 2025 19:49:31 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[hue]]></category>
		<category><![CDATA[macos]]></category>
		<category><![CDATA[monitor camera]]></category>
		<category><![CDATA[philips]]></category>
		<category><![CDATA[zoom]]></category>
		<guid isPermaLink="false">https://alexievarts.com/?p=6257</guid>

					<description><![CDATA[<p>When your webcam turns on, it’s often a moment you want to be aware of—especially during video calls, screen recordings, or any&#160;app that might access the camera unexpectedly. The bash script&#160;we will go over makes that awareness physical: it watches macOS’s unified logs for camera on/off events and automatically toggles a Philips Hue light to [&#8230;]</p>
<p>The post <a href="https://alexievarts.com/technology/control-hue-lights-via-laptop-camera-changes/">Turning a Philips Hue Light On When Your Mac’s Camera Turns On</a> appeared first on <a href="https://alexievarts.com">Alexiev Arts</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>When your webcam turns on, it’s often a moment you want to be aware of—especially during video calls, screen recordings, or any&nbsp;app that might access the camera unexpectedly. The bash script&nbsp;we will go over makes that awareness physical: it watches macOS’s unified logs for camera on/off events and automatically toggles a Philips Hue light to match.This is&nbsp;a small automation with a big UX payoff: your environment reflects&nbsp;your device&nbsp;state, without&nbsp;you&nbsp;having&nbsp;to&nbsp;think&nbsp;about it.</p>



<h2 class="wp-block-heading">Just do this</h2>



<pre class="wp-block-code"><code>bash camera_watch.sh</code></pre>



<p>And you should see this:   <code>Monitoring camera access…</code><br><br>That is all! From here if your setup is correct the moment you start your camera for a conference call or a meeting your hue light specified will turn on!</p>



<h2 class="wp-block-heading">Github Repo</h2>



<p>To get the actual files and run this locally go to <a href="https://github.com/Akrion/macos-camera-hue-indicator" target="_blank" rel="noreferrer noopener">THIS</a> github repo and follow the README.</p>



<h2 class="wp-block-heading">What the script does (purpose)</h2>



<ul class="wp-block-list">
<li>Monitors macOS&nbsp;unified&nbsp;logs&nbsp;in&nbsp;real&nbsp;time&nbsp;to&nbsp;detect when the&nbsp;camera&nbsp;starts&nbsp;and&nbsp;stops&nbsp;streaming.</li>



<li>Turns a Hue&nbsp;light&nbsp;ON&nbsp;when the&nbsp;camera&nbsp;becomes&nbsp;active.</li>



<li>Turns&nbsp;the&nbsp;Hue&nbsp;light OFF&nbsp;when&nbsp;the camera becomes&nbsp;inactive.</li>



<li>Optionally&nbsp;turns&nbsp;the&nbsp;light OFF&nbsp;on&nbsp;exit, so&nbsp;you&nbsp;don’t&nbsp;leave&nbsp;it&nbsp;on&nbsp;if&nbsp;you&nbsp;stop&nbsp;the&nbsp;script.</li>
</ul>



<p>In&nbsp;practice, it’s a&nbsp;“webcam&nbsp;indicator&nbsp;light,” but&nbsp;better—because&nbsp;you&nbsp;can&nbsp;place&nbsp;it&nbsp;anywhere in&nbsp;the&nbsp;room, use&nbsp;any&nbsp;Hue&nbsp;bulb/fixture, and make&nbsp;it&nbsp;as&nbsp;noticeable&nbsp;(or&nbsp;subtle) as you want.</p>



<h2 class="wp-block-heading">Why&nbsp;this&nbsp;is&nbsp;useful&nbsp;(benefits)</h2>



<ul class="wp-block-list">
<li>Immediate, ambient&nbsp;awareness: You&nbsp;get&nbsp;a physical “camera&nbsp;is&nbsp;live” signal even&nbsp;if&nbsp;the&nbsp;app&nbsp;UI&nbsp;is&nbsp;minimized&nbsp;or on a different screen.</li>



<li>Privacy + confidence: Helps&nbsp;you&nbsp;notice&nbsp;unexpected&nbsp;camera activation&nbsp;and&nbsp;reduces uncertainty (“Is my camera still&nbsp;on?”).</li>



<li>Hands-free automation: No need to remember&nbsp;to toggle lights&nbsp;at&nbsp;the&nbsp;start/end of&nbsp;calls.</li>



<li>Flexible&nbsp;setup: You&nbsp;can&nbsp;choose&nbsp;which Hue light&nbsp;to control&nbsp;and&nbsp;can&nbsp;override&nbsp;behavior&nbsp;via&nbsp;environment&nbsp;variables.</li>
</ul>



<h2 class="wp-block-heading">How&nbsp;it&nbsp;works</h2>



<p>At&nbsp;a&nbsp;high&nbsp;level, the script is&nbsp;a&nbsp;loop:</p>



<ol class="wp-block-list">
<li>Stream&nbsp;macOS&nbsp;logs&nbsp;continuously.</li>



<li>For&nbsp;each&nbsp;log&nbsp;line:</li>
</ol>



<ul class="wp-block-list">
<li>If&nbsp;it&nbsp;indicates&nbsp;camera&nbsp;start: turn&nbsp;Hue&nbsp;on.</li>



<li>If it indicates&nbsp;camera stop: turn&nbsp;Hue off.</li>
</ul>



<p>Here&nbsp;are&nbsp;the key&nbsp;moving&nbsp;parts.</p>



<h4 class="wp-block-heading">1) Safety&nbsp;and&nbsp;predictable&nbsp;shell&nbsp;behavior</h4>



<p>The&nbsp;script&nbsp;starts&nbsp;with:</p>



<ul class="wp-block-list">
<li><code>set&nbsp;-euo&nbsp;pipefail</code>:  fail&nbsp;fast&nbsp;on&nbsp;errors, undefined&nbsp;variables, and&nbsp;pipeline&nbsp;failures.</li>



<li><code>IFS=$'\n\t'</code>: safer&nbsp;word-splitting&nbsp;defaults.</li>
</ul>



<p>This&nbsp;is&nbsp;defensive&nbsp;Bash: it&nbsp;reduces&nbsp;the&nbsp;chance&nbsp;of&nbsp;silent&nbsp;failures&nbsp;and&nbsp;weird&nbsp;parsing&nbsp;bugs.</p>



<h4 class="wp-block-heading">2) Configuration&nbsp;with&nbsp;sensible&nbsp;defaults&nbsp;(and&nbsp;easy overrides)</h4>



<p>It&nbsp;defines defaults, but allows&nbsp;overriding&nbsp;via&nbsp;environment variables:</p>



<ul class="wp-block-list">
<li><code><strong>LOG_BIN</strong></code>&nbsp;(default&nbsp;<strong>/usr/bin/log</strong>): the&nbsp;macOS&nbsp;unified&nbsp;logging CLI.</li>



<li><code><strong>HUE_SCRIPT</strong></code>&nbsp;(default&nbsp;<strong>hue_camera_watch/hue_1.2.1.sh</strong>): the&nbsp;Hue&nbsp;control&nbsp;script&nbsp;it&nbsp;delegates&nbsp;to.</li>



<li><code><strong>HUE_LIGHT_TYPE</strong></code>&nbsp;(default&nbsp;<strong>light</strong>): passed&nbsp;through&nbsp;to&nbsp;the Hue script.</li>



<li><code><strong>HUE_LIGHT_ID</strong></code>&nbsp;(default&nbsp;<strong>28</strong>): which&nbsp;Hue&nbsp;light&nbsp;to&nbsp;toggle.</li>



<li><code><strong>LOG_LEVEL</strong></code>&nbsp;(default&nbsp;<strong>info</strong>): log&nbsp;streaming&nbsp;verbosity.</li>



<li><code><strong>CLEANUP_TURN_OFF</strong></code>&nbsp;(default&nbsp;<strong>true</strong>): whether&nbsp;to&nbsp;force&nbsp;the light off when&nbsp;the script stops.</li>
</ul>



<p>This&nbsp;design&nbsp;is&nbsp;practical: you can&nbsp;run&nbsp;the&nbsp;same&nbsp;script in&nbsp;different&nbsp;setups&nbsp;without editing&nbsp;it—just&nbsp;set&nbsp;env&nbsp;vars.</p>



<h4 class="wp-block-heading">3) Simple&nbsp;logging&nbsp;helper</h4>



<p>log_msg()&nbsp;prints timestamped&nbsp;messages&nbsp;to&nbsp;stderr, keeping stdout clean&nbsp;in&nbsp;case&nbsp;you want&nbsp;to&nbsp;pipe&nbsp;output:</p>



<ul class="wp-block-list">
<li>This&nbsp;is&nbsp;helpful&nbsp;if&nbsp;you&nbsp;run&nbsp;it&nbsp;under&nbsp;a&nbsp;supervisor, redirect&nbsp;logs, or&nbsp;want&nbsp;to&nbsp;keep&nbsp;the&nbsp;terminal&nbsp;tidy.</li>
</ul>



<h4 class="wp-block-heading">4) A&nbsp;tiny&nbsp;“adapter” function&nbsp;for&nbsp;Hue&nbsp;control</h4>



<p><code>hue_state()</code>&nbsp;is&nbsp;a&nbsp;wrapper&nbsp;that&nbsp;calls&nbsp;the&nbsp;Hue&nbsp;script&nbsp;like&nbsp;this:</p>



<pre class="wp-block-code"><code>/bin/bash&nbsp;"$HUE_SCRIPT"&nbsp;"$HUE_LIGHT_TYPE"&nbsp;"$HUE_LIGHT_ID"&nbsp;state&nbsp;on|off</code></pre>



<p>This&nbsp;keeps&nbsp;camera_watch.sh&nbsp;focused&nbsp;on&nbsp;detection&nbsp;and&nbsp;state&nbsp;logic, while&nbsp;<code>hue_1.2.1.sh</code>&nbsp;handles&nbsp;the&nbsp;details&nbsp;of&nbsp;talking&nbsp;to&nbsp;the&nbsp;Hue&nbsp;bridge.</p>



<h4 class="wp-block-heading">5) Cleanup&nbsp;and&nbsp;signal&nbsp;handling&nbsp;(don’t&nbsp;leave&nbsp;the&nbsp;light&nbsp;on)</h4>



<p>Two&nbsp;traps&nbsp;are&nbsp;important:</p>



<ul class="wp-block-list">
<li><code>trap&nbsp;'cleanup;&nbsp;exit&nbsp;0'&nbsp;INT TERM</code> : on&nbsp;Ctrl+C&nbsp;or&nbsp;termination, run&nbsp;cleanup and&nbsp;exit.</li>



<li><code>trap&nbsp;cleanup&nbsp;EXIT</code> : on&nbsp;any&nbsp;normal&nbsp;exit path, also run cleanup.</li>
</ul>



<p>And&nbsp;cleanup&nbsp;itself&nbsp;is&nbsp;“best effort”: it&nbsp;tries&nbsp;to&nbsp;turn the light&nbsp;off, but&nbsp;won’t&nbsp;crash&nbsp;the&nbsp;shutdown&nbsp;sequence&nbsp;if&nbsp;that&nbsp;fails.This&nbsp;is&nbsp;the&nbsp;kind of detail&nbsp;that&nbsp;makes a&nbsp;script feel trustworthy&nbsp;day-to-day.</p>



<h4 class="wp-block-heading">6) Early&nbsp;validation&nbsp;(fail&nbsp;fast)</h4>



<p>Before&nbsp;streaming&nbsp;logs, it checks:</p>



<ul class="wp-block-list">
<li>The&nbsp;log&nbsp;binary exists&nbsp;and&nbsp;is&nbsp;executable.</li>



<li>The&nbsp;Hue script&nbsp;file&nbsp;exists.</li>



<li>HUE_LIGHT_ID&nbsp;is numeric.</li>
</ul>



<p>That&nbsp;means&nbsp;you&nbsp;get&nbsp;clear&nbsp;errors&nbsp;immediately&nbsp;rather&nbsp;than&nbsp;a&nbsp;script&nbsp;that&nbsp;“runs” but&nbsp;doesn’t&nbsp;actually&nbsp;work.</p>



<h4 class="wp-block-heading">7) The&nbsp;core&nbsp;event&nbsp;loop: streaming&nbsp;logs&nbsp;and&nbsp;detecting&nbsp;camera&nbsp;events</h4>



<p>The&nbsp;heart&nbsp;of&nbsp;the&nbsp;script&nbsp;is:</p>



<pre class="wp-block-code"><code>log&nbsp;stream --style&nbsp;syslog&nbsp;--level "$LOG_LEVEL"&nbsp;--predicate&nbsp;'...'</code></pre>



<p>It&nbsp;filters to:</p>



<ul class="wp-block-list">
<li><code>process&nbsp;==&nbsp;"UVCAssistant"</code>&nbsp;and&nbsp;log&nbsp;messages&nbsp;containing:</li>



<li><code>kUVCExtensionEventStartStream</code></li>



<li><code>kUVCExtensionEventStopStream</code></li>
</ul>



<p>Those&nbsp;messages&nbsp;correlate&nbsp;with&nbsp;the&nbsp;camera&nbsp;starting/stopping&nbsp;at&nbsp;the&nbsp;system&nbsp;level.Then, for&nbsp;each&nbsp;line:</p>



<ul class="wp-block-list">
<li>It&nbsp;skips header/noise lines&nbsp;(important&nbsp;to&nbsp;avoid&nbsp;false positives&nbsp;at&nbsp;startup).</li>



<li>If&nbsp;it&nbsp;sees&nbsp;a&nbsp;StartStream&nbsp;event:</li>



<li>If the&nbsp;script&nbsp;currently&nbsp;thinks&nbsp;the&nbsp;camera&nbsp;is&nbsp;inactive, it&nbsp;flips&nbsp;internal&nbsp;state&nbsp;and&nbsp;turns&nbsp;the&nbsp;Hue&nbsp;light&nbsp;on.</li>



<li>If&nbsp;it&nbsp;sees&nbsp;a&nbsp;StopStream&nbsp;event:</li>



<li>If the script&nbsp;currently thinks the camera&nbsp;is active, it&nbsp;flips&nbsp;internal&nbsp;state&nbsp;and&nbsp;turns&nbsp;the&nbsp;Hue&nbsp;light&nbsp;off.</li>
</ul>



<p>That&nbsp;internal&nbsp;state&nbsp;(<code>CAMERA_ACTIVE</code>) is a simple&nbsp;but&nbsp;important&nbsp;detail: it prevents&nbsp;repeated&nbsp;“on” commands&nbsp;if&nbsp;multiple start&nbsp;log&nbsp;lines&nbsp;appear, and&nbsp;avoids&nbsp;spamming&nbsp;the&nbsp;Hue&nbsp;bridge.</p>



<h2 class="wp-block-heading">Customizing it (common tweaks)</h2>



<p>Because&nbsp;configuration&nbsp;is environment-driven, you&nbsp;can&nbsp;do&nbsp;things&nbsp;like:</p>



<ul class="wp-block-list">
<li>Pick&nbsp;a&nbsp;different&nbsp;light:</li>
</ul>



<ul class="wp-block-list">
<li>Set&nbsp;<code>HUE_LIGHT_ID</code>&nbsp;to&nbsp;your&nbsp;bulb’s&nbsp;ID.</li>
</ul>



<ul class="wp-block-list">
<li>Use&nbsp;a&nbsp;different&nbsp;Hue control&nbsp;script:</li>
</ul>



<ul class="wp-block-list">
<li>Set&nbsp;<code>HUE_SCRIPT=/path/to/your_hue_script.sh</code></li>
</ul>



<ul class="wp-block-list">
<li>Keep&nbsp;the&nbsp;light&nbsp;as-is&nbsp;when&nbsp;you&nbsp;stop&nbsp;the&nbsp;script:</li>
</ul>



<ul class="wp-block-list">
<li>Set&nbsp;<code>CLEANUP_TURN_OFF=false</code></li>
</ul>



<ul class="wp-block-list">
<li>Adjust&nbsp;verbosity:</li>
</ul>



<ul class="wp-block-list">
<li>Set&nbsp;<code>LOG_LEVEL=debug</code>&nbsp;(or&nbsp;keep&nbsp;info)</li>
</ul>



<h2 class="wp-block-heading">Practical&nbsp;notes&nbsp;and limitations</h2>



<ul class="wp-block-list">
<li>macOS-specific: it&nbsp;relies&nbsp;on&nbsp;the&nbsp;unified&nbsp;logging&nbsp;system&nbsp;and&nbsp;the&nbsp;UVCAssistant&nbsp;process&nbsp;behavior.</li>



<li>Event&nbsp;accuracy&nbsp;depends&nbsp;on&nbsp;logs: if&nbsp;Apple&nbsp;changes&nbsp;log&nbsp;messages/process&nbsp;names&nbsp;in&nbsp;future&nbsp;macOS&nbsp;versions, the predicate&nbsp;may&nbsp;need updating.</li>



<li>Requires&nbsp;Hue&nbsp;connectivity: if&nbsp;the&nbsp;bridge is&nbsp;unreachable, the&nbsp;script may&nbsp;fail&nbsp;when&nbsp;sending&nbsp;commands&nbsp;(it’s&nbsp;intentionally&nbsp;strict&nbsp;overall).</li>
</ul>



<p></p>
<p>The post <a href="https://alexievarts.com/technology/control-hue-lights-via-laptop-camera-changes/">Turning a Philips Hue Light On When Your Mac’s Camera Turns On</a> appeared first on <a href="https://alexievarts.com">Alexiev Arts</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://alexievarts.com/technology/control-hue-lights-via-laptop-camera-changes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Dynamic meta tags with Create React App, Handlebars, and no Server-Side Rendering</title>
		<link>https://alexievarts.com/technology/create-react-app-dynamic-head-meta-elements-with-handlebars-and-no-ssr/</link>
					<comments>https://alexievarts.com/technology/create-react-app-dynamic-head-meta-elements-with-handlebars-and-no-ssr/#respond</comments>
		
		<dc:creator><![CDATA[Akrion]]></dc:creator>
		<pubDate>Thu, 15 Aug 2019 06:32:00 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[cra]]></category>
		<category><![CDATA[create react app]]></category>
		<category><![CDATA[dynamic meta]]></category>
		<category><![CDATA[handlebars]]></category>
		<category><![CDATA[react]]></category>
		<guid isPermaLink="false">https://alexievarts.com/?p=5704</guid>

					<description><![CDATA[<p>Create React App (CRA) offers quite a few advantages when it comes to mocking up quickly a react web application. One of the disadvantages however is that if you want to have your open graph and meta tags populated dynamically some sort of server-side rendering approach is usually recommended. That however is not always the [&#8230;]</p>
<p>The post <a href="https://alexievarts.com/technology/create-react-app-dynamic-head-meta-elements-with-handlebars-and-no-ssr/">Dynamic meta tags with Create React App, Handlebars, and no Server-Side Rendering</a> appeared first on <a href="https://alexievarts.com">Alexiev Arts</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="has-drop-cap">Create React App (<a href="https://create-react-app.dev/docs/getting-started" target="_blank" rel="noreferrer noopener">CRA</a>) offers quite a few advantages when it comes to mocking up quickly a react web application. One of the disadvantages however is that if you want to have your <a href="https://en.wikipedia.org/wiki/Facebook_Platform#Open_Graph_protocol" target="_blank" rel="noreferrer noopener">open graph</a> and meta tags populated dynamically some sort of server-side rendering approach is usually recommended. That however is not always the desired route nor the most trivial to set up. </p>



<p>In this article, we would explore a solution where we would make our <code><strong>index.html</strong></code> a handlebars template and hydrate it on the client site without SSR (Server-Side Rendering). This approach would use the <code>npm <strong>scripts</strong></code> section of our <strong>package.json</strong> where we would replace the <code><strong>start</strong></code> and add <code><strong>prebuild</strong></code> stages with simple bash scripts. That way by doing <code><strong>npm start</strong></code> to start our app we would be hydrating and creating the <code><strong>index.html</strong></code> at run and build time. Also, this approach would allow for multiple environments and instances configuration. You would be able to dynamically hydrate your index for development vs. production build or <strong>siteA</strong> vs. <strong>siteB</strong> instance by simply providing create react app with a few <a href="https://create-react-app.dev/docs/adding-custom-environment-variables" target="_blank" rel="noreferrer noopener">environment variables</a>. </p>



<p><strong>TLDR</strong>: Working version of the CRA below can be found <a href="https://repl.it/@akrion/Dynamic-Meta" target="_blank" rel="noreferrer noopener">on Repl.it</a>. Fork it to run the npm scripts etc.</p>



<h2 class="wp-block-heading">Requirements:</h2>



<ul class="wp-block-list"><li><a href="https://nodejs.org/en/" target="_blank" rel="noreferrer noopener">Nodejs</a>  version 8.10 or above</li><li>npm version 5.6 or above</li></ul>



<h2 class="wp-block-heading">Setting up our React App</h2>



<p>So lets start with creating our CRA first which we would name <code><strong>dynamic-meta</strong></code> with:</p>



<pre class="wp-block-code"><code><strong>npx</strong> create-react-app dynamic-meta</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><code>npx</code>&nbsp;on the first line is not a typo — it’s a&nbsp;<a href="https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b" target="_blank" rel="noreferrer noopener">package runner tool that comes with npm 5.2+</a></p></blockquote>



<p>Next, let&#8217;s add the <a href="https://www.npmjs.com/package/hbs-cli" target="_blank" rel="noreferrer noopener">handlebars CLI</a> package called <code><strong>hbs-cli</strong></code> and save it to our <code><strong>package.json</strong></code> file as a dependency:</p>



<pre class="wp-block-code"><code><strong>npm</strong> i hbs-cli -s</code></pre>



<p>We need the <code><strong>hbs-cli</strong></code> in order to run handlebars via the shell script which we would place in our <code>package.json scripts</code> section. </p>



<p>At this point, we have all the needed packages from npm to make this work. Next, let&#8217;s setup a few more files and folders for organization purposes. Let&#8217;s move the <code><strong>index.html</strong></code> from the <strong>public</strong> folder to a folder in the root called <code><strong>template</strong></code> and rename it to <code><strong>index.hbs</strong></code>. This would be our template which would be hydrated to produce the final <code>index.html</code> in the public folder. We would also add some handlebars variables and clean up some of the comments added by CRA. So the end result is something like this:</p>



<pre class="wp-block-code"><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;link rel="icon" href="%PUBLIC_URL%/favicon.ico" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
    &lt;meta name="theme-color" content="#000000" /&gt;
    &lt;meta property="og:title" content="<strong>{{{TITLE}}}</strong>"/&gt;
    &lt;meta property="og:description" content="<strong>{{{DESCRIPTION}}}</strong>"/&gt;
    &lt;link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /&gt;
    &lt;link rel="manifest" href="%PUBLIC_URL%/manifest.json" /&gt;
    &lt;title&gt;<strong>{{{TITLE}}}</strong>&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;noscript&gt;You need to enable JavaScript to run this app.&lt;/noscript&gt;
    &lt;div id="root"&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>



<p>You can already see what we would be replacing in the index template. All the handlebars variables shown above would be hydrated via json files at start/build time. To learn more about handlebars <a href="https://handlebarsjs.com/guide/" target="_blank" rel="noreferrer noopener">click here</a>.</p>



<p>Now we would assume that we have few environments for our application and few instances as well. For example, we will have a development environment and a production one and in each of those, we might have different API and other keys that we might want to use. You might have a sandbox API key for a 3rd party integration in development and another production version for your production environment. Also, each one of the different instances might have a different <strong>favicon.ico</strong> and <strong>manifest.json</strong> as well. What about the app logo? </p>



<p>So in order to support all those we would simply create another folder in the root and call it <strong>sites</strong>. In that folder, we would have <strong>sub-folders</strong> with the name of our instances. For this example, we would use <code><strong>siteA</strong></code> and <code><strong>siteB</strong></code>. And since we are creating folders, let&#8217;s create another one called <strong>scripts</strong> in the root folder. </p>



<p>At this point, our app tree looks like this:</p>



<pre class="wp-block-code"><code><strong>root</strong>
|
└-- <strong>public</strong>        // CRA default public folder
└-- <strong>scripts</strong>       // Our <code>start</code> and <code>prebuild</code> scripts reside here
└-- <strong>sites</strong>         // To keep our instance folders organized
|   |
|   └-- <strong>siteA</strong>     // Instance folder A
|   └-- <strong>siteB</strong>     // Instance folder B
└-- <strong>src</strong>           // CRA default source folder
└-- <strong>template</strong>      // Where our index.hbs resides
    |
    └-- <strong>index.hbs</strong> // Our handlebars template file
</code></pre>



<p>Since each instance of our site would be different in terms of look and feel we would copy favicon.ico, logo files, and manifest.json to each of the instance folders and remove them from the public folder. Our <strong>public</strong> folder should contain only the <code><strong>rebots.txt</strong></code> file generated by the CRA at this point. We would copy all the instance files from the instance folder to the public folder at start &amp; build time. We will also add an entry to our <code><strong>.gitignore</strong></code> file to ignore all files in the public folder except the robots.txt one later.</p>



<h2 class="wp-block-heading">The configuration JSON files</h2>



<p>We would also want each site instance to have its own images/title/description/API Keys etc. So let&#8217;s start with what would be common between all the <strong>siteA</strong> environments. <strong>Title</strong> and <strong>Description</strong> sound like good candidates here. Let&#8217;s create a <strong>default.json file that</strong> would be always used by handlebars when we want to hydrate our <strong>index.hbs</strong>.  For <strong>siteA</strong> we would have:</p>



<pre class="wp-block-code"><code>{
  "TITLE": "SITE A",
  "DESCRIPTION": "SITE A Description"
}</code></pre>



<p>You <strong>would have the same name file in the siteB folder with different values for the TITLE and DESCRIPTION.</strong> </p>



<p>Ok we are almost there. The only thing missing is the actual scripts to &#8220;glue&#8221; together everything. </p>



<h2 class="wp-block-heading">The Scripts</h2>



<p>If you try to run our app at its current state nothing good would happen since we have <strong>no index.html</strong> at all in our public folder. We need to actually generate one. To do this let&#8217;s set up our scripts in our <strong>package.json</strong> first:</p>



<pre class="wp-block-code"><code>"scripts": {
<strong>    "start": "bash scripts/start.sh",
    "prebuild": "bash scripts/prebuild.sh",</strong>
    <strong>"build": "react-scripts build",</strong>
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },</code></pre>



<p>Next, let&#8217;s create the <strong>prebuild.sh</strong> file in the <strong>scripts folder</strong>. We start with that one since the <strong>start.sh</strong> would be relying on the <strong>prebuild.sh</strong>. Here is what the <strong>prebuild.sh would look like</strong>:</p>



<pre class="wp-block-code"><code>#!/usr/bin/env bash

# Parameters
<strong>ENV=${REACT_APP_NODE_ENV:-development}
INSTANCE=${REACT_APP_NODE_APP_INSTANCE:-siteA}
</strong>
# Folders
<strong>PUB="public"
SITES="sites"</strong>

# Files containing the handlebars variables
<strong>DEFAULT_FILE=${PUB}/default.json
ENV_FILE=${PUB}/${ENV}.json</strong>

# Template files as parameters to the CLI command
<strong>PARAMS="-D ${DEFAULT_FILE}"</strong>

<strong>echo "ENV: $ENV"
echo "INSTANCE: $INSTANCE"
echo</strong>

# Copy all instance files into the public web folder
<strong>&#91; -d ${SITES}/${INSTANCE} ] &amp;&amp; command cp ${SITES}/${INSTANCE}/* ${PUB}</strong>

# Only continue if we have default template variables file
<strong>if &#91; -f ${DEFAULT_FILE} ]
then</strong>
  # Concatenate env variables file to the data parameters variable
  <strong>&#91; -f ${ENV_FILE} ] &amp;&amp; PARAMS="${PARAMS} -D ${ENV_FILE}"</strong>

  # Run the CLI for handlebars to hydrate the template with the data files
  <strong>command npx hbs ${PARAMS} template/index.hbs -o ${PUB}</strong>

  # Remove the copied template json files except manifest.json
  <strong>command find ${PUB}/*.json ! -name manifest.json | xargs rm</strong>
<strong>fi</strong>

<strong>echo "┌-----------------┐"
echo "| Pre-Build Done! |"
echo "└-----------------┘"</strong></code></pre>



<p>Now we would not go into too many details of what the shell script above does (there are comments on every line) but here are few pointers. The first and most important thing to mention here is the parameters being read in ENV and INSTANCE variables. If any is provided then we would use those but if not we would default to <code><strong>development</strong></code> environment and <code><strong>siteA</strong></code> instance.</p>



<p>Note that we use the <code><strong>command</strong></code> prefix in order to make sure we <a href="https://askubuntu.com/questions/512770/what-is-use-of-command-command" target="_blank" rel="noreferrer noopener">avoid any aliases being used</a>. For example, if the alias of <strong>cp -i</strong> is registered for the <strong>cp</strong> command the script would have different behavior. Another important thing to more here is the use of <code><strong>npx hbs</strong></code> in order to hydrate our <strong>index.hbs</strong> template and produce the <strong>index.html</strong> file. Handlebars by default outputs HTML so we only specify the output folder with the <strong>-o parameter</strong>.</p>



<p>Next lets setup our final script file &#8211; the <strong>start.sh</strong>:</p>



<pre class="wp-block-code"><code>#!/usr/bin/env bash

<strong>export REACT_APP_NODE_ENV="${REACT_APP_NODE_ENV:-development}"</strong>
<strong>export REACT_APP_NODE_APP_INSTANCE="${REACT_APP_NODE_APP_INSTANCE:-siteA}"</strong>

# Run the prebuild with the exported above ENV variables
<strong>bash scripts/prebuild.sh</strong>

# Start the app
<strong>npx react-scripts start</strong></code></pre>



<p>As you can see the only purpose of the <strong>start.sh </strong>is to export the REACT_APP variables so they are accessible to the <strong>prebuild.sh</strong>  file. After that, it simply start the app via the <strong>react-scripts start command</strong>. Note also that it defaults the <strong>REACT_APP_NODE_ENV</strong> to <code><strong>development</strong></code> and <strong>REACT_APP_NODE_APP_INSTANCE</strong> to <code><strong>siteA</strong></code>. This is for convenience purposes since we do not want to always specify the CRA environment variables to start our app. This way <code><strong>npm start</strong></code> would start the <strong><code>development</code> siteA</strong>.</p>



<h2 class="wp-block-heading">Wrapping things up</h2>



<p>So if you <strong>start</strong> our app right now with <strong>npm start</strong> &#8230; this is what we should see in the terminal:</p>



<pre class="wp-block-code"><code>ENV: development
INSTANCE: siteA

Wrote /&lt;PATH TO YOUR APP&gt;/dynamic-meta/public/index.html from template/index.hbs
┌-----------------┐
| Pre-Build Done! |
└-----------------┘</code></pre>



<p>Opening the page source of the dynamically created <strong>index.html </strong>in the <strong>public folder</strong> gives us:</p>



<pre class="wp-block-code"><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;link rel="icon" href="/favicon.ico" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
    &lt;meta name="theme-color" content="#000000" /&gt;
    &lt;meta property="og:title" content="<strong>SITE A</strong>"/&gt;
    &lt;meta property="og:description" content="<strong>SITE A Description</strong>"/&gt;
    &lt;link rel="apple-touch-icon" href="/logo192.png" /&gt;
    &lt;link rel="manifest" href="/manifest.json" /&gt;
    &lt;title&gt;<strong>SITE A</strong>&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;noscript&gt;You need to enable JavaScript to run this app.&lt;/noscript&gt;
    &lt;div id="root"&gt;&lt;/div&gt;
  &lt;script src="/static/js/bundle.js"&gt;&lt;/script&gt;&lt;script src="/static/js/0.chunk.js"&gt;&lt;/script&gt;&lt;script src="/static/js/main.chunk.js"&gt;&lt;/script&gt;&lt;/body&gt;
&lt;/html&gt;</code></pre>



<p>As you can see we have our handlebars variables hydrated. Now lets try passing a different instance with:</p>



<pre class="wp-block-code"><code>R<strong>EACT_APP_NODE_APP_INSTANCE=siteB</strong> npm start</code></pre>



<p>We would get as we would expect the <strong>siteB</strong> meta title and description:</p>



<pre class="wp-block-code"><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;link rel="icon" href="/favicon.ico" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
    &lt;meta name="theme-color" content="#000000" /&gt;
    &lt;meta property="og:title" content="<strong>SITE B</strong>"/&gt;
    &lt;meta property="og:description" content="<strong>SITE B Description</strong>"/&gt;
    &lt;link rel="apple-touch-icon" href="/logo192.png" /&gt;
    &lt;link rel="manifest" href="/manifest.json" /&gt;
    &lt;title&gt;<strong>SITE B</strong>&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;noscript&gt;You need to enable JavaScript to run this app.&lt;/noscript&gt;
    &lt;div id="root"&gt;&lt;/div&gt;
  &lt;script src="/static/js/bundle.js"&gt;&lt;/script&gt;&lt;script src="/static/js/0.chunk.js"&gt;&lt;/script&gt;&lt;script src="/static/js/main.chunk.js"&gt;&lt;/script&gt;&lt;/body&gt;
&lt;/html&gt;</code></pre>



<h2 class="wp-block-heading">More than just meta tags</h2>



<p>Last but not least what about different values that we might have for environments like development or production?  Let&#8217;s say we have a 3rd party app integration like google analytics or similar that has different keys for the different environments. How would we solve that with the approach above?</p>



<p>We simply add them in the <code><strong>index.hbs</strong></code> with handlebars <strong>if</strong> condition and we add the environment json files. <strong>Our prebuild script already accounts for that</strong>. So let&#8217;s add <strong>development.json</strong> and <strong>production.json</strong> in the <strong>siteA</strong> and <strong>siteB</strong> site folders. In each let&#8217;s add a prop with the name <strong>APP_ID</strong>. For example, this would be our <strong>sites/siteA/development.json</strong>:</p>



<pre class="wp-block-code"><code>{
  "APP_ID": "DEV SITE A"
}</code></pre>



<p>and this <strong>sites/siteA/production.json</strong>:</p>



<pre class="wp-block-code"><code>{
  "APP_ID": "PROD SITE A"
}</code></pre>



<p>Now lets add in the <strong>index.hbs</strong> template:</p>



<pre class="wp-block-code"><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;link rel="icon" href="%PUBLIC_URL%/favicon.ico" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
    &lt;meta name="theme-color" content="#000000" /&gt;
    &lt;meta property="og:title" content="{{{TITLE}}}"/&gt;
    &lt;meta property="og:description" content="{{{DESCRIPTION}}}"/&gt;
    &lt;meta name="description" content="{{{DESCRIPTION}}}"/&gt;
    &lt;link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /&gt;
    &lt;link rel="manifest" href="%PUBLIC_URL%/manifest.json" /&gt;
    &lt;title&gt;{{{TITLE}}}&lt;/title&gt;
<strong>    &lt;script type="text/javascript"&gt;
      {{# if APP_ID}}window.APP_ID='{{APP_ID}}';{{/if}}
      if (window.APP_ID) {
        alert(`APP_ID: ${window.APP_ID}`)
      }
    &lt;/script&gt;</strong>
  &lt;/head&gt;
  &lt;body&gt;
    &lt;noscript&gt;You need to enable JavaScript to run this app.&lt;/noscript&gt;
    &lt;div id="root"&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>



<p>We simply use handlebars if condition which says if we have as a variable <strong>APP_ID</strong> then write the text <strong>window.APP_ID='{{{APP_ID}}&#8217;</strong>  and replace the APP_ID with the value. Then we check if <strong>window.APP_ID</strong> exists and if so we alert it. So if we run this with the default <code><strong>npm start</strong></code> we would see the alert <strong>DEV SITE A</strong> since we have an entry for the APP_ID in our <strong><code>siteA</code> development.json</strong> file.</p>



<p>Now lets run the production one with:</p>



<pre class="wp-block-code"><code><strong>REACT_APP_NODE_ENV=production REACT_APP_NODE_APP_INSTANCE=siteA</strong> npm start</code></pre>



<p>Now we would be using the the <strong>APP_ID</strong> from the <strong>production.json</strong> file and we would get <strong>PROD SITE A</strong> alert.</p>



<h2 class="wp-block-heading">What about build time?</h2>



<p>If you would like to crate a build for the default <code><strong>siteA</strong></code> instance and the default <code><strong>development</strong></code> environment when you simply run: </p>



<pre class="wp-block-code"><code>npm <strong>run build</strong></code></pre>



<p>To run a <strong>production</strong> build for <strong>siteB</strong> you would run:</p>



<pre class="wp-block-code"><code>REACT_APP_NODE_ENV=<strong>production</strong> REACT_APP_NODE_APP_INSTANCE=<strong>siteB</strong> npm run build</code></pre>



<p>The cool thing is that we have hooked our dynamic index.html creation at the prebuild time so the actual build would already have the <strong>hydrated index.html</strong> from the <strong>index.hbs</strong> and would then go through the create react app react-scripts pipeline to create the final create react app build.</p>



<h2 class="wp-block-heading">Repl.it</h2>



<p>If you would like to play with the code for this and see the actual results from the create react app just go to <a href="https://repl.it/@akrion/Dynamic-Meta" target="_blank" rel="noreferrer noopener"><strong>this link</strong></a>. Then click on the <strong>Run</strong> button to start the default build. You can also then use the Repl.it console to execute the different <strong>npm start</strong> commands we mentioned above where you would pass the REACT_APP_NODE_ENV and the REACT_APP_NODE_APP_INSTANCE parameters.</p>



<h2 class="wp-block-heading">Other Options</h2>



<p>You can achieve a <strong>similar result</strong> without the use of the <code><strong>hbs-cli</strong></code> package and only with shell. For that, you can use the <a href="https://github.com/tests-always-included/mo" target="_blank" rel="noreferrer noopener">Mustache templates in bash</a> or <strong>mo</strong> for short and call that instead of <strong>hbs-cli</strong> in your <strong>prebuild.sh</strong> script. You might have to change the parameters passed to <strong>mo</strong> slightly but other than that the rest would remain the same.</p>
<p>The post <a href="https://alexievarts.com/technology/create-react-app-dynamic-head-meta-elements-with-handlebars-and-no-ssr/">Dynamic meta tags with Create React App, Handlebars, and no Server-Side Rendering</a> appeared first on <a href="https://alexievarts.com">Alexiev Arts</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://alexievarts.com/technology/create-react-app-dynamic-head-meta-elements-with-handlebars-and-no-ssr/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Tesla Owners API &#8211; How To</title>
		<link>https://alexievarts.com/technology/tesla-owners-api-how-to/</link>
					<comments>https://alexievarts.com/technology/tesla-owners-api-how-to/#respond</comments>
		
		<dc:creator><![CDATA[Akrion]]></dc:creator>
		<pubDate>Mon, 15 Jul 2019 07:45:17 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[tesla]]></category>
		<guid isPermaLink="false">https://alexievarts.com/?p=3992</guid>

					<description><![CDATA[<p>Tesla Owners API refers to an application programming interface provided by Tesla which when requests are made against it, it returns information related to your Tesla vehicle. The idea is to simply use the documentation services provided by Apiary.io and their testing tool to make the actual requests and see the responses. This has been [&#8230;]</p>
<p>The post <a href="https://alexievarts.com/technology/tesla-owners-api-how-to/">Tesla Owners API &#8211; How To</a> appeared first on <a href="https://alexievarts.com">Alexiev Arts</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="has-drop-cap">Tesla Owners API refers to an application programming interface provided by Tesla which when requests are made against it, it returns information related to your Tesla vehicle. The idea is to simply use the documentation services provided by <a rel="noreferrer noopener" href="https://apiary.io/" target="_blank">Apiary.io</a> and their testing tool to make the actual requests and see the responses. This has been extremely helpful to me personally. Tesla multiple times has failed me with their customer service and only the data from their servers was able to prove I was right in the related conversations. </p>



<h1 class="wp-block-heading">How is this useful?</h1>



<p>To give you one example: Tesla techs kept telling me that I had an upgrade that I did not have.  Only when I gave them the raw data from the API they understood that they have missed one. In another example I found out from the options codes returned from the API that I had a feature I did not know I had and it was not listed anywhere in the orientation or the invoice which came with the vehicle!</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Please note that this documentation is not official and in any shape or form supported or maintained by Tesla. It is actually reverse-engineered. The documentation web site Apiary is actually owned by Oracle and it is simply a product that helps with the documentation of application programming interfaces (or APIs). Also, none of your credentials are stored or kept anywhere. They are simply passed through to Tesla servers</p></blockquote>



<h1 class="wp-block-heading">How does this work?</h1>



<p>We will start with the following steps needed to get the information we want from the Tesla Owners API:</p>



<ul class="wp-block-list"><li>Authenticate via the <a aria-label="Apiary Tesla Owner JSON API (opens in a new tab)" rel="noreferrer noopener" href="https://akrion.docs.apiary.io/#reference/authentication/tokens/get-an-access-token?console=1" target="_blank">Apiary Tesla Owner JSON API</a> and get the authentication token we need in order to make any further requests to Tesla servers.</li><li>Once we have the token we would use that and add it to the header so our request can properly. authenticate against the Tesla servers and obtain the other pieces of information we need.</li><li>Get the list of vehicles under your account via the authentication token.</li><li>Using a vehicle id get the information of interest.</li></ul>



<h1 class="wp-block-heading">Step 1: Go to the Tesla Owner JSON API on Apiary.io</h1>



<p><a aria-label="Click on this link (opens in a new tab)" rel="noreferrer noopener" href="https://akrion.docs.apiary.io/#reference/authentication/tokens/get-an-access-token?console=1" target="_blank">Click on this link</a> and have the browser window open and handy so you can see the current one you are reading from and the new one where you would add/change values. The link is to the actual documentation website we would use to make the requests.</p>



<h1 class="wp-block-heading">Step 2: Get an authentication token from Tesla</h1>



<figure class="wp-block-gallery columns-1 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-01.jpg"><img fetchpriority="high" decoding="async" width="2209" height="1252" src="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-01.jpg" alt="Tesla API 01" data-id="4000" class="wp-image-4000" srcset="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-01.jpg 2209w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-01-300x170.jpg 300w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-01-768x435.jpg 768w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-01-249x140.jpg 249w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-01-232x130.jpg 232w" sizes="(max-width: 2209px) 100vw, 2209px" /></a></figure></li></ul></figure>



<p>You should see the screen above. The left side of it is the actual documentation and every request is explained in detail there. On the right side is the console where we would actually perform the requests and see the responses. Since the link already pointed to the <strong>Get an Access Token </strong>request<strong> </strong>it is already open and ready to be executed on the right side. The <strong>header</strong> information is already added as well as the majority of the <strong>body</strong>. What is only missing is your <em>email and password</em>. Enter those where it says &#8220;YOUR_EMAIL&#8221; and &#8220;YOUR_PASSWORD&#8221; and <strong>click on the &#8220;Call Resource&#8221;</strong>. Again no information is kept on your request. Your credentials are simply passed through to Tesla from the Apiary servers. You should see the following response <strong>in the console section</strong>:</p>



<figure class="wp-block-gallery columns-1 is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-02.jpg"><img decoding="async" width="1179" height="1329" src="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-02.jpg" alt="" data-id="4004" class="wp-image-4004" srcset="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-02.jpg 1179w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-02-266x300.jpg 266w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-02-768x866.jpg 768w" sizes="(max-width: 1179px) 100vw, 1179px" /></a></figure></li></ul></figure>



<p>You should get a <strong>200</strong> response from the server (see the red rectangle in the image above). This means we did everything correctly and we now have received an authentication token from the Tesla servers. This is the <strong>access_token</strong> in the <strong>Response Body</strong> above (masked in this example). Copy the value of that access_token (copy the text between the &#8220;&#8221; for the <strong>access_token</strong> key).</p>



<h1 class="wp-block-heading">Step 3: Get the list of vehicles using the token</h1>



<p>Now that we have the token we would go to the <strong>Vehicles</strong> part of the documentation and click on the <strong>List all Vehicles</strong> request:</p>



<figure class="wp-block-gallery columns-1 is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-03.jpg"><img decoding="async" width="2191" height="473" src="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-03.jpg" alt="" data-id="4009" class="wp-image-4009" srcset="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-03.jpg 2191w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-03-300x65.jpg 300w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-03-768x166.jpg 768w" sizes="(max-width: 2191px) 100vw, 2191px" /></a></figure></li></ul></figure>



<p>In the console section, we would go to the Headers tab and for the Authorization key, we would set the value to be: Bearer and the token we copied from Step 1. That is all you need before clicking on the Call Resource again to this time to get the list of vehicles. Note that the Authorization value should not contain double quotes etc. Should be simply Bearer followed by space and the token value from Step 1. When you are done you should see something like this in the response:</p>



<figure class="wp-block-gallery columns-1 is-cropped wp-block-gallery-4 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-04.jpg"><img loading="lazy" decoding="async" width="1177" height="1530" src="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-04.jpg" alt="" data-id="4012" class="wp-image-4012" srcset="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-04.jpg 1177w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-04-231x300.jpg 231w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-04-768x998.jpg 768w" sizes="auto, (max-width: 1177px) 100vw, 1177px" /></a></figure></li></ul></figure>



<p>All is well! We now have received the first few details about our car. We have the VIN, the actual Id in the Tesla system, the option codes, etc. Great result for a few minutes of actual &#8220;work&#8221; right?  You also can now compare and check if your option codes match your invoice :). Now that we have the vehicle list we can copy the <strong>id_s</strong> value from it and dive into the actual specific data of that vehicle.</p>



<h1 class="wp-block-heading">Step 4: Using the id_s to get vehicle data</h1>



<p>What we will do now is to utilize the <strong>token</strong> and the <strong>id_s</strong> to get any of the <strong>State and Settings</strong> data we would like.  We would only do the Vehicle State in this example since all others follow the same pattern. So two things we need to go forward with this. <strong>One</strong> is the authorization <strong>token</strong> we got from <strong>step 1</strong> and <strong>second</strong> the <strong>id_s</strong> we got from <strong>step 3</strong>. Let&#8217;s click on the <strong>Vehicle State</strong> in the <strong>State and Settings</strong> section of the documentation.</p>



<figure class="wp-block-gallery columns-1 is-cropped wp-block-gallery-5 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-05.jpg"><img loading="lazy" decoding="async" width="2186" height="1225" src="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-05.jpg" alt="Tesla API 05" data-id="4015" class="wp-image-4015" srcset="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-05.jpg 2186w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-05-300x168.jpg 300w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-05-768x430.jpg 768w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-05-366x205.jpg 366w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-05-534x300.jpg 534w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-05-165x92.jpg 165w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-05-249x140.jpg 249w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-05-232x130.jpg 232w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-05-344x193.jpg 344w" sizes="auto, (max-width: 2186px) 100vw, 2186px" /></a></figure></li></ul></figure>



<p>Here in the console, we would go to the URL Parameters and for the value of <strong>vehicle_id</strong>, we would set the value we got from <strong>step 3</strong> for the <strong>id_s</strong>. Then we would click on the <strong>Headers</strong> tab and do <strong>exactly what we did in step 3</strong>. Set the <strong>Authorization</strong> key to the <strong>Bearer</strong> and the token value from step 1. Clicking on <strong>Call Resource</strong> should return a response looking like this:<br></p>



<figure class="wp-block-gallery columns-1 is-cropped wp-block-gallery-6 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-06.jpg"><img loading="lazy" decoding="async" width="1160" height="1956" src="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-06.jpg" alt="" data-id="4016" class="wp-image-4016" srcset="https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-06.jpg 1160w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-06-178x300.jpg 178w, https://alexievarts.com/wp-content/uploads/2019/07/Tesla-API-06-768x1295.jpg 768w" sizes="auto, (max-width: 1160px) 100vw, 1160px" /></a></figure></li></ul></figure>



<p>As you can see this returns a lot more data related to the actual state of the vehicle. You can now follow this example and do any of the other requests listed under the State and Settings section. For the sake of brevity, we would not cover the Vehicle Commands section. It follows the same patterns overall so you can experiment if you like it.</p>



<p>Hope this helps and if you have any questions do not hesitate to post a comment. I will do my best to reply promptly. </p>



<h1 class="wp-block-heading">Use my referral code and save!</h1>



<p>If you would like to receive <strong>1,000 free Supercharger miles</strong> when you purchase your new Tesla use my referral code: <a rel="noreferrer noopener" aria-label="http://ts.la/ilian3072 (opens in a new tab)" href="http://ts.la/ilian3072" target="_blank">http://ts.la/ilian3072</a></p>
<p>The post <a href="https://alexievarts.com/technology/tesla-owners-api-how-to/">Tesla Owners API &#8211; How To</a> appeared first on <a href="https://alexievarts.com">Alexiev Arts</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://alexievarts.com/technology/tesla-owners-api-how-to/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Spectrum internet self-installation with a router</title>
		<link>https://alexievarts.com/technology/spectrum-internet-self-installation-with-a-router/</link>
					<comments>https://alexievarts.com/technology/spectrum-internet-self-installation-with-a-router/#respond</comments>
		
		<dc:creator><![CDATA[Akrion]]></dc:creator>
		<pubDate>Tue, 07 May 2019 21:11:00 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[asus]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[modem]]></category>
		<category><![CDATA[router]]></category>
		<category><![CDATA[RT-AC68W]]></category>
		<category><![CDATA[spectrum]]></category>
		<category><![CDATA[technology]]></category>
		<guid isPermaLink="false">https://alexievarts.com/?p=5629</guid>

					<description><![CDATA[<p>Spectrum internet setup is pretty straightforward these days. You order it, a box arrives with a modem (and router if you want Spectrum&#8217;s wifi option) you follow a few steps, and you are done. Pretty easy right? As it turns out, however, there are a few tricks and issues that may cause some frustration with [&#8230;]</p>
<p>The post <a href="https://alexievarts.com/technology/spectrum-internet-self-installation-with-a-router/">Spectrum internet self-installation with a router</a> appeared first on <a href="https://alexievarts.com">Alexiev Arts</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="has-drop-cap">Spectrum internet setup is pretty straightforward these days. You order it, a box arrives with a modem (and router if you want Spectrum&#8217;s wifi option) you follow a few steps, and you are done. Pretty easy right? As it turns out, however, there are a few tricks and issues that may cause some frustration with the setup. One example is if you connect your computer to the modem and activate it and later want to add a router. In that scenario, things do not work straightforward at all. The worst part is that Spectrum support would not help and would consistently guide you to your router manufacturer support.</p>



<h1 class="wp-block-heading">No router scenario</h1>



<p>If you do not want/need a router then your setup steps are very straight forward and simply watching Spectrum&#8217;s video should get you set up. It goes step by step. You connect your modem to the cable. Connect your computer to the modem. Activate your modem and you should be good to go.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Self-Installation: Spectrum Internet" width="1104" height="621" src="https://www.youtube.com/embed/T_PL1FbjJvs?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<h1 class="wp-block-heading">Router setup</h1>



<p>The important step here is to make sure you activate your model <strong>only after</strong> you have connected your router to it and your computer to the router. If that is how you activated your model all should be fine and working. The way Spectrum makes the setup easy and secure is to remember your computer mac address</p>



<p>The mistake many people do is to connect the computer to the modem first. Activate the modem and make sure there is a working internet connection. Then adding the router to this setup should just work, right? Well not exactly. What happens is the modem records the computer <a href="https://en.wikipedia.org/wiki/MAC_address" target="_blank" rel="noreferrer noopener">mac address</a> and from that point on it gets tricky to make it work with a router. Unless your router can do a <strong>mac clone</strong>.</p>



<h1 class="wp-block-heading">Mac Clone</h1>



<p>In our case, the router was added after the modem was activated with a computer connected to it. So the mac address of the computer was stored. The initial idea we had was we would set up the router with a static IP (which we got from our computer) and then have the modem as the gateway. That worked until Spectrum issued a new IP to us which was expected since we did not order static IP from them. They can change the IP anytime they want.</p>



<p>So how can you trick the modem to think that the computer that activated the service is the router? Here is where the mac clone functionality of the router comes into play. The router now &#8220;acts&#8221; as the computer with which you activated the service and you can still have your automatic IP setup as expected. Just click on the Mac Clone button and leave the WAN Connection type to &#8220;Automatic IP&#8221;.</p>



<figure class="wp-block-gallery columns-1 is-cropped wp-block-gallery-7 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="https://alexievarts.com/wp-content/uploads/2021/01/CleanShot-2021-01-02-at-13.31.41.png"><img loading="lazy" decoding="async" width="1006" height="1195" src="https://alexievarts.com/wp-content/uploads/2021/01/CleanShot-2021-01-02-at-13.31.41.png" alt="" data-id="5632" data-full-url="https://alexievarts.com/wp-content/uploads/2021/01/CleanShot-2021-01-02-at-13.31.41.png" data-link="https://alexievarts.com/?attachment_id=5632" class="wp-image-5632" srcset="https://alexievarts.com/wp-content/uploads/2021/01/CleanShot-2021-01-02-at-13.31.41.png 1006w, https://alexievarts.com/wp-content/uploads/2021/01/CleanShot-2021-01-02-at-13.31.41-253x300.png 253w, https://alexievarts.com/wp-content/uploads/2021/01/CleanShot-2021-01-02-at-13.31.41-768x912.png 768w" sizes="auto, (max-width: 1006px) 100vw, 1006px" /></a></figure></li></ul></figure>



<p>Our router was <a href="https://www.asus.com/us/Networking/RTAC68W/" target="_blank" rel="noreferrer noopener">Asus RT-AC68W</a> but most if not all recent Asus routers have the mac clone capability. Other router manufacturers have that functionality as well. If you know how to get to your router user interface that should all you need to do.</p>



<p>To get to the router user interface you have to either connect a LAN cable to it and your computer. If it is a wifi router you can join the wifi network it creates. Then with your browser go to <strong>192.168.0.1</strong> or <strong>192.168.1.1</strong>. Those are the usual default addresses manufacturers use. You should follow the manufacturer manual/documentation as to how to log in and get to the WAN settings.</p>
<p>The post <a href="https://alexievarts.com/technology/spectrum-internet-self-installation-with-a-router/">Spectrum internet self-installation with a router</a> appeared first on <a href="https://alexievarts.com">Alexiev Arts</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://alexievarts.com/technology/spectrum-internet-self-installation-with-a-router/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Sony A7III &#8211; Switch Between EVF and LCD via Custom Button</title>
		<link>https://alexievarts.com/photography/sony-a7iii-switch-between-evf-and-lcd-via-custom-button/</link>
					<comments>https://alexievarts.com/photography/sony-a7iii-switch-between-evf-and-lcd-via-custom-button/#respond</comments>
		
		<dc:creator><![CDATA[Akrion]]></dc:creator>
		<pubDate>Sat, 02 Mar 2019 03:34:18 +0000</pubDate>
				<category><![CDATA[Photography]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[evf]]></category>
		<category><![CDATA[lcd]]></category>
		<category><![CDATA[sony]]></category>
		<category><![CDATA[sony a7III]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[tips & tricks]]></category>
		<guid isPermaLink="false">https://alexievarts.com/?p=3232</guid>

					<description><![CDATA[<p>Before we got our first Sony mirrorless camera we tried to do extensive research and compare various other cameras. We had plenty of Nikons and it was time to try something different. From the many reviews, we went through one negative comment was constant &#8211; the Sony menu system. The thing about menu systems is [&#8230;]</p>
<p>The post <a href="https://alexievarts.com/photography/sony-a7iii-switch-between-evf-and-lcd-via-custom-button/">Sony A7III &#8211; Switch Between EVF and LCD via Custom Button</a> appeared first on <a href="https://alexievarts.com">Alexiev Arts</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Before we got our first Sony mirrorless camera we tried to do extensive research and compare various other cameras. We had plenty of Nikons and it was time to try something different. From the many reviews, we went through one negative comment was constant &#8211; the Sony menu system. </p>



<p>The thing about menu systems is that once you set it up you usually do not need to deal with it a lot. And even when you need to you always have a &#8220;Favorites&#8221; or &#8220;My Menu&#8221; where you store those hard to get to items. So we thought this is not a big deal.<br></p>



<p>Well, we got our A7III and we realized that some of the complaints in regards to the menu system are valid. Something as simple as switch between the EVF (Electronic View Finder) and the LCD is quite difficult to do. In fact, you can not unless you assign a custom button! Why would you need to do such a thing you would ask &#8230; good question let me explain:</p>



<h3 class="wp-block-heading">The Problem</h3>



<p>Out of the box, the camera switches automatically between the LCD and the EVF. When you get your eye on the EVF it defects it and shuts down the LCD. When your eye is away from the EVF it shuts it down and turns on the LCD. The issue is that the damn thing is so sensitive that every time you move your finger close to the EVF it shuts down the LCD which is THE thing you are a thing to change or do something with. Very annoying and frustrating after spending time with the camera. So we were on a mission to do this manually. If EVF is needed press a button to turn it on. Otherwise, keep LCD as the primary option. Or the other way around. </p>



<p>Since there are so many custom options you can have there are only a few that are not set and made sense to set this function on. We decided to set the Dial DOWN press to switch between the EVF and the LCD. Here is how we did it:</p>



<h3 class="wp-block-heading">Step 1: Custom Operation1 &gt; Page 8/9 &gt; Custom Key</h3>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1000" height="750" src="https://alexievarts.com/wp-content/uploads/2019/03/IMG_12982.jpg" alt="Sony A7III Custom Operation1 menu" class="wp-image-3230" srcset="https://alexievarts.com/wp-content/uploads/2019/03/IMG_12982.jpg 1000w, https://alexievarts.com/wp-content/uploads/2019/03/IMG_12982-300x225.jpg 300w, https://alexievarts.com/wp-content/uploads/2019/03/IMG_12982-768x576.jpg 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<p>Please note that this selected item (Custom Keys) is a sub-menu for setting the camera custom keys (C1, C2, C3, C4, etc) ONLY when in &#8220;taking pictures mode&#8221;. The menu item underneath it is for setting the custom keys for when in video mode and the last one is for when in preview mode. It is not very self-explanatory. Icons are helping but not that much. Nikon menu system had a help function where you can press a button and see a screen full of explanation about the selected menu. It was VERY helpful. So back to the task at hand. Let&#8217;s get into the Photo Custom Key menu and try to find where the dial DOWN button is and set it to do what we want.</p>



<h3 class="wp-block-heading">Step 2: Custom Key &gt; Page 2 &gt; Down Button</h3>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1000" height="750" src="https://alexievarts.com/wp-content/uploads/2019/03/IMG_1298.jpg" alt="Sony A7III Custom Key Down Button" class="wp-image-3228" srcset="https://alexievarts.com/wp-content/uploads/2019/03/IMG_1298.jpg 1000w, https://alexievarts.com/wp-content/uploads/2019/03/IMG_1298-300x225.jpg 300w, https://alexievarts.com/wp-content/uploads/2019/03/IMG_1298-768x576.jpg 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /><figcaption>&#8220;Finder/Monitor Sel.&#8221; Set for Down Button Custom Button</figcaption></figure>



<p>Once we are in the photo custom key section we go to <strong>page 2</strong> and all the way down select/press on the &#8220;<strong>Down Button</strong>&#8220;. That refers to the main dial down button apparently. Next click on it and from that menu find the Finder/Monitor Sel. function located at page 14/19 in Display / Auto Review sub-menu:</p>



<h3 class="wp-block-heading">Step 3: Display/Auto Review &gt; Page 14/19 &gt; Finder/Monitor Sel.</h3>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="800" height="540" src="https://alexievarts.com/wp-content/uploads/2019/03/DownButtonCustomKey2.jpg" alt="Sony A7III Down Menu Custom Key Sub Menu" class="wp-image-3242" srcset="https://alexievarts.com/wp-content/uploads/2019/03/DownButtonCustomKey2.jpg 800w, https://alexievarts.com/wp-content/uploads/2019/03/DownButtonCustomKey2-300x203.jpg 300w, https://alexievarts.com/wp-content/uploads/2019/03/DownButtonCustomKey2-768x518.jpg 768w, https://alexievarts.com/wp-content/uploads/2019/03/DownButtonCustomKey2-76x50.jpg 76w, https://alexievarts.com/wp-content/uploads/2019/03/DownButtonCustomKey2-123x82.jpg 123w, https://alexievarts.com/wp-content/uploads/2019/03/DownButtonCustomKey2-83x55.jpg 83w, https://alexievarts.com/wp-content/uploads/2019/03/DownButtonCustomKey2-125x83.jpg 125w, https://alexievarts.com/wp-content/uploads/2019/03/DownButtonCustomKey2-264x178.jpg 264w" sizes="auto, (max-width: 800px) 100vw, 800px" /></figure>



<p>Once you select/press on the <strong>Finder/Monitor Sel.</strong> from the above <strong>Display / Auto Review sub-menu</strong> you are set. Now if you press the Down Button you will be able to manually switch between the LCD and the EVF!</p>



<h3 class="wp-block-heading">Step 4: FINDER/MONITOR &gt; Monitor (Manual)</h3>



<p>Ok so we got the button covered but the camera still auto switches between the EVF and the LCD. In order to change that you need to go to the main menu (Just press the Menu button) and go to Display / Auto Review1 and then select FINDER/MONITOR (Yes it is in capital letters on the menu!). Once you select that you will get this on the screen:</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1000" height="750" src="https://alexievarts.com/wp-content/uploads/2019/03/FinderMonitorSetup.jpg" alt="Sony A7III Finder/Monitor menu" class="wp-image-3227" srcset="https://alexievarts.com/wp-content/uploads/2019/03/FinderMonitorSetup.jpg 1000w, https://alexievarts.com/wp-content/uploads/2019/03/FinderMonitorSetup-300x225.jpg 300w, https://alexievarts.com/wp-content/uploads/2019/03/FinderMonitorSetup-768x576.jpg 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /><figcaption>&#8220;Monitor (Manual)&#8221; Selection</figcaption></figure>



<p>We want to select here <strong>Monitor (Manual)</strong> from this menu. Once you do that on start the camera will turn on the LCD and not the EVF EVEN if you have your eye on it. You have to press the Down button to switch between the LCD and the EVF. Pressing again on the Down button would get you back on the LCD and turn the EVF off.</p>



<h3 class="wp-block-heading">Note: Auto Preview</h3>



<p>One thing to note is that if you have Auto preview on and you have set it to one of the time intervals (like 3-5 sec) it would ONLY show on the currently selected viewpoint. So if you are shooting with EVF and you have the auto preview it would show ONLY in the EVF :). For that reason, I have disabled the auto preview and it is only available by pressing the preview button. It actually works great that way since once you know the shot is good you hardly need to check and have the camera show every other picture of that sequence on the LCD or the EVF.</p>
<p>The post <a href="https://alexievarts.com/photography/sony-a7iii-switch-between-evf-and-lcd-via-custom-button/">Sony A7III &#8211; Switch Between EVF and LCD via Custom Button</a> appeared first on <a href="https://alexievarts.com">Alexiev Arts</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://alexievarts.com/photography/sony-a7iii-switch-between-evf-and-lcd-via-custom-button/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
