<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Naomi Pentrel</title>
    <description>The latest articles on DEV Community by Naomi Pentrel (@npentrel).</description>
    <link>https://dev.to/npentrel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F160781%2F41cbd8bd-9c52-492e-b37f-e439b4ef0b31.png</url>
      <title>DEV Community: Naomi Pentrel</title>
      <link>https://dev.to/npentrel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/npentrel"/>
    <language>en</language>
    <item>
      <title>An award-winning devportal is more than words</title>
      <dc:creator>Naomi Pentrel</dc:creator>
      <pubDate>Wed, 07 Jan 2026 11:32:49 +0000</pubDate>
      <link>https://dev.to/npentrel/an-award-winning-devportal-is-more-than-words-1iig</link>
      <guid>https://dev.to/npentrel/an-award-winning-devportal-is-more-than-words-1iig</guid>
      <description>&lt;p&gt;&lt;em&gt;A reflection on 3 years as a Head of Developer Content.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The Viam docs cover a complex and large developer platform, SDKs in multiple languages and APIs that move at the speed of, well, a startup. And for that the docs received several awards. &lt;br&gt;
But where did it start? This &lt;a href="https://web.archive.org/web/20221221171119/https://docs.viam.com/" rel="noopener noreferrer"&gt;Web Archive capture&lt;/a&gt; shows what they looked like three years ago, before I started.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3hiwp9qq50obl6fkm5dp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3hiwp9qq50obl6fkm5dp.png" alt="The front page of the docs as they were 3 years ago" width="800" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My team and I got to work, and a year after that humble starting point, the docs had transformed into something worth reading. We had won multiple awards at the Devportal awards, including the &lt;a href="https://www.linkedin.com/posts/devportal-awards_awards-awards2023-awardsceremony-activity-7136287365001601026-SKsu" rel="noopener noreferrer"&gt;Best Overall SME Devportal award&lt;/a&gt;: we were on the right track.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improving the docs website
&lt;/h2&gt;

&lt;p&gt;A good docs portal isn't just about the technical writing: it is, after all, a website that users of your product have to interact with most days. With that in mind, we also made it a point to add usability features.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;dynamic elements that allowed for filtering changelog entries, tutorials, and modules (the latter long before the product)&lt;/strong&gt;: A combination of Typesense, an open source search engine, and Algolia's InstantSearch.js, an open source UI library allowed us to add these dynamic components to our otherwise static site.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In text glossary items that show more info on hover&lt;/strong&gt;. Hugo is a wonderful framework for creating docs sites if you want to add customization but don't want to use front-end frameworks to build components or the entire thing. In this case I was able to lean on and learn from the work that the writers at K8s had built, who also use Hugo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using GIFs to show features &amp;amp; hardware in action&lt;/strong&gt;: I decided early on to lean on imagery to bring the product to live, because I feel hardware actuation is best conveyed that way. And with Hugo I was able to add shortcodes to allow us to serve GIFs as more bandwidth-friendly videos. Generally I used Hugo a lot to enforce SEO rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6vq75yl2yf73fgmdu8na.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6vq75yl2yf73fgmdu8na.png" alt="Tutorial page of the Viam docs" width="800" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Automation with GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Keeping on top of the documentation surface area for a complex platform, whilst also maintaining a user-facing web application, is no small feat for a small team. We did what we could to make ends meet. Namely: automation. In our case with GitHub Actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Style guide checking with Vale&lt;/strong&gt; - a linter that is focused on prose. After creating regexes that cover the rules from a style guide. Luckily Vale is a long time favourite of mine which I first found at MongoDB and used to &lt;a href="https://github.com/npentrel/vale-mongodb" rel="noopener noreferrer"&gt;write the rules&lt;/a&gt; they still use 5 years later - and which were later were &lt;a href="https://github.com/mongodb/mongodb-vale-action" rel="noopener noreferrer"&gt;released by someone else&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code sample testing&lt;/strong&gt; - I wrote an entire testing suite by putting code samples in files with project setup and teardown and markup to delineate the code samples. This allowed me to then use GitHub Actions and some bash scripts to automatically run the tests and to generate the code samples from them based on the markup delineations. While the initial cost is a bit higher - the end result was e2e tests that caught API changes and outages and provided confidence in the code samples.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tooling to find dead links and surface links that needed forwarding&lt;/strong&gt;. Htmltest is a great tool to check for broken links but checking for links that have gone away and should be forwarded was a bit harder. I finally solved this with a Netlify integration (I believe it was No more 404s). Netlify also helped me move from HTML level forwarding to HTTP level forwarding.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F998r015fxtkf2k5fjdbd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F998r015fxtkf2k5fjdbd.png" alt="GitHub Action screen" width="800" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Generative AI
&lt;/h2&gt;

&lt;p&gt;We also did a lot with generative AI. I wrote a POC for a tool that would update docs based on information from a PR, and then found a vendor that did this even better. Reviewing AI-generated content still requires enormous diligence - but something to look out for in the future. AI chat is far more advanced, and I was somewhat surprised how useful it was - if and only if used with diligence in fact checking. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I find myself wishing that people viewed generative AI output as a different kind of search, because I think this view of it retains the need for critical review better.&lt;/strong&gt; I think we as an industry have some work to do in improving user literacy around how generative AI works, as it’s too easy for users to expect generative AI to have capabilities it doesn’t have (and to entrust AI chats with passwords and secrets).&lt;/p&gt;

&lt;p&gt;The learnings from our AI usage can easily span multiple blog posts. So I’ll leave it at saying that if you’re looking for prebuilt embeddable AI chat tooling, I’d recommend &lt;a href="https://inkeep.com/" rel="noopener noreferrer"&gt;Inkeep&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A single source of truth: SDK docs and "main" docs
&lt;/h2&gt;

&lt;p&gt;Lastly, we leveraged automatic docs generation to reduce our workload. For example, we automatically generated main platform documentation from SDK docs. When I realized people had been copying code samples from SDK docs to the main docs (and vice versa), I pushed for a single source of truth. Code samples that show how to use individual API functions should live with the SDK. The SDK docs are generated from the docstrings in the SDK code, so this also meant that the docs were colocated with the code and therefore more likely to be up to date. So we built a system to ingest the SDK docs and generate parts of the main docs automatically. As the system ran, we were able to see and review new changes, and make edits to the SDK docs if needed. The result was better consistency and less work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;While the docs weren't all I worked on, they are the work I took most pride in. And 3 years later, as I hand over the docs, there is still work to be done - but I am happy with what we accomplished in the time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2rod08p4ofb9i9u3klr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2rod08p4ofb9i9u3klr.png" alt="dev tools page of the current Viam docs" width="800" height="648"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take a look for yourself: &lt;a href="https://docs.viam.com/" rel="noopener noreferrer"&gt;https://docs.viam.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>devjournal</category>
      <category>documentation</category>
      <category>writing</category>
    </item>
    <item>
      <title>Print, Paint, and Program a Guardian to Track Humans and Dogs Using a Pi, Camera, and Servo</title>
      <dc:creator>Naomi Pentrel</dc:creator>
      <pubDate>Wed, 09 Aug 2023 11:57:19 +0000</pubDate>
      <link>https://dev.to/npentrel/print-paint-and-program-a-guardian-to-track-humans-and-dogs-using-a-pi-camera-and-servo-20k8</link>
      <guid>https://dev.to/npentrel/print-paint-and-program-a-guardian-to-track-humans-and-dogs-using-a-pi-camera-and-servo-20k8</guid>
      <description>&lt;p&gt;In the run up to the new Zelda release, I realized you can build a stationary guardian robot with a servo and a camera.&lt;br&gt;
