<?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>Forem: Mangirdas Judeikis</title>
    <description>The latest articles on Forem by Mangirdas Judeikis (@mjudeikis).</description>
    <link>https://forem.com/mjudeikis</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%2F697475%2F3e833f48-2e43-40dd-8039-1617cf80b189.jpeg</url>
      <title>Forem: Mangirdas Judeikis</title>
      <link>https://forem.com/mjudeikis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mjudeikis"/>
    <language>en</language>
    <item>
      <title>What is Azure IoT Hub and how do I use it?</title>
      <dc:creator>Mangirdas Judeikis</dc:creator>
      <pubDate>Tue, 09 Nov 2021 08:51:18 +0000</pubDate>
      <link>https://forem.com/mjudeikis/what-is-azure-iot-hub-and-how-do-i-use-it-2fcn</link>
      <guid>https://forem.com/mjudeikis/what-is-azure-iot-hub-and-how-do-i-use-it-2fcn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Synpse is an end-to-end platform to manage your device fleet that can grow to hundreds of thousands of devices, perform OTA software updates, collect metrics, logs, deploy your containerized applications and facilitate tunnel-based SSH access to any of your device. You can find a &lt;a href="https://docs.synpse.net/start-here/quick-start-web-user" rel="noopener noreferrer"&gt;Quick Start here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fp3yvcrvwzqi4dce4wc5a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fp3yvcrvwzqi4dce4wc5a.png" alt="Azure landing page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro into Azure IoT Hub
&lt;/h2&gt;

&lt;p&gt;We often get questions how Synpse is compared or competes with &lt;a href="https://azure.microsoft.com/en-us/overview/iot/" rel="noopener noreferrer"&gt;Azure IoT Hub&lt;/a&gt; service. The short answer is that they operate in slightly different domains. Azure IoT hub focuses on application connectivity of the devices while Synpse targets deployment of the applications that may or may not be using services such as IoT Core.&lt;/p&gt;

&lt;p&gt;The best results are achieved when solutions are used together. For example, when you build an application locally that utilizes AWS IoT Core message broker or device state services and then use Synpse to distribute your application to thousands of devices. &lt;/p&gt;

&lt;h2&gt;
  
  
  Example application
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we will deploy a simple open-source application that collects metrics and send them to AWS IoT Core for further processing. All code for this blog post can be found at:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/synpse-hq/metrics-nats-example-app" rel="noopener noreferrer"&gt;https://github.com/synpse-hq/metrics-nats-example-app&lt;/a&gt; - Sample metrics application&lt;br&gt;
&lt;a href="https://github.com/synpse-hq/azure-iot-hub-example" rel="noopener noreferrer"&gt;https://github.com/synpse-hq/azure-iot-hub-example&lt;/a&gt; - Azure IoT Hub example&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create Azure IoT hub&lt;/li&gt;
&lt;li&gt;Configure rules to forward results into Azure blob storage&lt;/li&gt;
&lt;li&gt;Create Azure "Thing"/IoT device for Synpse&lt;/li&gt;
&lt;li&gt;Demo Synpse application from 3 microservices - Metrics demo, NATs messaging, Azure IoT python forwarder containers&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Technologies used
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://cloud.synpse.net" rel="noopener noreferrer"&gt;Synpse&lt;/a&gt; - manage devices and deploy applications to them&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nats.io/" rel="noopener noreferrer"&gt;NATs&lt;/a&gt; - a lightweight message broker that can run on-prem&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://azure.microsoft.com/en-gb/services/iot-hub/" rel="noopener noreferrer"&gt;Azure IoT Hub&lt;/a&gt; - message broker between all devices and Azure &lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Contrary to &lt;a href="https://synpse.net/blog/clouds/aws-iot-core/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt;, Azure was easy to configure using CLI. All steps here will be done using Azure CLI.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Azure IoT Hub
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create Azure IoT hub:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az iot hub create &lt;span class="nt"&gt;--resource-group&lt;/span&gt; MyResourceGroup &lt;span class="nt"&gt;--name&lt;/span&gt; MyIotHub &lt;span class="nt"&gt;--location&lt;/span&gt; eastus &lt;span class="nt"&gt;--tags&lt;/span&gt; &lt;span class="nv"&gt;synpse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Create certificate based on &lt;a href="https://docs.microsoft.com/en-us/azure/iot-hub/tutorial-x509-self-sign" rel="noopener noreferrer"&gt;Azure documentation&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Upload the certificates for Azure device by creating "device-identity"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Thumbprint 1: SHA1 &lt;span class="nv"&gt;Fingerprint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;56:0E:78:56:74:F1:1B:60:73:AA:7C:8E:12:73:C4:62:01:D5:A3:10 
Thumbprint 2: SHA1 &lt;span class="nv"&gt;Fingerprint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;81:EB:0B:27:BB:3F:BB:D8:91:AF:38:28:BE:83:E5:46:C3:0F:4D:DE

&lt;span class="c"&gt;# remove colons ':' from the fingerprints&lt;/span&gt;

az iot hub device-identity create &lt;span class="nt"&gt;-n&lt;/span&gt; MyIotHub &lt;span class="nt"&gt;-d&lt;/span&gt; synpse &lt;span class="nt"&gt;--am&lt;/span&gt; x509_thumbprint &lt;span class="nt"&gt;--ptp&lt;/span&gt; &lt;span class="s2"&gt;"560E785674F11B6073AA7C8E1273C46201D5A310"&lt;/span&gt; &lt;span class="nt"&gt;--stp&lt;/span&gt; &lt;span class="s2"&gt;"81EB0B27BB3FBBD891AF3828BE83E546C30F4DDE"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this example, we gonna create a message route to the storage account blob.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create storage account:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az storage account create &lt;span class="nt"&gt;-n&lt;/span&gt; MyStorageAccountName &lt;span class="nt"&gt;-g&lt;/span&gt; MyResourceGroup &lt;span class="nt"&gt;-l&lt;/span&gt; eastus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create container/bucket for results:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az storage container create &lt;span class="nt"&gt;--account-name&lt;/span&gt; MyStorageAccountName &lt;span class="nt"&gt;-n&lt;/span&gt; metrics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create IoT hub endpoint for message routing:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;storageConnectionString&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;az storage account show-connection-string &lt;span class="nt"&gt;--name&lt;/span&gt; MyStorageAccountName &lt;span class="nt"&gt;--query&lt;/span&gt; connectionString &lt;span class="nt"&gt;-o&lt;/span&gt; tsv&lt;span class="si"&gt;)&lt;/span&gt;

az iot hub routing-endpoint create &lt;span class="nt"&gt;--resource-group&lt;/span&gt; MyResourceGroup &lt;span class="nt"&gt;--hub-name&lt;/span&gt; MyIotHub &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--endpoint-name&lt;/span&gt; storage &lt;span class="nt"&gt;--endpoint-type&lt;/span&gt; azurestoragecontainer &lt;span class="nt"&gt;--endpoint-resource-group&lt;/span&gt; MyResourceGroup &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--endpoint-subscription-id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;az account show | jq &lt;span class="nt"&gt;-r&lt;/span&gt; .id&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;--connection-string&lt;/span&gt; &lt;span class="nv"&gt;$storageConnectionString&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--container-name&lt;/span&gt; metrics &lt;span class="nt"&gt;--batch-frequency&lt;/span&gt; 60 &lt;span class="nt"&gt;--chunk-size&lt;/span&gt; 10 &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--ff&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;iothub&lt;span class="o"&gt;}&lt;/span&gt;-&lt;span class="o"&gt;{&lt;/span&gt;partition&lt;span class="o"&gt;}&lt;/span&gt;-&lt;span class="o"&gt;{&lt;/span&gt;YYYY&lt;span class="o"&gt;}&lt;/span&gt;-&lt;span class="o"&gt;{&lt;/span&gt;MM&lt;span class="o"&gt;}&lt;/span&gt;-&lt;span class="o"&gt;{&lt;/span&gt;DD&lt;span class="o"&gt;}&lt;/span&gt;-&lt;span class="o"&gt;{&lt;/span&gt;HH&lt;span class="o"&gt;}&lt;/span&gt;-&lt;span class="o"&gt;{&lt;/span&gt;mm&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Use routing in question with our HUB (endpoint name is same as --endpoint-name)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az iot hub route create &lt;span class="nt"&gt;-g&lt;/span&gt; MyResourceGroup &lt;span class="nt"&gt;--hub-name&lt;/span&gt; MyIotHub &lt;span class="nt"&gt;--endpoint-name&lt;/span&gt; storage &lt;span class="nt"&gt;--source-type&lt;/span&gt; DeviceMessages &lt;span class="nt"&gt;--route-name&lt;/span&gt; Route &lt;span class="nt"&gt;--condition&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="nt"&gt;--enabled&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploy an application
&lt;/h3&gt;

&lt;p&gt;Deploy an application. Modify application YAML with your thing endpoint.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create certificate secrets
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;synpse secret create azure-crt &lt;span class="nt"&gt;-f&lt;/span&gt; device1.crt
synpse secret create azure-key &lt;span class="nt"&gt;-f&lt;/span&gt; device1.key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy the application. You will need to modify other values inside YAML file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;synpse deploy &lt;span class="nt"&gt;-f&lt;/span&gt; synpse-azure-example.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;synpse-azure-example.yaml&lt;/code&gt; is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Azure-IoT-Hub&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Azure IoT Hub Synpse example&lt;/span&gt;
&lt;span class="na"&gt;scheduling&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Conditional&lt;/span&gt;
  &lt;span class="na"&gt;selectors&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# device selector&lt;/span&gt;
    &lt;span class="na"&gt;azure&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;iot&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nats&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nats&lt;/span&gt;
      &lt;span class="na"&gt;restartPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;metrics&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;quay.io/synpse/metrics-nats-example-app&lt;/span&gt;
      &lt;span class="na"&gt;restartPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;azure-iot&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;quay.io/synpse/azure-iot-hub-example&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/server/azure.py&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NATS_HOSTNAME&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nats&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HOSTNAME&lt;/span&gt;
          &lt;span class="c1"&gt;# IoT hub DNS name&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mj-hub.azure-devices.net"&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DEVICE_ID&lt;/span&gt;
          &lt;span class="c1"&gt;# device id used when creating a device&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;synpse"&lt;/span&gt;
      &lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;azure-crt&lt;/span&gt;
        &lt;span class="na"&gt;filepath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/server/device1.crt&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;azure-key&lt;/span&gt;
        &lt;span class="na"&gt;filepath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/server/device1.key&lt;/span&gt;
      &lt;span class="na"&gt;restartPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see messages coming into the Azure IoT Hub&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F8xejg3wpoelc9w626t62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F8xejg3wpoelc9w626t62.png" alt="message flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once running, you should see the application running and data coming into Azure storage account blob.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F4fcowa6qkjtm9hu796gp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4fcowa6qkjtm9hu796gp.png" alt="Message flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Things to look for
&lt;/h3&gt;

&lt;p&gt;Certificate configuration path is painful. But this is the common pattern between cloud offering. Azure offers shared private key authentication. This makes multiple device provisioning easier. If you are not interested in cloud portability - this might be easier way to deal with complexities.&lt;/p&gt;

&lt;p&gt;Events land into a storage account without visibility how and the default data structure cannot easily adjust. Sometimes it takes a few minutes, sometimes multiple minutes. We assume this is due to the ETL (Extract, Transform, Load) process, which is not visible to users. &lt;strong&gt;But on the other hand, on GCP it was very visible and VERY expensive. Not sure if both here are possible :)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Overall Azure experience was quite pleasant. API and CLI consistent, documentation is quite well written. &lt;/p&gt;