Adding a bit of &lt;a href="https://docs.viam.com/services/ml/" rel="noopener noreferrer"&gt;machine learning&lt;/a&gt;, you can then make the guardian detect objects or people or pets and follow them around by rotating its head.&lt;br&gt;
Luckily, I am not the first one to have the idea to build a guardian and there was already a &lt;a href="https://www.thingiverse.com/thing:2391826" rel="noopener noreferrer"&gt;brilliant guardian 3D model&lt;/a&gt; on Thingiverse with space for LEDs and a servo.&lt;/p&gt;

&lt;p&gt;In this tutorial, I will walk you through the steps to build your own functional guardian with a &lt;a href="https://docs.viam.com/components/servo/" rel="noopener noreferrer"&gt;servo&lt;/a&gt;, a &lt;a href="https://docs.viam.com/components/camera/" rel="noopener noreferrer"&gt;camera&lt;/a&gt;, some LEDs and the &lt;a href="https://docs.viam.com/services/ml/" rel="noopener noreferrer"&gt;ML Model service&lt;/a&gt; and &lt;a href="https://docs.viam.com/services/vision/" rel="noopener noreferrer"&gt;vision service&lt;/a&gt;.&lt;br&gt;
Here's a video of the finished guardian detecting me:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://player.vimeo.com/video/852973061" width="710" height="399"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Hardware requirements
&lt;/h2&gt;

&lt;p&gt;To build your own guardian robot, you need the following hardware:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hardware&lt;/th&gt;
&lt;th&gt;Approximate price&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Raspberry Pi + power cable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Raspberry Pi Camera v1.3 + 50cm ribbon cable&lt;/strong&gt;: The default 15cm ribbon cable is not long enough.&lt;/td&gt;
&lt;td&gt;$15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;180 degree SG90 servo&lt;/strong&gt;: Because of the camera ribbon, I restricted the servo to only 180 degrees.&lt;/td&gt;
&lt;td&gt;$4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3x &lt;strong&gt;10mm RGB LEDs with common cathode&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;$4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;cables&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4x &lt;strong&gt;M2 screws&lt;/strong&gt; to attach the camera&lt;/td&gt;
&lt;td&gt;$2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;speaker&lt;/strong&gt;: Optional if you want music. I used a 4Ω 2W speaker with connected aux in. You can use any speaker you can connect to your Pi.&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Print or order the following printed 3D parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.thingiverse.com/thing:6027280" rel="noopener noreferrer"&gt;this head&lt;/a&gt; which fits the camera&lt;/li&gt;
&lt;li&gt;the decorations for the head from &lt;a href="https://www.thingiverse.com/thing:2387723" rel="noopener noreferrer"&gt;this Guardian Robot model&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;the body, base cover, claws, and leg segments from the &lt;a href="https://www.thingiverse.com/thing:2391826" rel="noopener noreferrer"&gt;Guardian Robot, Hackable&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkytou7cprv1gtb8rjufe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkytou7cprv1gtb8rjufe.png" alt="3d printed parts" width="600" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make the guardian's lights shine through its body, use filament that allows the light to shine through and paint the parts that shouldn't allow light to shine through.&lt;/p&gt;

&lt;p&gt;Optionally, if you want to decorate your guardian, I recommend the following materials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;primer&lt;/strong&gt;: Vallego Surface Primer Grey or other brand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;acrylic paint&lt;/strong&gt;: I ordered armour modelling paint but found that mixing my own colors from a regular acrylic paint set worked best for me.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;modeling grass, stones, glue&lt;/strong&gt;: The Army Painter makes a Battlefields Basing Set which comes with all of this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;a base for the guardian&lt;/strong&gt;: I used a wooden disk with a hole cut in the middle and a box with a hole in the top underneath.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqb3dsmdp2kr8wea3lj1.png" alt="Wooden guardian base" width="400" height="299"&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ground texture&lt;/strong&gt;: If you want the base to look more natural, you can use Vallejo Ground Texture Acrylic or something similar to create patches that look like stone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;wire&lt;/strong&gt;: To allow you to position the legs better, you can thread wire through them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Software requirements
&lt;/h2&gt;

&lt;p&gt;You will use the following software in this tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.python.org/downloads/" rel="noopener noreferrer"&gt;Python 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.viam.com/installation/#install-viam-server" rel="noopener noreferrer"&gt;&lt;code&gt;viam-server&lt;/code&gt;&lt;/a&gt;: Follow the &lt;a href="https://docs.viam.com/installation/#install-viam-server" rel="noopener noreferrer"&gt;installation instructions&lt;/a&gt; to install &lt;code&gt;viam-server&lt;/code&gt; on your Raspberry Pi.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Assemble the robot
&lt;/h2&gt;

&lt;p&gt;You can view a timelapse of the robot assembly here:&lt;br&gt;
&lt;a href="https://imgur.com/gallery/3sCrNh4" rel="noopener noreferrer"&gt;https://imgur.com/gallery/3sCrNh4&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Assemble for testing
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyxanftscc8r0yuytdj57.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyxanftscc8r0yuytdj57.png" alt="Head with camera attachment" width="300" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To assemble the guardian, start with the head and use four M2 screws to screw the camera with attached ribbon cable to the front half of the head.&lt;br&gt;
Optionally, if the green of the camera is visible from the outside, use a marker to color the camera board.&lt;br&gt;
Then put both parts of the head together.&lt;/p&gt;

&lt;p&gt;Your servo probably came with mounting screws and a plastic horn for the gear.&lt;br&gt;
Use the screws to attach the horn to the base of the head.&lt;/p&gt;

&lt;p&gt;Next, get your Raspberry Pi and your servo and connect the servo to the Raspberry Pi by connecting the PWM wire to pin 12, the power wire to pin 2, and the ground wire to pin 8.&lt;/p&gt;

&lt;p&gt;To make it easier for you to see which pin is which, you can print out &lt;a href="https://docs.viam.com/try-viam/viam-raspberry-leaf-8.5x11.pdf" rel="noopener noreferrer"&gt;this Raspberry Pi Leaf&lt;/a&gt; which has labels for the pins and carefully push it onto the pins or fold or cut it so you can hold it up to the Raspberry Pi pins.&lt;br&gt;
If you use A4 paper, use this &lt;a href="https://docs.viam.com/try-viam/viam-raspberry-leaf-A4.pdf" rel="noopener noreferrer"&gt;this Raspberry Pi Leaf&lt;/a&gt; instead.&lt;/p&gt;