&lt;h2&gt;
  
  
  go run ./wrap_up.go
&lt;/h2&gt;

&lt;p&gt;This is a simple way to use Azure IoT Hub with Synpse. When it comes to consuming and managing a lot of data, constructing complex applications and integrating seamlessly into your current technological infrastructure - nothing can beat the public cloud. But where the cloud is lacking is - IoT device and application management.&lt;/p&gt;

&lt;p&gt;Public cloud providers are built on assumption that they will manage infrastructure for you. When it comes to devices themselves - they are yours and yours only. And this is where Public cloud providers lack influence and where Synpse comes into the picture.&lt;/p&gt;

&lt;p&gt;If you have any questions or suggestions, feel free to start a new discussion in our &lt;a href="https://github.com/synpse-hq/synpse/discussions" rel="noopener noreferrer"&gt;forum&lt;/a&gt; or drop us a line on &lt;a href="https://discord.gg/dkgN4vVNdm" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://synpse.net/blog" rel="noopener noreferrer"&gt;https://synpse.net/blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>synpse</category>
      <category>iot</category>
      <category>cloud</category>
    </item>
    <item>
      <title>What is AWS IoT Core and how do I use it?</title>
      <dc:creator>Mangirdas Judeikis</dc:creator>
      <pubDate>Tue, 02 Nov 2021 08:11:35 +0000</pubDate>
      <link>https://forem.com/mjudeikis/what-is-aws-iot-core-and-how-do-i-use-it-3ilj</link>
      <guid>https://forem.com/mjudeikis/what-is-aws-iot-core-and-how-do-i-use-it-3ilj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Synpse is an end-to-end platform to manage your device fleet that can grow to hundreds of thousands of devices, perform OTA software updates, collect metrics, logs, deploy your containerized applications and facilitate tunnel-based SSH access to any of your device. You can find a &lt;a href="https://docs.synpse.net/start-here/quick-start-web-user"&gt;Quick Start here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ymqDFjGi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xvhowoi8cj2r4kuxixpv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ymqDFjGi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xvhowoi8cj2r4kuxixpv.png" alt="AWS landing page" width="880" height="683"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro into AWS IoT Core
&lt;/h2&gt;

&lt;p&gt;We often get questions about how Synpse is compared or competes with the &lt;a href="https://aws.amazon.com/iot-core/"&gt;AWS IoT Core&lt;/a&gt; service. The short answer is that they operate in slightly different domains. AWS IoT Core focuses on application connectivity of the devices while Synpse targets deployment of the applications that may or may not be using services such as IoT Core.&lt;/p&gt;

&lt;p&gt;The best results are achieved when solutions are used together. For example, when you build an application locally that utilizes AWS IoT Core message broker or device state services and then use Synpse to distribute your application to thousands of devices. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclaimer: While the AWS landing page says "Easily and securely connect.." we found that it's not true. Setup is quite complicated so buckle up, backaroo! &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Example application
&lt;/h3&gt;

&lt;p&gt;In this tutorial, we will deploy a simple open-source application that collects metrics and send them to AWS IoT Core for further processing. All code for this blog post can be found at:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/synpse-hq/metrics-nats-example-app"&gt;https://github.com/synpse-hq/metrics-nats-example-app&lt;/a&gt; - Sample metrics application&lt;br&gt;
&lt;a href="https://github.com/synpse-hq/aws-iot-core-example"&gt;https://github.com/synpse-hq/aws-iot-core-example&lt;/a&gt; - AWS IoT Core example&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up AWS IoT Core&lt;/li&gt;
&lt;li&gt;Configure rules to forward data into the S3 bucket&lt;/li&gt;
&lt;li&gt;Create AWS device/Thing for Synpse&lt;/li&gt;
&lt;li&gt;Deploy a demo Synpse application from 3 microservices - Metrics collector, NATS broker, example Python app that forwards data to AWS IoT Core&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Technologies used
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://cloud.synpse.net"&gt;Synpse&lt;/a&gt; - manage devices and deploy applications to them&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nats.io/"&gt;NATS&lt;/a&gt; - a lightweight message broker that can run on-prem&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/iot/"&gt;AWS IoT Core&lt;/a&gt; - message broker between all devices and AWS &lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  AWS IoT Core
&lt;/h3&gt;

&lt;p&gt;For this application to work we need to setup AWS IoT Core and its pre-requisites. AWS uses certificate authentication by default for all IoT devices.&lt;/p&gt;
&lt;h4&gt;
  
  
  AWS IoT Core page
&lt;/h4&gt;

&lt;p&gt;Inside AWS IoT Core page navigate to Manage sub-page. Create a "Thing" with AWS generated certificates. Download certificates to your workstation. We will need them later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1olIZXTA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tdxmw6zarotihgx60lu5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1olIZXTA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tdxmw6zarotihgx60lu5.gif" alt="Create a thing" width="880" height="479"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  AWS IoT S3 page
&lt;/h4&gt;

&lt;p&gt;Inside the AWS IoT S3 page, create an S3 bucket for metrics to be stored. We gonna use it later&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h96DsdCv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4m2exa0i0qck8pqftpmf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h96DsdCv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4m2exa0i0qck8pqftpmf.gif" alt="Create S3" width="880" height="479"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Create Act Rule
&lt;/h4&gt;

&lt;p&gt;Go back on the IoT Core page navigate to the ACT subpage. We will create a new Rule for our metrics. Rule creation involved multiple steps, like creating the rule itself, granting access with policy and finalizing the setup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2EdpfPqZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jta1rihp32110fju1tjr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2EdpfPqZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jta1rihp32110fju1tjr.gif" alt="Create rule" width="880" height="479"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Create policy and attach
&lt;/h4&gt;

&lt;p&gt;We will need to create a policy to publish events, and attach it to the certificate we generated&lt;/p&gt;

&lt;p&gt;The policy document is as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect",
        "iot:Receive",
        "iot:Publish",
        "iot:Subscribe"
      ],
      "Resource": "*"
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_auKiNeM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pisfcghz4ru5cko3j6jv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_auKiNeM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pisfcghz4ru5cko3j6jv.gif" alt="Create policy" width="880" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Attach the policy to a certificate, used by "Thing"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UfKDGk5X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s34l6tyvong5jtb3kehi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UfKDGk5X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s34l6tyvong5jtb3kehi.gif" alt="Attach cert" width="880" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Get endpoint
&lt;/h4&gt;

&lt;p&gt;You will need an endpoint for your IoT Core. You can get it via CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws iot describe-endpoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or navigate via UI:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sgBIWSQL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ddz2liii27zo80ai8vxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sgBIWSQL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ddz2liii27zo80ai8vxz.png" alt="Endpoint" width="880" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Deploy an application
&lt;/h4&gt;

&lt;p&gt;We have downloaded certificates in the first step. Let's create Synpse secret with those certificates&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;synpse secret create aws-cert --file zzz-certificate.pem.crt
synpse secret create aws-key --file zzz-private.pem.key
synpse secret create aws-root-ca --file AmazonRootCA1.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy Synpse application. Modify application yaml with your thing endpoint and messaging topic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;synpse deploy -f synpse-aws-example.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;synpse-aws-example.yaml&lt;/code&gt; is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: AWS-IoT-Core
description: AWS IoT Core Synpse example
scheduling:
  type: Conditional
  selectors:
    aws: iot    