&lt;p&gt;If you are having trouble punching the pins through, you can pre-punch the pin holes with a pen.&lt;br&gt;
Only attach the paper when the Pi is unplugged.&lt;br&gt;
To make attaching the paper easier, use a credit card or a small screwdriver.&lt;/p&gt;

&lt;p&gt;Then attach the head to the servo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5mf8cubxgdefmfv93ij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5mf8cubxgdefmfv93ij.png" alt="A Raspberry Pi connected to a FS90R servo. The yellow PWM wire is attached to pin twelve on the raspberry pi. The red five-volt wire is attached to pin two. The black ground wire is attached to pin eight" width="800" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, get the three 10mm RGB LEDs ready.&lt;br&gt;
Attach the common cathode of each LED to a &lt;a href="https://pinout.xyz/pinout/ground" rel="noopener noreferrer"&gt;ground pin&lt;/a&gt; on your Raspberry Pi.&lt;br&gt;
Attach the wires for the red and the blue LEDs to &lt;a href="https://pinout.xyz/pinout/wiringpi" rel="noopener noreferrer"&gt;GPIO pins&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flggoqzs18c54n5tw09yf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flggoqzs18c54n5tw09yf.png" alt="Components assembled for testing" width="400" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before continuing with assembly, you should test your components work as expected.&lt;br&gt;
To be able to test the components, you need to install &lt;code&gt;viam-server&lt;/code&gt; and configure your components.&lt;/p&gt;
&lt;h3&gt;
  
  
  Install &lt;code&gt;viam-server&lt;/code&gt; and connect to your robot
&lt;/h3&gt;

&lt;p&gt;Go to the &lt;a href="https://app.viam.com" rel="noopener noreferrer"&gt;Viam app&lt;/a&gt; and create a new robot called &lt;code&gt;guardian&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Go to the &lt;strong&gt;Setup&lt;/strong&gt; tab of your new robot's page and follow the steps &lt;a href="https://docs.viam.com/installation/" rel="noopener noreferrer"&gt;to install &lt;code&gt;viam-server&lt;/code&gt; on your computer&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Configure the components
&lt;/h3&gt;

&lt;p&gt;Navigate to the &lt;strong&gt;Config&lt;/strong&gt; tab of your robot's page in &lt;a href="https://app.viam.com" rel="noopener noreferrer"&gt;the Viam app&lt;/a&gt;.&lt;br&gt;
Click on the &lt;strong&gt;Components&lt;/strong&gt; subtab and navigate to the &lt;strong&gt;Create component&lt;/strong&gt; menu.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add the board.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enter &lt;code&gt;local&lt;/code&gt; for the name for your &lt;a href="https://docs.viam.com/components/board/" rel="noopener noreferrer"&gt;board component&lt;/a&gt;, select the type &lt;code&gt;board&lt;/code&gt;, and select the &lt;code&gt;pi&lt;/code&gt; model.&lt;br&gt;
Then click &lt;strong&gt;Create component&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add the camera.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a &lt;a href="https://docs.viam.com/components/camera/" rel="noopener noreferrer"&gt;camera component&lt;/a&gt; with the name &lt;code&gt;cam&lt;/code&gt;, the type &lt;code&gt;camera&lt;/code&gt; and the model &lt;code&gt;webcam&lt;/code&gt;.&lt;br&gt;
Click &lt;strong&gt;Create Component&lt;/strong&gt; to add the camera.&lt;br&gt;
In the new camera panel, click the &lt;strong&gt;Video Path&lt;/strong&gt; field to reveal a drop-down populated with camera paths that have been identified on your machine.&lt;br&gt;
Select &lt;code&gt;mmal service 16.1 (platform:bcm2835_v4l2-0)&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add the servo.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a &lt;a href="https://docs.viam.com/components/servo/" rel="noopener noreferrer"&gt;servo component&lt;/a&gt; with the name &lt;code&gt;servo&lt;/code&gt;, the type &lt;code&gt;servo&lt;/code&gt; and the model &lt;code&gt;pi&lt;/code&gt;.&lt;br&gt;
Click &lt;strong&gt;Create Component&lt;/strong&gt; to add the servo.&lt;br&gt;
Configure the attributes by adding the name of your board, &lt;code&gt;local&lt;/code&gt;, and the pin number of the pin on &lt;code&gt;local&lt;/code&gt; that you connected your servo PWM wire to, &lt;code&gt;12&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"12"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"board"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"local"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;Click &lt;strong&gt;Save config&lt;/strong&gt; in the bottom left corner of the screen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test the components
&lt;/h3&gt;

&lt;p&gt;Navigate to your &lt;a href="https://docs.viam.com/manage/fleet/robots/#control" rel="noopener noreferrer"&gt;robot's Control tab&lt;/a&gt; to test your components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd937nw8r9aq71eoprzt5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd937nw8r9aq71eoprzt5.png" alt="the control tab" width="600" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the servo panel and increase or decrease the servo angle to test that the servo moves.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfc7g5nrbibxq8ksapbp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfc7g5nrbibxq8ksapbp.png" alt="the control tab servo panel" width="600" height="136"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, click on the board panel.&lt;br&gt;
The board panel allows you to get and set pin states.&lt;br&gt;
Set the pin states for the pins your LEDs are connected to to high to test that they light up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feiu1b2u671dqkb76z0u6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feiu1b2u671dqkb76z0u6.png" alt="the control tab board panel" width="600" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, click on the camera panel and toggle the camera on to test that you get video from your camera.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fruf4r2cytbcjeil1klw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fruf4r2cytbcjeil1klw9.png" alt="the control tab camera panel" width="600" height="513"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Assemble and decorate
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvs3ak8g6kwvl4l9ka5x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvs3ak8g6kwvl4l9ka5x.png" alt="Fully assembled guardian" width="300" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you have tested your components, you can disconnect them again, paint and decorate your guardian, and then put the rest of the guardian together.&lt;br&gt;
Remove the servo horn, and place one LED in the back of the Guardian head, leaving the wires hanging out behind the ribbon camera.&lt;/p&gt;

&lt;p&gt;Then place the servo inside the Guardian body and attach the horn on the head to the servo's gear.&lt;br&gt;
Carefully place the remaining two LEDs in opposite directions inside the body.&lt;br&gt;
Thread all the cables through the hole in the lid for the base of the guardian, and close the lid.&lt;/p&gt;

&lt;p&gt;Use a suitable base with a hole, like a box with a hole cut into the top, to place your guardian on top of and reconnect all the wires to the Raspberry Pi.&lt;/p&gt;

&lt;p&gt;At this point also connect the speaker to your Raspberry Pi.&lt;/p&gt;