spec:
  containers:
  - name: nats
    image: nats
  - name: app
    image: quay.io/synpse/metrics-nats-example-app
  - name: aws-iot
    image: quay.io/synpse/aws-iot-core-example
    forcePull: true
    args:
      - --endpoint 
      - a243pu5i3wf6nw-ats.iot.us-east-1.amazonaws.com
      - --cert 
      - /server/gateway/certificate.pem  
      - --key 
      - /server/gateway/certificate.key
      - --root-ca 
      - /server/gateway/AmazonRootCA1.pem
      - --topic
      - test/topic
    command: /server/aws.py
    secrets:
      - name: aws-cert
        filepath: /server/gateway/certificate.pem
      - name: aws-key
        filepath: /server/gateway/certificate.key
      - name: aws-root-ca
        filepath: /server/gateway/AmazonRootCA1.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once running, you should see the application running and data coming into the AWS S3 account&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ArP7ou8a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2wlly71nuqpudtg1guxr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ArP7ou8a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2wlly71nuqpudtg1guxr.png" alt="Storage blob" width="880" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;At this point, you might thing "This was not as hard as you told us". We did all the steps using AWS Console UI. Github repository contains more detail steps how to achieve same result via CLI. Good luck :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Things to look for
&lt;/h3&gt;

&lt;p&gt;AWS CLI was a disaster 5 years ago and it still is. Either API is consistent or CLI should be advanced enough to abstract inconsistencies. In AWS case API documentation is very poor, and if it is there, it just doesn't work. But if you are comfortable "clicking UI" - you are good. In my personal opinion&lt;br&gt;
AWS still does a good job to keep  their things proprietary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;This is a simple way to use AWS IoT Core with Synpse. When it comes to consuming and managing a lot of data, constructing complex applications and integrating seamlessly into your current infrastructure - nothing can beat public cloud. But where the cloud is lacking - IoT device and application management.&lt;/p&gt;

&lt;p&gt;Public cloud providers are built on assumption that they will manage infrastructure for you. When it comes to devices itself - hardware is owned by you so there's little incentive for them to manage fleets of machines that they can't be properly billing for.&lt;/p&gt;

&lt;p&gt;If you have any questions or suggestions, feel free to start a new discussion in our &lt;a href="https://github.com/synpse-hq/synpse/discussions"&gt;forum&lt;/a&gt; or drop us a line on &lt;a href="https://discord.gg/dkgN4vVNdm"&gt;Discord&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://synpse.net/blog/clouds/aws-iot-core/"&gt;https://synpse.net/blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>iot</category>
      <category>synpse</category>
      <category>aws</category>
    </item>
    <item>
      <title>DIY downtime monitor with NodeRED</title>
      <dc:creator>Mangirdas Judeikis</dc:creator>
      <pubDate>Tue, 26 Oct 2021 11:52:43 +0000</pubDate>
      <link>https://forem.com/mjudeikis/diy-dowtime-monitor-with-nodered-g99</link>
      <guid>https://forem.com/mjudeikis/diy-dowtime-monitor-with-nodered-g99</guid>
      <description>&lt;p&gt;"Black box" monitoring is one of the key concepts, when monitoring any application. We will show how to deploy a free DIY downtime monitoring stack, using NodeRed and Synpse.&lt;/p&gt;

&lt;p&gt;Similar pattern could be used to do almost any home automation. So go crazy! We use this pattern as its easy to modify, and not does much maintenance.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Synpse is an end-to-end platform to manage your device fleet that can grow to hundreds of thousands of devices, perform OTA software updates, collect metrics, logs, deploy your containerized applications and facilitate tunnel-based SSH access to any of your device. You can find a Quick Start here .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Technologies used
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cloud.synpse.net/"&gt;Synpse&lt;/a&gt; for hosting and running applications anywhere&lt;br&gt;
&lt;a href="https://nodered.org/"&gt;NodeRED&lt;/a&gt; for instrumenting our monitoring&lt;/p&gt;
&lt;h2&gt;
  
  
  NodeRED
&lt;/h2&gt;

&lt;p&gt;We will use NodeRED as instrumentation tool to “write code without writing any code” and monitor our web pages availability. If downtime is detected, we will notify administrators via slack or discord message.&lt;/p&gt;

&lt;p&gt;First lets deploy NodeRED into Synpse enable IoT device we own. We use simple RPI4 under the desk at home:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NodeRed&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Low-code programming for event-driven applications&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;container&lt;/span&gt;
&lt;span class="na"&gt;scheduling&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Selector&lt;/span&gt;
  &lt;span class="c1"&gt;# More on selectors https://docs.synpse.net/synpse-core/applications/scheduling&lt;/span&gt;
  &lt;span class="na"&gt;selectors&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;nodered&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nodered&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nodered/node-red:latest-minimal&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1880:1880"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/data/nodered:/data&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/etc/localtime:/etc/localtime&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/root/.ssh:/root/.ssh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access the remote device via Synpse proxy CLI command to configure it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;synpse device proxy &amp;lt;device_name&amp;gt; --port 1880
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the browser page &lt;a href="http://localhost:1880"&gt;http://localhost:1880&lt;/a&gt;. You should be able to see NodeRed running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Downtime flow
&lt;/h2&gt;

&lt;p&gt;We use Discord webhook integration to send a messages and alert our developers once page is down. Discord webhook documentation can be found &lt;a href="https://discord.com/developers/docs/resources/webhook"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XxMZV59c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/utdi3di8qhk8mo6ndecy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XxMZV59c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/utdi3di8qhk8mo6ndecy.png" alt="Discord webhook" width="774" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Flow we created is very simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Every 5 seconds cloud.synpse.net health url&lt;/li&gt;
&lt;li&gt;If response is not 200, go to next phase, else drop&lt;/li&gt;
&lt;li&gt;Rate limit to send only 1 message every 5 min&lt;/li&gt;
&lt;li&gt;Create a Webhook payload&lt;/li&gt;
&lt;li&gt;Send POST request to webhook URL&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Flow itself looks like this (we have left if 200 branch too, in case you want to re-use it for other purposes). Full json flow can be found bellow for you to reuse.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tFgvzmKn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7k6v8n4pyoe081roheh2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tFgvzmKn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7k6v8n4pyoe081roheh2.png" alt="NodeRED flow" width="880" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press “deploy” and you are done :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xAd9HcKU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2uef3gj0bww7ke9qp6w3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xAd9HcKU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2uef3gj0bww7ke9qp6w3.png" alt="Message" width="542" height="78"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is very simple way to monitor your applications or construct any other automation flows. In addition you can deploy same application to different agents across the globe, and you have free Region based downtime monitoring!&lt;/p&gt;

&lt;h2&gt;
  
  
  ./wrap_up.sh
&lt;/h2&gt;

&lt;p&gt;If you have any questions or suggestions, feel free to start a new discussion in our forum or drop us a line on &lt;a href="https://discord.gg/dkgN4vVNdm"&gt;Discord&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://synpse.net/blog/nodered/downtime-monitor-nodered/"&gt;Synpse.net blog&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Full flow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"90902c5d92f08930"&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;"tab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NodeRed on Synpse"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"disabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ef34b5db67c67385"&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;"http request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"z"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"90902c5d92f08930"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"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;"&amp;lt;PAGE_TO_CHECK_NAME&amp;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;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"paytoqs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ignore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;PAGE_TO_CHECK_URL&amp;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;"tls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"persist"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"proxy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"authType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;370&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;260&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"wires"&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="s2"&gt;"2109536ce55f85cf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"1aae7673af94fb6c"&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;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3c39826c5c2c418b"&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;"inject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"z"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"90902c5d92f08930"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"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;"ticker 5s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"props"&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;"p"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"payload"&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;"p"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"topic"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"vt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"str"&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;"repeat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"crontab"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"once"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"onceDelay"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"topic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"payloadType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;260&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"wires"&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="s2"&gt;"ef34b5db67c67385"&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;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2109536ce55f85cf"&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;"switch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"z"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"90902c5d92f08930"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"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;"if not 200"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"property"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"statusCode"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"propertyType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rules"&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;"t"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"neq"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"v"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"200"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"vt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"str"&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;"checkall"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"repair"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"outputs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;580&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"wires"&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="s2"&gt;"758156729b55665f"&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;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1aae7673af94fb6c"&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;"switch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"z"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"90902c5d92f08930"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"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;"if  200"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"property"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"statusCode"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"propertyType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rules"&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;"t"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eq"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"v"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"200"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"vt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"str"&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;"checkall"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"repair"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"outputs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;570&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"wires"&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;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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"758156729b55665f"&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;"delay"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"z"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"90902c5d92f08930"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"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;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"pauseType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"timeoutUnits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"seconds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nbRateUnits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rateUnits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"minute"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"randomFirst"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"randomLast"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"randomUnits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"seconds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"drop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"allowrate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;740&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;260&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"wires"&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="s2"&gt;"a062d51eb49713f9"&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;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2452ffaa52e6333f"&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;"http request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"z"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"90902c5d92f08930"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"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;"discord webhook"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"paytoqs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ignore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;DISCORD_WEBHOOK_URL&amp;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;"tls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"persist"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"proxy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"authType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1110&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;260&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"wires"&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;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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a062d51eb49713f9"&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;"function"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"z"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"90902c5d92f08930"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"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;"payload"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"func"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"var payload = {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;username&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Downtime BOT&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;avatar_url&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;https://i.imgur.com/zEGYUVs.jpeg&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;cloud.synpse.net Downtime detected. Next check in 5 min&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;msg.payload = payload&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;return msg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"outputs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"noerr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"initialize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"finalize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"libs"&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;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;920&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;260&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"wires"&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="s2"&gt;"2452ffaa52e6333f"&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;