&lt;p&gt;Then test the components on the &lt;a href="https://docs.viam.com/manage/fleet/robots/#control" rel="noopener noreferrer"&gt;robot's Control tab&lt;/a&gt; again to ensure everything still works.&lt;/p&gt;
&lt;h2&gt;
  
  
  Detect persons and pets
&lt;/h2&gt;

&lt;p&gt;For the guardian to be able to detect living beings, you can use &lt;a href="https://github.com/viam-labs/devrel-demos/raw/main/Light%20up%20bot/effdet0.tflite" rel="noopener noreferrer"&gt;this Machine Learning model&lt;/a&gt;.&lt;br&gt;
The model can detect a variety of things which you can see in the associated &lt;a href="https://github.com/viam-labs/devrel-demos/raw/main/Light%20up%20bot/labels.txt" rel="noopener noreferrer"&gt;labels.txt&lt;/a&gt; file.&lt;/p&gt;

&lt;p&gt;You can also &lt;a href="https://docs.viam.com/manage/ml/train-model/" rel="noopener noreferrer"&gt;train your own custom model&lt;/a&gt; based on images from your robot but the provided Machine Learning model is a good one to start with.&lt;/p&gt;

&lt;p&gt;To use the provided Machine Learning model, copy the &lt;a href="https://github.com/viam-labs/devrel-demos/raw/main/Light%20up%20bot/effdet0.tflite" rel="noopener noreferrer"&gt;effdet0.tflite&lt;/a&gt; file and the &lt;a href="https://github.com/viam-labs/devrel-demos/raw/main/Light%20up%20bot/labels.txt" rel="noopener noreferrer"&gt;labels.txt&lt;/a&gt; to your Raspberry Pi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp effdet0.tflite pi@guardian.local:/home/pi/effdet0.tflite
scp labels.txt pi@guardian.local:/home/pi/labels.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, navigate to the &lt;strong&gt;Config&lt;/strong&gt; tab of your robot's page in &lt;a href="https://app.viam.com" rel="noopener noreferrer"&gt;the Viam app&lt;/a&gt;.&lt;br&gt;
Click on the &lt;strong&gt;Services&lt;/strong&gt; subtab and navigate to the &lt;strong&gt;Create service&lt;/strong&gt; menu.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add a ML model service.&lt;/strong&gt;&lt;br&gt;
The &lt;a href="https://docs.viam.com/services/ml/" rel="noopener noreferrer"&gt;ML model service&lt;/a&gt; allows you to deploy the provided machine learning model to your robot.&lt;br&gt;
Create an ML model with the name &lt;code&gt;mlmodel&lt;/code&gt;, the type &lt;code&gt;mlmodel&lt;/code&gt; and the model &lt;code&gt;tflite_cpu&lt;/code&gt;.&lt;br&gt;
Then click &lt;strong&gt;Create Service&lt;/strong&gt;.&lt;br&gt;
In the new ML Model panel, select &lt;strong&gt;Path to Existing Model On Robot&lt;/strong&gt; for the &lt;strong&gt;Deployment&lt;/strong&gt;.&lt;br&gt;
Then specify the absolute &lt;strong&gt;Model Path&lt;/strong&gt; as &lt;code&gt;/home/pi/effdet0.tflite&lt;/code&gt; and the &lt;strong&gt;Label Path&lt;/strong&gt; as &lt;code&gt;/home/pi/labels.txt&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add a vision service.&lt;/strong&gt;&lt;br&gt;
Next, add a &lt;a href="https://docs.viam.com/services/vision/detection/" rel="noopener noreferrer"&gt;detector&lt;/a&gt; as a vision service to be able to make use of the ML model.&lt;br&gt;
Create an vision service with the name &lt;code&gt;detector&lt;/code&gt;, the type &lt;code&gt;vision&lt;/code&gt; and the model &lt;code&gt;mlmodel&lt;/code&gt;.&lt;br&gt;
Then click &lt;strong&gt;Create Service&lt;/strong&gt;.&lt;br&gt;
In the new detector panel, select the &lt;code&gt;mlmodel&lt;/code&gt; you configured in the previous step.&lt;br&gt;
Click &lt;strong&gt;Save config&lt;/strong&gt; in the bottom left corner of the screen.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add a &lt;code&gt;transform&lt;/code&gt; camera.&lt;/strong&gt;&lt;br&gt;
To be able to test that the vision service is working, add a &lt;code&gt;transform&lt;/code&gt; camera which will add bounding boxes and labels around the objects the service detects.&lt;br&gt;
Click on the &lt;strong&gt;Components&lt;/strong&gt; subtab and navigate to the &lt;strong&gt;Create component&lt;/strong&gt; menu.&lt;br&gt;
Create a &lt;a href="https://docs.viam.com/components/camera/transform/" rel="noopener noreferrer"&gt;transform camera&lt;/a&gt; with the name &lt;code&gt;transform_cam&lt;/code&gt;, the type &lt;code&gt;camera&lt;/code&gt; and the model &lt;code&gt;transform&lt;/code&gt;.&lt;br&gt;
Replace the attributes JSON object with the following object which specifies the camera source that the &lt;code&gt;transform&lt;/code&gt; camera will be using and defines a pipeline that adds the defined &lt;code&gt;detector&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cam"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"pipeline"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"detections"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="nl"&gt;"detector_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"detector"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="nl"&gt;"confidence_threshold"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Click &lt;strong&gt;Save config&lt;/strong&gt; in the bottom left corner of the screen.&lt;/p&gt;

&lt;p&gt;Navigate to your &lt;a href="https://docs.viam.com/manage/fleet/robots/#control" rel="noopener noreferrer"&gt;robot's Control tab&lt;/a&gt; to test the transform camera.&lt;br&gt;
Click on the transform camera panel and toggle the camera on, then point your camera at a person or pet to test if the vision service detects them.&lt;br&gt;
You should see bounding boxes with labels around different objects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmjlim20jcy3e7yk5zfiq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmjlim20jcy3e7yk5zfiq.png" alt="the control tab transform camera panel" width="600" height="449"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Program the Guardian
&lt;/h2&gt;

&lt;p&gt;With the guardian completely configured and the configuration tested, it's time to make the robot guardian behave like a "real" guardian by programming the person and pet detection, lights, music, and movement.&lt;/p&gt;

&lt;p&gt;The full code is available at the end of the tutorials.&lt;/p&gt;
&lt;h3&gt;
  
  
  Set up the Python environment
&lt;/h3&gt;

&lt;p&gt;We are going to use Virtualenv to set up a virtual environment for this project, in order to isolate the dependencies of this project from other projects.&lt;br&gt;
Run the following commands in your command-line to install virtualenv, set up an environment &lt;code&gt;venv&lt;/code&gt; and activate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; virtualenv
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv &lt;span class="nb"&gt;env
source env&lt;/span&gt;/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, install the Python Viam SDK and the VLC module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip3 &lt;span class="nb"&gt;install &lt;/span&gt;viam-sdk python-vlc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Connect
&lt;/h3&gt;

&lt;p&gt;Next, go to the &lt;strong&gt;Code sample&lt;/strong&gt; tab on your robot page and select &lt;strong&gt;Python&lt;/strong&gt;, then click &lt;strong&gt;Copy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This code snippet imports all the necessary packages and sets up a connection with the Viam app in the cloud.&lt;/p&gt;

&lt;p&gt;Next, create a file named main.py and paste the boilerplate code from the &lt;strong&gt;Code sample&lt;/strong&gt; tab of the Viam app into your file.&lt;br&gt;
Then, save your file.&lt;/p&gt;

&lt;p&gt;Run the code to verify that the Viam SDK is properly installed and that the &lt;code&gt;viam-server&lt;/code&gt; instance on your robot is live.&lt;/p&gt;

&lt;p&gt;You can run your code by typing the following into your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The program prints a list of robot resources.&lt;/p&gt;

&lt;p&gt;On top of the packages that the code sample snippet imports, add the &lt;code&gt;random&lt;/code&gt; and the &lt;code&gt;vlc&lt;/code&gt; package to the imports.&lt;br&gt;
The top of your code should now look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;vlc&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;viam.robot.client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RobotClient&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;viam.rpc.dial&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Credentials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DialOptions&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;viam.components.board&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Board&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;viam.components.camera&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Camera&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;viam.components.servo&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Servo&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;viam.services.vision&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;VisionClient&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;creds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Credentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;robot-location-secret&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;LOCATION SECRET FROM THE VIAM APP&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RobotClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;refresh_interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;dial_options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;DialOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;RobotClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;at_address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ADDRESS FROM THE VIAM APP&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will update the &lt;code&gt;main()&lt;/code&gt; method later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lighting
&lt;/h3&gt;

&lt;p&gt;Next, you'll write the code to manage the LEDs.&lt;br&gt;
Underneath the &lt;code&gt;connect()&lt;/code&gt; function, add the following class which allows you to create groups of LEDs that you can then turn on and off with one method call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LedGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;group&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pin&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to test this code, change your &lt;code&gt;main()&lt;/code&gt; method to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;robot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;local&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Board&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_robot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;local&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;red_leds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LedGroup&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;22&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;24&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;26&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;blue_leds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LedGroup&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;11&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;13&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;15&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;blue_leds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can test the code by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Guardian lights up blue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Detections
&lt;/h3&gt;

&lt;p&gt;Now, you'll add the code for the Guardian to detect persons and pets.&lt;br&gt;
If you are building it for persons or cats or dogs, you'll want to use &lt;code&gt;Person&lt;/code&gt;, &lt;code&gt;Dog&lt;/code&gt;, &lt;code&gt;Cat&lt;/code&gt;, and, if you have a particularly teddy-bear-like dog, &lt;code&gt;Teddy bear&lt;/code&gt;.&lt;br&gt;
You can also specify different ones based on the available labels in &lt;a href="https://github.com/viam-labs/devrel-demos/raw/main/Light%20up%20bot/labels.txt" rel="noopener noreferrer"&gt;labels.txt&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Above the &lt;code&gt;connect()&lt;/code&gt; method, add the following variable which defines the labels that you want to look for in detections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;LIVING_OBJECTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Person&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dog&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Teddy bear&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, above the &lt;code&gt;main()&lt;/code&gt; method add the following function which checks detections for living creatures as they are defined in the &lt;code&gt;LIVING_OBJECTS&lt;/code&gt; variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_for_living_creatures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;detections&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;detections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;confidence&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class_name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;LIVING_OBJECTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;detected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Idling
&lt;/h3&gt;

&lt;p&gt;Underneath the &lt;code&gt;check_for_living_creatures()&lt;/code&gt; function, add the following function which gets images from the Guardian's camera and checks them for living creatures and if none are detected moves the servo randomly.&lt;br&gt;
If a creature is detected, the red LEDs will light up and music will play.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;idle_and_check_for_living_creatures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blue_leds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;red_leds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;living_creature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;random_number_checks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_playing&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;random_number_checks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random_number_checks&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;detections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;detector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_detections_from_camera&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;living_creature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;check_for_living_creatures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;detections&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;living_creature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;red_leds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;blue_leds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_playing&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
                    &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;living_creature&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;START IDLE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;blue_leds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;red_leds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_playing&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Focus
&lt;/h3&gt;

&lt;p&gt;There is one last function that you need to add before you can write the full &lt;code&gt;main()&lt;/code&gt; function and that is a function to focus on a given creature.&lt;br&gt;
The function calculates the center of the detected object and then checks if that center is close to the middle of the entire image.&lt;br&gt;
If it is not near the middle of the entire image, the function moves the servo to the left or right to attempt to center the object.&lt;/p&gt;

&lt;p&gt;Add the following function above your &lt;code&gt;main()&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;focus_on_creature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;creature_midpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creature&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x_max&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;creature&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x_min&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="n"&gt;image_midpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="n"&gt;center_min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_midpoint&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;image_midpoint&lt;/span&gt;
    &lt;span class="n"&gt;center_max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_midpoint&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;image_midpoint&lt;/span&gt;

    &lt;span class="n"&gt;movement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_midpoint&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;creature_midpoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;image_midpoint&lt;/span&gt;
    &lt;span class="n"&gt;angular_scale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MOVE BY: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;angular_scale&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_position&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creature_midpoint&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;center_min&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;creature_midpoint&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;center_max&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;angular_scale&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;servo_angle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;servo_return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_position&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;servo get_position return value: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;servo_return_value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Main logic
&lt;/h3&gt;

&lt;p&gt;The main logic for the guardian robot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;initializes all the variables&lt;/li&gt;
&lt;li&gt;turns all LEDs blue&lt;/li&gt;
&lt;li&gt;loads a music file &lt;code&gt;guardian.mp3&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;runs an infinite loop where it calls the &lt;code&gt;idle_and_check_for_living_creatures()&lt;/code&gt; function and when a creature is found calls the &lt;code&gt;focus_on_creature()&lt;/code&gt; function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Copy a suitable music file to the directory where your code is running and name it &lt;code&gt;guardian.mp3&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Replace your &lt;code&gt;main()&lt;/code&gt; function with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;robot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;local&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Board&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_robot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;local&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cam&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_robot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cam&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_image&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;servo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Servo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_robot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;servo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;red_leds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LedGroup&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;22&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;24&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;26&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;blue_leds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LedGroup&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;11&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;13&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;15&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;blue_leds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;music_player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vlc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MediaPlayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;guardian.mp3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# grab Viam's vision service for the detector
&lt;/span&gt;    &lt;span class="n"&gt;detector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;VisionClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_robot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;detector&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# move head periodically left and right until movement is spotted.
&lt;/span&gt;        &lt;span class="n"&gt;living_creature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;idle_and_check_for_living_creatures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blue_leds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;red_leds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;focus_on_creature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;living_creature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Don't forget to close the robot when you're done!
&lt;/span&gt;    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, run the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything works, your guardian should now start to idle and when it detects humans or dogs or cats turn red, start music, and focus on the detected being.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run the program automatically
&lt;/h2&gt;