</description>
      <category>iot</category>
      <category>devicemanagement</category>
      <category>synpsenodered</category>
    </item>
    <item>
      <title>Access remote networks without a VPN!</title>
      <dc:creator>Mangirdas Judeikis</dc:creator>
      <pubDate>Mon, 20 Sep 2021 07:50:23 +0000</pubDate>
      <link>https://forem.com/mjudeikis/access-remote-networks-without-a-vpn-39h8</link>
      <guid>https://forem.com/mjudeikis/access-remote-networks-without-a-vpn-39h8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Synpse is an end-to-end platform to manage your device fleet that can grow to hundreds of thousands of devices, perform OTA software updates, collect metrics, logs, deploy your containerized applications and facilitate tunnel-based SSH access to any of your device. You can find a &lt;a href="https://docs.synpse.net/start-here/quick-start-web-user" rel="noopener noreferrer"&gt;Quick Start&lt;/a&gt; here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sometimes you get into situations, where you want to configure your home router to expose new ports, or help your close ones to configure some network device in their home network (IP camera, router, smart home system). How many times you wanted to have SSH access into your mini server at home while on holidays?&lt;/p&gt;

&lt;p&gt;I had a similar case. I was traveling, and at some point I needed to reconfigure my home wifi router because ISP updated the firmware, and external IP address changed and I lost all port forwarding rules to my "home hosted devices". So no more free home hosted VPN (I will have separate post about this)&lt;/p&gt;

&lt;p&gt;Luckily, I had synpse device running in my home! I will show a simple and easy way to access your remote networks in cases like this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proxy feature
&lt;/h2&gt;

&lt;p&gt;Synpse allows you to proxy from your laptop to remote device for the local development:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;synpse device proxy &amp;lt;device-name&amp;gt; &amp;lt;local-port&amp;gt;:&amp;lt;remote-port&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is very helpful, when you are doing remote development and need to debug remote devices and application. But there is more to this. Synpse can act as forward proxy to other devices on the remote network (nothing what normal SSH can't do too but just makes it easier).  Diagram bellow show how this could be used at the high level:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ft5zsg3rz9gva39djlmqv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ft5zsg3rz9gva39djlmqv.png" alt="Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To achieve this, just change a command a bit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;synpse device proxy &amp;lt;device-name&amp;gt; &amp;lt;local-port&amp;gt;:&amp;lt;&lt;span class="nb"&gt;hostname&lt;/span&gt;/ip&amp;gt;:&amp;lt;remote-port&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How does this looks like?
&lt;/h2&gt;

&lt;p&gt;In my case, we needed to access WIFI router and reconfigure it.&lt;/p&gt;

&lt;p&gt;SSH into remote device to check network address space it is running in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;synpse device ssh rpi3
root@synpse:/# ip a
...
2: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel state UP group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether b8:27:eb:15:c6:af brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.178/24 brd 192.168.0.255 scope global dynamic eth0
       valid_lft 85386sec preferred_lft 85386sec
    inet6 fd01::ba27:ebff:fe15:c6af/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 286sec preferred_lft 286sec
    inet6 fe80::ba27:ebff:fe15:c6af/64 scope &lt;span class="nb"&gt;link 
       &lt;/span&gt;valid_lft forever preferred_lft forever
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We see that my device is in &lt;code&gt;192.168.0.1/24&lt;/code&gt; network. We know our router is the first IP address in the network. Lets get to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;synpse device proxy rpi3 8443:192.168.0.1:443
forwarding port &lt;span class="o"&gt;(&lt;/span&gt;local-&amp;gt;remote&lt;span class="o"&gt;)&lt;/span&gt; 8443 -&amp;gt; 192.168.0.1:443 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is it. Open &lt;code&gt;https://localhost:8443&lt;/code&gt; and you should see the router page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fhrdiqqvun4u6l0njlx61.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fhrdiqqvun4u6l0njlx61.png" alt="Remote router"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ./wrap_up
&lt;/h2&gt;

&lt;p&gt;In short, Synpse is not only tool to manage deployments for your IoT fleet, but it is a development and debugging tool too!&lt;/p&gt;

&lt;p&gt;If you have any questions or suggestions, feel free to start a new discussion in our &lt;a href="https://github.com/synpse-hq/synpse/discussions" rel="noopener noreferrer"&gt;forum&lt;/a&gt; or drop us a line on &lt;a href="https://discord.gg/dkgN4vVNdm" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Originally published at: &lt;a href="https://synpse.net/blog/synpse/access-remote-networks/" rel="noopener noreferrer"&gt;https://synpse.net&lt;/a&gt;&lt;/p&gt;

</description>
      <category>iot</category>
      <category>synpse</category>
      <category>devicemanagement</category>
    </item>
    <item>
      <title>Welcome to Synpse — an IoT platform for everybody</title>
      <dc:creator>Mangirdas Judeikis</dc:creator>
      <pubDate>Mon, 13 Sep 2021 15:46:22 +0000</pubDate>
      <link>https://forem.com/mjudeikis/welcome-to-synpse-an-iot-platform-for-everybody-167h</link>
      <guid>https://forem.com/mjudeikis/welcome-to-synpse-an-iot-platform-for-everybody-167h</guid>
      <description>&lt;h2&gt;
  
  
  Why IoT?
&lt;/h2&gt;

&lt;p&gt;IoT should not be hard. Sadly we found it to be not the case. As a DYI hackers and hobbyists we are running a lot of random projects on the side. From home automation, 3D printers, heating, temperature sensors, car tracking systems and more. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ks-_GESX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1siinvt09jxw97042tag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ks-_GESX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1siinvt09jxw97042tag.png" alt="Synpse UI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, once upon a time, we received a request to deploy software to a place where we didn't even imagine you can place a computer with a working Linux OS 🤯. &lt;/p&gt;

&lt;p&gt;That led us to a journey where we tried and tested a bunch of different tools for IoT fleet management. In the end we reached a conclusion - running software on the edge is not that easy with the current available technologies. The ones capable of doing so are either too expensive to run, do not scale or require custom OS'es to be installed or all those things. What is more, if you do it yourself it is an incredibly tedious and error prone process. Ansible, Chef, Puppet, Terraform and all the other tools are great, but they are not flexible enough to manage thousands of devices and especially when all of those little computers are just out of reach.&lt;/p&gt;

&lt;p&gt;So, as true Engineers - we created a new tool for the job 😀&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Synpse?
&lt;/h2&gt;

&lt;p&gt;If you are coming from &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt; world, you might be thinking - "I know how to do it - let's use Kubernetes". Not so fast, cowboy 🤠. True edge devices have a bit different requirements. They need to be able to go "offline" and "online" without any need to reach the control plane, "graceful shutdown" almost never exist, your devices just lose electricity. They need to be independent from the network and they need to be able to be deployed in different environments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VQrEY-eE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpw0899h8e9ydalcmet3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VQrEY-eE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpw0899h8e9ydalcmet3.jpeg" alt="Kubernetes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, the main reasons why we didn't choose Kubernetes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We didn't want to run Kubernetes ourselves as we don't need most of the features it offers.&lt;/li&gt;
&lt;li&gt;Agents should be lightweight and are not allowed to consume most of the resources (kubelets can be resource hungry).&lt;/li&gt;
&lt;li&gt;Deployments in IoT fleets usually work more as a daemonsets where it's important to run apps on specific devices and not an X number of replicas on any of the devices (can be achieved on k8s with daemonsets and taints but it's just not the right solution).&lt;/li&gt;
&lt;li&gt;Scale and controlplane resource consumption. With Kubernetes, when you reach &amp;gt;1K, controller nodes will be consuming massive amounts of CPU, RAM and Etcd will be slowing down. We wanted a system that can easily scale to thousands of nodes, running on a single core machine with several gigs of RAM.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why not Docker Compose?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, &lt;a href="https://docs.docker.com/compose/"&gt;Docker Compose&lt;/a&gt; is great for local development or deploying some simple software to a remote server. However, moving docker-compose.yaml files around can become complicated. Also, it wouldn't provide any cluster management functionality.&lt;/p&gt;