&lt;p&gt;One more thing.&lt;br&gt;
Right now, you have to run the code manually every time you want your Guardian to work.&lt;br&gt;
You can also configure Viam to automatically run your code as a &lt;a href="https://docs.viam.com/manage/configuration/#processes" rel="noopener noreferrer"&gt;process&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To be able to run the Python script from your Raspberry Pi, you need to install the Python SDK on your Raspberry Pi and copy your code onto the Raspberry Pi.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.viam.com/installation/prepare/rpi-setup/#connect-with-ssh" rel="noopener noreferrer"&gt;&lt;code&gt;ssh&lt;/code&gt; into your Pi&lt;/a&gt; and install &lt;code&gt;pip&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;python3-pip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a folder &lt;code&gt;guardian&lt;/code&gt; inside your home directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;guardian
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then install the Viam Python SDK and the VLC module &lt;strong&gt;into that folder&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip3 &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;guardian viam-sdk python-vlc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit out of your connection to your Pi and use &lt;code&gt;scp&lt;/code&gt; to copy your code to your Pi into your new folder.&lt;br&gt;
Your hostname may be different:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp main.py pi@guardian.local:/home/pi/guardian/main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also copy your music file over:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp guardian.mp3 pi@guardian.local:/home/pi/guardian/guardian.mp3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now navigate to the &lt;strong&gt;Config&lt;/strong&gt; tab of your robot's page in &lt;a href="https://app.viam.com" rel="noopener noreferrer"&gt;the Viam app&lt;/a&gt;.&lt;br&gt;
Click on the &lt;strong&gt;Processes&lt;/strong&gt; subtab and navigate to the &lt;strong&gt;Create process&lt;/strong&gt; menu.&lt;/p&gt;

&lt;p&gt;Enter &lt;code&gt;main&lt;/code&gt; as the process name and click &lt;strong&gt;Create process&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the new process panel, enter &lt;code&gt;python3&lt;/code&gt; as the executable, &lt;code&gt;main.py&lt;/code&gt; as the argument, and the working directory of your Raspberry Pi as &lt;code&gt;/home/pi/guardian&lt;/code&gt;.&lt;br&gt;
Click on &lt;strong&gt;Add argument&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Save config&lt;/strong&gt; in the bottom left corner of the screen.&lt;/p&gt;

&lt;p&gt;Now your guardian starts behaving like a guardian automatically once booted!&lt;/p&gt;
&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;You now have a functioning guardian robot which you can use to monitor your pets or people. Or simply use to greet you when you get back to your desk.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://player.vimeo.com/video/852971649" width="710" height="399"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Of course, you’re free to adapt the code to make it do something else, add more LEDs, or even train your own custom model to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;vlc&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;viam.robot.client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RobotClient&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;viam.rpc.dial&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Credentials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DialOptions&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;viam.components.board&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Board&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;viam.components.camera&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Camera&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;viam.components.servo&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Servo&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;viam.services.vision&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;VisionClient&lt;/span&gt;

&lt;span class="n"&gt;LIVING_OBJECTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Person&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dog&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Teddy bear&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;creds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Credentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;robot-location-secret&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SECRET_FROM_VIAM_APP&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RobotClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;refresh_interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;dial_options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;DialOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;RobotClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;at_address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;guardian-main.vw3iu72d8n.viam.cloud&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_for_living_creatures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;detections&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;detections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;confidence&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class_name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;LIVING_OBJECTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;detected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;focus_on_creature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;creature_midpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creature&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x_max&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;creature&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x_min&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="n"&gt;image_midpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="n"&gt;center_min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_midpoint&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;image_midpoint&lt;/span&gt;
    &lt;span class="n"&gt;center_max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_midpoint&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;image_midpoint&lt;/span&gt;

    &lt;span class="n"&gt;movement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_midpoint&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;creature_midpoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;image_midpoint&lt;/span&gt;
    &lt;span class="n"&gt;angular_scale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MOVE BY: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;angular_scale&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_position&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creature_midpoint&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;center_min&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;creature_midpoint&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;center_max&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;angular_scale&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;servo_angle&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;servo_angle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;servo_return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_position&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;servo get_position return value: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;servo_return_value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LedGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;group&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pin&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;idle_and_check_for_living_creatures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blue_leds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;red_leds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;living_creature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;random_number_checks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_playing&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;random_number_checks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random_number_checks&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;detections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;detector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_detections_from_camera&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;living_creature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;check_for_living_creatures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;detections&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;living_creature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;red_leds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;blue_leds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_playing&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
                    &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;living_creature&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;START IDLE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;blue_leds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;red_leds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_playing&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;robot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;local&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Board&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_robot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;local&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cam&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_robot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cam&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_image&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;servo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Servo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_robot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;servo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;red_leds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LedGroup&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;22&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;24&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;26&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;blue_leds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LedGroup&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;11&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;13&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpio_pin_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;15&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;blue_leds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;led_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;music_player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vlc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MediaPlayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;guardian.mp3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# grab Viam's vision service for the detector
&lt;/span&gt;    &lt;span class="n"&gt;detector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;VisionClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_robot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;detector&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# move head periodically left and right until movement is spotted.
&lt;/span&gt;        &lt;span class="n"&gt;living_creature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;idle_and_check_for_living_creatures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cam&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blue_leds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;red_leds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;music_player&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;focus_on_creature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;living_creature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;servo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Don't forget to close the robot when you're done!
&lt;/span&gt;    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>robotics</category>
      <category>tutorial</category>
      <category>python</category>
      <category>learning</category>
    </item>
    <item>
      <title>Docker Containers vs VMs</title>
      <dc:creator>Naomi Pentrel</dc:creator>
      <pubDate>Sun, 21 Jul 2019 15:26:11 +0000</pubDate>
      <link>https://dev.to/npentrel/docker-containers-vs-vms-257i</link>
      <guid>https://dev.to/npentrel/docker-containers-vs-vms-257i</guid>
      <description>&lt;p&gt;&lt;strong&gt;Virtual Machines (VMs)&lt;/strong&gt; and &lt;strong&gt;Docker containers&lt;/strong&gt; are two technologies that can help with resource utilization, enabling you to run multiple apps in isolated environments on the same infrastructure.&lt;/p&gt;

&lt;p&gt;Given a terminal on a VM or a container, either will behave much as though it was in fact a dedicated machine. This can make it hard to differentiate between VMs and containers, especially if you are just getting started with Docker. To help with that, this blog post will show you how both function under the hood, while pointing out their similarities and differences. No previous knowledge of VMs or containers is necessary for this post.&lt;/p&gt;

&lt;h4&gt;
  
  
  Virtual Machines and Containers
&lt;/h4&gt;

&lt;p&gt;VMs have been around for a long time, allowing physical machines to run multiple operating systems and multiple isolated apps. VMs are similar to "regular" physical computers: they run an operating system, have a lot of libraries installed, and run applications. The difference is that a virtual machine does not have its own dedicated hardware. Instead, VMs use the physical machine's underlying infrastructure through software that imitates dedicated hardware. The software that virtualizes hardware for VMs is called a hypervisor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fng4zz7hskwn4welxnerl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fng4zz7hskwn4welxnerl.png" alt="Multiple VMs that run on top of a hypervisor which regulates access to underlying infrastructure." width="400" height="359"&gt;&lt;/a&gt;&lt;/p&gt;
Source: https://docs.docker.com/get-started/#containers-and-virtual-machines



&lt;p&gt;The fact that each VM has its own operating system makes VMs require quite a bit of storage and other resources. To reduce the needed resources per running application, people came up with containers.&lt;/p&gt;

&lt;p&gt;While containerization had been around for a while on various operating systems, the community rallied behind Docker which was first released in 2013. During that time, the tech world (and the DevOps world in particular) was looking for solutions that would make deploying and scaling microservices more efficient. Docker managed to address that need by making Linux's LXC containerization easier to use and more accessible. They took the heavy lifting and planning that usually went into configuring a container and turned it into writing a Docker file which then did that work for you. This ease of use is what made Docker so popular; the fact that Docker was open source from the start certainly also helped.&lt;/p&gt;

&lt;p&gt;Containers allow developers to minimize the resources they need by only packaging an application and its exact dependencies. Instead of running on a hypervisor the containers run on top of a container runtime environment which is installed on an operating system. While VMs use virtualized hardware, containers use underlying resources of the host operating system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqh7kqrepsnbnag6rwwyu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqh7kqrepsnbnag6rwwyu.png" alt="Multiple containers that run on top of Docker which is installed on the host operating system which regulates access to underlying infrastructure." width="400" height="359"&gt;&lt;/a&gt;&lt;/p&gt;
Source: https://docs.docker.com/get-started/#containers-and-virtual-machines



&lt;p&gt;Comparing VMs and containers to houses and apartments can help make these differences more apparent: A house has its own water pipes, its own internet cable, and its own garbage disposal system. Apartments on the other hand have these resources managed by their apartment complex and can access the resources of the entire building without having to each have their own separate version. House rules ensure that apartment residents do not irritate each other and get a fair share of all resources.&lt;/p&gt;

&lt;p&gt;Virtual Machines are like houses in this comparison. They each have their own operating system with its own dedicated resources (e.g. kernel, filesystem, process tree, network stack). The VM accesses CPU, storage, RAM etc. through a hypervisor which virtualizes the hardware.&lt;/p&gt;

&lt;p&gt;Containers are much more like apartments. They only have exactly what they need to run their application. They share the underlying operating system's resources (e.g. kernel, filesystem, process tree, network stack) which are isolated by the container runtime environment which enforces rules around the resources particular containers have access to. Overall, this model makes containers a much more lightweight solution.&lt;/p&gt;

&lt;p&gt;These differences in how containers and VMs function under the hood make containers a lot faster to provision and means they are often (and generally should be) used as immutable, non-persistent constructs. Containers live and die and are largely not something you ought to care about (unless they all die at the same time!). VMs, on the other hand, often have a longer life span, you spend more time configuring them and you probably care if something happens to them.&lt;/p&gt;

&lt;p&gt;On a high level, the differences between containers and VMs can be summarized by saying that VMs are considered to be a virtualization technology and containers an application delivery technology.&lt;/p&gt;

&lt;h4&gt;
  
  
  Learn more
&lt;/h4&gt;

&lt;p&gt;This was our concise overview of VMs and containers. If you are interested to learn more, check out: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/npentrel/docker-jargon-from-dockerfile-to-container-942"&gt;Docker Jargon: FROM Dockerfile to Container&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=wjvyN_r-zkk" rel="noopener noreferrer"&gt;Docker tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/npentrel/SmoothDevOps/raw/master/cheatsheets/01%20Docker%20Cheatsheet.pdf" rel="noopener noreferrer"&gt;Docker cheatsheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/get-started/" rel="noopener noreferrer"&gt;Docker's get started guide&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Docker-Deep-Dive-Nigel-Poulton-ebook/dp/B01LXWQUFF" rel="noopener noreferrer"&gt;Nigel Poulton's Docker Deep Dive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://orhandogan.net/docker/" rel="noopener noreferrer"&gt;orhandogan.net/docker/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>containerization</category>
      <category>containers</category>
      <category>vms</category>
    </item>
    <item>
      <title>Docker Jargon: FROM Dockerfile to Container</title>
      <dc:creator>Naomi Pentrel</dc:creator>
      <pubDate>Sun, 21 Jul 2019 15:25:32 +0000</pubDate>
      <link>https://dev.to/npentrel/docker-jargon-from-dockerfile-to-container-942</link>
      <guid>https://dev.to/npentrel/docker-jargon-from-dockerfile-to-container-942</guid>
      <description>&lt;p&gt;There are quite a few terms that get thrown around in the Docker community. Even the word Docker has a (slightly hidden) meaning. In &lt;em&gt;Docker Deep Dive&lt;/em&gt; Nigel Poulton explains that "the word 'Docker' comes from a British colloquialism meaning &lt;strong&gt;dock&lt;/strong&gt; work_er_ - somebody who loads and unloads cargo ships."&lt;/p&gt;

&lt;p&gt;While you can use Docker without knowing where its name originated from, it is important that you know the jargon. To that end, this blog post will show you the main terms in the Docker world along with their meaning. &lt;/p&gt;

&lt;p&gt;If you’re new to Docker or have always wanted a more thorough explanation, this post is for you. You do not need any special knowledge to follow along. After reading this post you will know the meaning of the following terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Docker Container&lt;/li&gt;
&lt;li&gt;Docker Image&lt;/li&gt;
&lt;li&gt;Dockerfile&lt;/li&gt;
&lt;li&gt;Layers&lt;/li&gt;
&lt;li&gt;Docker Volumes&lt;/li&gt;
&lt;li&gt;Docker Engine&lt;/li&gt;
&lt;li&gt;Image Registries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntofu371zp4d2piky82d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntofu371zp4d2piky82d.png" alt="Docker logo" width="792" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Docker markets itself as a container platform that helps developers &lt;strong&gt;build, ship, and run&lt;/strong&gt; &lt;strong&gt;any application in any environment&lt;/strong&gt;. Apps written on your computer will run the exact same way on your friend's computer, a bare metal server, the cloud, etc. That includes hosts with different operating systems such as Windows and Mac computers. To run Linux containers on both of these, Docker uses a light-weight Linux VM that operates on top of a hypervisor (xhyve for Mac and Hyper-V or VirtualBox for Windows).&lt;/p&gt;