&lt;p&gt;We didn't create the tool for sake of building something. We encountered a problem and decided to solve it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Biggest challenges that we had to overcome
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;How to quickly bootstrap thousands of devices.&lt;/li&gt;
&lt;li&gt;How to ensure that the bootstrap process is secure, reproduceable and allows the organization to group devices based on their needs.&lt;/li&gt;
&lt;li&gt;How to access devices when they are located in the unknown network you don't control, even behind firewalls where external IPs are not available or when it's behind CGNAT.&lt;/li&gt;
&lt;li&gt;How to deploy software to devices and update applications easily (updates over the air/OTA)&lt;/li&gt;
&lt;li&gt;Use concepts and tools that most modern software developers are already familiar with and love - SSH, Containers, Docker, TCP tunnels.&lt;/li&gt;
&lt;li&gt;We wanted to use any OS we choose to. Some tools are better on Ubuntu, some on Fedora or Raspberry PI OS. When you deal with embedded devices you need more flexibility as manufacturers are often not very accomodating. &lt;/li&gt;
&lt;li&gt;It should be simple and easy to use (batteries included :)).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of these are new problems. We just had to solve them in a different way. So we did.&lt;/p&gt;

&lt;h3&gt;
  
  
  This is how Synpse was born
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nkuc-5Ns--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0soa5nx9wqwafts7lu3u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nkuc-5Ns--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0soa5nx9wqwafts7lu3u.jpg" alt="It's alive!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bespoke solution for edge device management. Easy to use without history of complexity behind it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Whats next?
&lt;/h2&gt;

&lt;p&gt;We prepared set of blog posts for you to get started:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://synpse.net/blog/how-to-build-image/"&gt;How to create image for your device&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://synpse.net/blog/how-to-install-synpse/"&gt;How to install Synpse&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://synpse.net/blog/how-to-deploy-homeassistant/"&gt;How to deploy Home Automation to Synpse&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Originally posted at &lt;a href="https://synpse.net/welcome-to-synpse"&gt;synpse.net&lt;/a&gt;&lt;/p&gt;

</description>
      <category>iot</category>
      <category>devicemanagement</category>
      <category>synpse</category>
    </item>
  </channel>
</rss>