&lt;p&gt;You can look at the benefits of Docker from the perspective of two groups of people: DevOps folks, and developers. If you're a developer, the benefit of Docker is that you can set up one environment which you can use for both testing and for production. Iterating on, testing, and deploying changes should be very fast. On top of that, containers solve the problem of 'it works for me'-bugs because everything will be exactly the same regardless where you deploy. If you do DevOps, containers allow you to focus more on container management while removing the responsibility of configuring machines. Now that you know about Docker, the next step is Docker containers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frgoc4eklaqos0zl2tjsm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frgoc4eklaqos0zl2tjsm.png" alt="A Dockerfile is turned into a Docker Image by running the command  raw `docker build .` endraw . A Docker Container is run on top of a Docker Image by running the command  raw `docker run` endraw ." width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;container&lt;/strong&gt; packages code and dependencies together to create a light-weight, abstracted, portable app. Containerizing apps allows you to maximize the utilization of a machine's resources by allowing you to run many apps. Each container is run in its own isolated environment. Docker containers are created on top of Docker Images.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;Docker Image&lt;/strong&gt; can be thought of as a blueprint of an application. It's important to understand the difference between images and containers: An image is not the same as a running container - it's merely a snapshot of a container. Given such a snapshot the Docker engine knows how to create a container when a &lt;code&gt;docker run&lt;/code&gt; command is issued but the snapshot itself is only a lifeless read-only blueprint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykn7olzmlp2h82phicww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykn7olzmlp2h82phicww.png" alt="Photoshopped version of René Magritte's painting 'The Treachery of Images'. A container is in the middle and underneath it reads 'Ceci n'est pas un container' (This is not a container)." width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;
A way to remember this is René Magritte’s famous painting The treachery of Images in which he cleverly depicted a pipe under which he wrote ‘Ceci n’est pas une pipe’ meaning ‘This is not a pipe’.



&lt;p&gt;To build such a snapshot, you use a &lt;strong&gt;Dockerfile&lt;/strong&gt;, i.e. a file on disk that contains instructions for creating an image. When you issue a &lt;code&gt;docker build&lt;/code&gt; command, Docker uses a base image (e.g. a centos image or a ubuntu image). On top of the base image Docker executes each instruction within the Dockerfile to produce a new Docker Image. The file changes that occur when each instruction is executed are stored as a read-only filesystem, also called a &lt;strong&gt;layer&lt;/strong&gt;. Most images consist of multiple layers (one for each line of instructions from the Dockerfile that was used to create the image). Since all layers are read-only the Docker Image is immutable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffbhemwns56bj5tdawfpi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffbhemwns56bj5tdawfpi.png" alt="Image showing layers stacked on top of each other, forming an image" width="637" height="512"&gt;&lt;/a&gt;&lt;/p&gt;
Source: https://docs.docker.com/terms/images/docker-filesystems-multilayer.png



&lt;p&gt;When a container is run, the Docker engine, in particular its storage engine, takes care of presenting the layers that form an image as a single unified object (somewhat similar to git commits). On top of this unified object, the Docker engine then adds a read-write filesystem which makes it an actual container. Any file changes that occur happen inside this top layer which is the only layer that can be modified when a container is run. This setup makes containers very resource-efficient, as multiple containers can be run using the same image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo95u2s5onxajx9ua527t.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo95u2s5onxajx9ua527t.jpg" alt="Multiple containers are shown as thin read-writable layers which all point to the same image" width="769" height="475"&gt;&lt;/a&gt;&lt;/p&gt;
Source: https://docs.docker.com/storage/storagedriver/



&lt;p&gt;The read-writable layer on top of the image within a container is meant to be thin and is not designed to hold persistent data. If you do need to have persistent data, Docker suggests to use &lt;strong&gt;Docker Volumes&lt;/strong&gt;. Volumes are independent constructs that can be attached to containers. If a container is killed or dies, the volume will still be accessible even if the container is removed. With containers you generally shouldn't care about them dying or being killed, because they are not special and you can easily create new ones. Tools like Kubernetes allow you to automatically spin up new containers should anything happen to the running ones.&lt;/p&gt;

&lt;p&gt;Containers, Images, and Volumes are all managed by the &lt;strong&gt;Docker Engine&lt;/strong&gt; which needs to be installed on top of an operating system. The Docker Engine is a client-server application made up of the Docker daemon, a REST API that specifies interfaces for interacting with the daemon, and a command line interface (CLI). When you issue a Docker command on the command line, the Docker CLI will use the daemon's REST API to communicate with the daemon. The daemon will in turn work with the host operating system to allocate operating system resources (CPU, storage, etc) for containers.&lt;br&gt;
 &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8v4q4e43txdd8t9unya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8v4q4e43txdd8t9unya.png" alt="The Docker Engine is shown to comprise the Docker CLI and the Docker daemon. These all sit on top of the operating system and manage the containers which are also directly on top of the operating system" width="793" height="474"&gt;&lt;/a&gt;&lt;/p&gt;
Source: http://orhandogan.net/docker/



&lt;p&gt;The last thing to mention are Image Registries like &lt;a href="https://hub.docker.com/" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt;, &lt;a href="https://cloud.google.com/container-registry/" rel="noopener noreferrer"&gt;Google Container Registry&lt;/a&gt;, and Azure Container Registry. These fulfill a similar function GitHub fulfills for code: they host Docker images which can be used by yourself and others. Docker Hub has a library full of official images like this &lt;a href="https://hub.docker.com/_/mongo/" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt; image. You can use these official images as base images for your own images. If you would like to look at the &lt;a href="https://github.com/docker-library/mongo/blob/9ab7383589df65a7ad12f143d1db4731214ec518/4.2-rc/Dockerfile" rel="noopener noreferrer"&gt;Dockerfiles&lt;/a&gt; that were used to create the official images, you can find the links to them on the pages of the official images. It's also possible to host your own private registry of images.&lt;/p&gt;

&lt;h4&gt;
  
  
  Learn more
&lt;/h4&gt;

&lt;p&gt;This concludes our overview of Docker Jargon. If you are interested to learn more, check out: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/npentrel/docker-containers-vs-vms-257i"&gt;the differences between VMs and Containers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=wjvyN_r-zkk" rel="noopener noreferrer"&gt;Docker tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/npentrel/SmoothDevOps/raw/master/cheatsheets/01%20Docker%20Cheatsheet.pdf" rel="noopener noreferrer"&gt;Docker cheatsheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/get-started/" rel="noopener noreferrer"&gt;Docker's get started guide&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Docker-Deep-Dive-Nigel-Poulton-ebook/dp/B01LXWQUFF" rel="noopener noreferrer"&gt;Nigel Poulton's Docker Deep Dive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://orhandogan.net/docker/" rel="noopener noreferrer"&gt;orhandogan.net/docker/&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>intro</category>
      <category>containers</category>
      <category>containerization</category>
    </item>
  </channel>
</rss>
