<?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: Pavol</title>
    <description>The latest articles on Forem by Pavol (@palo).</description>
    <link>https://forem.com/palo</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%2F1384797%2F222e02ab-0f2e-4b22-9cf9-bcf958519b8f.jpg</url>
      <title>Forem: Pavol</title>
      <link>https://forem.com/palo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/palo"/>
    <language>en</language>
    <item>
      <title>New universal drivers for IoT Platform</title>
      <dc:creator>Pavol</dc:creator>
      <pubDate>Wed, 22 Oct 2025 06:19:26 +0000</pubDate>
      <link>https://forem.com/palo/new-universal-drivers-for-iot-platform-3fbe</link>
      <guid>https://forem.com/palo/new-universal-drivers-for-iot-platform-3fbe</guid>
      <description>&lt;p&gt;In some of the previous blogs, I wrote a lot about the &lt;strong&gt;&lt;a href="https://dev.to/palo/iot-platform-totaljs-41p4"&gt;IoT platform&lt;/a&gt;&lt;/strong&gt; from &lt;strong&gt;&lt;a href="https://www.totaljs.com/" rel="noopener noreferrer"&gt;Total.js&lt;/a&gt;&lt;/strong&gt;. Like what it is, why it can be useful, how to install individual parts to get it working, and how to set it up and start using it. But there is still one part of the platform that has to be created or modified especially for your case. And those are drivers.&lt;/p&gt;

&lt;p&gt;We published some of the custom drivers we used before, but now we have added universal drivers. These drivers are ready to use. We created universal drivers for the electrometer, weather, meteo data, and switch. In this blog, I will introduce them to you. You can use them as they are, create new drivers based on principles used in these drivers, or modify them for your case. Also, I will show you how to add a sensor to one of them, so you will be able to adjust them correctly for your case.&lt;/p&gt;

&lt;p&gt;The difference I want to point out first is that we changed &lt;strong&gt;devEUI&lt;/strong&gt; in the received JSON to &lt;strong&gt;id&lt;/strong&gt;. If you are new here, just take it as best practice. If you used one of the drivers with an older JSON schema, be careful now, the old one was because of a custom implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are universal drivers
&lt;/h2&gt;

&lt;p&gt;Each of these drivers is for a different device. We created them based on specifications so they can fit easily into any device of their own type. If you need to do some modifications, it is very easy with little knowledge about drivers, which you can get in the &lt;strong&gt;&lt;a href="https://docs.totaljs.com/iot/IebeqS1cW61f/" rel="noopener noreferrer"&gt;Total.js documentation&lt;/a&gt;&lt;/strong&gt;, and some basic programming skills.&lt;/p&gt;

&lt;p&gt;Each driver has its own properties that can be processed, and there is a possibility of setting a &lt;strong&gt;Token&lt;/strong&gt;. This token is for security reasons. If you set some value there, each received message has to include the same value in the received headers in the property &lt;strong&gt;x-token&lt;/strong&gt;. This will be validated, and if the received header value is different, the driver will not process any data from that request. If you do not set any value to this token, validation will be skipped, and every request will be processed.&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%2Fclaebjy5ielnbaqjqr4z.gif" 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%2Fclaebjy5ielnbaqjqr4z.gif" alt="Setting a value for Token"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This functionality is the same for every driver.&lt;/p&gt;

&lt;h2&gt;
  
  
  Electrometer
&lt;/h2&gt;

&lt;p&gt;The electrometer driver is for electrometer devices. It can receive and process various data that are sent to &lt;strong&gt;/electrometer/&lt;/strong&gt; endpoint. &lt;/p&gt;

&lt;p&gt;Data structure for this driver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;voltageL1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;236.97&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;voltageL2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;234.47&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;voltageL3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;238.12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;currentL1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;6.08&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;currentL2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.52&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;currentL3&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="nx"&gt;activepowerL1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;activepowerL2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.27&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;activepowerL3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.29&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;reactivepowerL1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;reactivepowerL2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;reactivepowerL3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;powerfactorL1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.84&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;powerfactorL2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.94&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;powerfactorL3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123456789&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, there are a lot of different measured values like voltage for 3 phases, current for 3 phases and more. The only property that is not a measured value but is used for pairing a real device with a device in the platform is the &lt;strong&gt;id&lt;/strong&gt; property.&lt;/p&gt;

&lt;h2&gt;
  
  
  Air quality
&lt;/h2&gt;

&lt;p&gt;Air quality is a driver for indoor air quality monitoring. It can receive and process various data that are sent to &lt;strong&gt;/airquality/&lt;/strong&gt; endpoint.&lt;/p&gt;

&lt;p&gt;Data structure for this driver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;24.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;humidity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;co2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1071&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;tvoc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;122&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;00162a820a010072&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can process received data for temperature, humidity, CO2, and tvoc. Same as before, the only property that is not for measured values but for pairing a real device with a device in the platform is the &lt;strong&gt;id&lt;/strong&gt; property.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meteo
&lt;/h2&gt;

&lt;p&gt;Meteo is a driver for outdoor weather conditions monitoring. It can receive and process various data that are sent to &lt;strong&gt;/meteo/&lt;/strong&gt; endpoint.&lt;/p&gt;

&lt;p&gt;Data structure for this driver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;24.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;humidity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;pressure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1013&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;windspeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;3.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ilumination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;uv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;5.6&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;00162a820a010072&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can process received data for temperature, humidity, pressure, windspeed, ilumination, and uv. Same as before, the only property that is not for measured values but for pairing a real device with a device in the platform is the &lt;strong&gt;id&lt;/strong&gt; property.&lt;/p&gt;

&lt;h2&gt;
  
  
  Switch
&lt;/h2&gt;

&lt;p&gt;Switch is a driver created for any kind of switch device with two possible values: &lt;strong&gt;true&lt;/strong&gt; or &lt;strong&gt;false&lt;/strong&gt;. So it is not for receiving values of the type of number, but a boolean. It can receive and process data that is sent to &lt;strong&gt;/switch/&lt;/strong&gt; endpoint.&lt;/p&gt;

&lt;p&gt;Data structure for this driver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123456789&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can process received data as a value property, and same as before, the only property which is not for measured values but for pairing a real device with a device in the platform is the &lt;strong&gt;id&lt;/strong&gt; property.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use the driver?
&lt;/h2&gt;

&lt;p&gt;Usage of IoT drivers is very easy, you have to only copy code from the driver you want, click on the &lt;strong&gt;Create&lt;/strong&gt; button in the &lt;strong&gt;Drivers&lt;/strong&gt; section, paste the code there, and click save. Then the new driver will appear in the listing, and you can also see it in the process of creating a new device.&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%2Fhj2z48q88zvfq22q26d3.gif" 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%2Fhj2z48q88zvfq22q26d3.gif" alt="Creating a new driver"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to modify the driver?
&lt;/h2&gt;

&lt;p&gt;For this example, we will use the Switch driver. Right now, we have only one property for processing data, which is &lt;strong&gt;value&lt;/strong&gt;. I want to have a switch with two values, so the first will stay the same as it is now, and the second will be &lt;strong&gt;value2&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When we open the source code of the driver, first we have to go to &lt;strong&gt;exports.outputs&lt;/strong&gt;, and add our new output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{0}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;offline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2 hours&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Value 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{0}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;offline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2 hours&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Object with id &lt;strong&gt;value&lt;/strong&gt; is our original output, and &lt;strong&gt;value2&lt;/strong&gt; is the new one. &lt;strong&gt;value2&lt;/strong&gt; will also be a name of a property, from which will driver pair a value from received data.&lt;/p&gt;

&lt;p&gt;Then we have to find &lt;strong&gt;com.jsonschema&lt;/strong&gt; where we need to add also &lt;strong&gt;value2&lt;/strong&gt; for validation purposes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsonschema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*id:String,value:Boolean,value2:Boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toJSONSchema&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, it will be the same data type as the original output, which is &lt;strong&gt;Boolean&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And the last addition we have to do is add this to the &lt;strong&gt;instance.message&lt;/strong&gt; function, where we process received data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;value2&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newmessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code will set the received value from property &lt;strong&gt;value2&lt;/strong&gt; (payload.value2) to our output with id &lt;strong&gt;value2&lt;/strong&gt;, under the condition that the received value is not null.&lt;/p&gt;

&lt;p&gt;The last thing we should do is update our readme, so every user of our application can see that this driver was modified and now it can process more data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;value2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123456789&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I will create a device based on this driver, and we can try it.&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%2Fmylffoxverki94sg4rw5.gif" 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%2Fmylffoxverki94sg4rw5.gif" alt="Sending data to the modified driver"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;So that is all for this blog about IoT platform drivers. We learned about a new universal driver, and now we know how to modify it for new sensors.&lt;/p&gt;

&lt;p&gt;I hope you like this blog, and I will happily share with you more knowledge about &lt;strong&gt;Total.js&lt;/strong&gt; in future blogs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video:
&lt;/h2&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/OSHF9QW5t2s"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

</description>
      <category>iot</category>
      <category>industry40</category>
      <category>totaljs</category>
      <category>sensors</category>
    </item>
    <item>
      <title>IoT Platform Update: New Features and Enhancements</title>
      <dc:creator>Pavol</dc:creator>
      <pubDate>Wed, 08 Oct 2025 07:25:15 +0000</pubDate>
      <link>https://forem.com/palo/iot-platform-update-new-features-and-enhancements-3p8h</link>
      <guid>https://forem.com/palo/iot-platform-update-new-features-and-enhancements-3p8h</guid>
      <description>&lt;p&gt;If you read my blog, you have certainly come across some blogs about &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;IoT platform&lt;/a&gt;&lt;/strong&gt;. It is application ready to use for making easier your IoT managment, processing data and analyzing them. Despite it, we found some features and enhancements, that can &lt;strong&gt;make it even more powerful, and can be useful in various case you may encounter&lt;/strong&gt;. So we got to work and now I want to present you this updates to IoT platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an IoT platform?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;IoT Platform&lt;/a&gt;&lt;/strong&gt; is an application built with &lt;strong&gt;&lt;a href="https://www.totaljs.com/" rel="noopener noreferrer"&gt;Total.js&lt;/a&gt;&lt;/strong&gt; to work with data from &lt;strong&gt;IoT devices&lt;/strong&gt;. It includes apps like &lt;strong&gt;Stream&lt;/strong&gt; for receiving data, &lt;strong&gt;&lt;a href="https://www.totaljs.com/openreports/" rel="noopener noreferrer"&gt;OpenReports&lt;/a&gt;&lt;/strong&gt; for creating reports, &lt;strong&gt;&lt;a href="https://www.totaljs.com/flow/" rel="noopener noreferrer"&gt;Flow&lt;/a&gt;&lt;/strong&gt; for visual automation, and &lt;strong&gt;&lt;a href="https://www.totaljs.com/openplatform/" rel="noopener noreferrer"&gt;OpenPlatform&lt;/a&gt;&lt;/strong&gt; for managing everything in one place. These apps can work together to collect, process, and show data in real time. The platform helps you create your own system for monitoring and reacting to data from sensors or other devices.&lt;/p&gt;

&lt;p&gt;This was just for quick overview, for more information, please go through this blog post about &lt;strong&gt;IoT platform&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reports
&lt;/h2&gt;

&lt;p&gt;Big update was done in Reports section. Now you can create your report right in the IoT platform application without the need to use OpenReports. &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%2F8e8v7edw2je476i09dz6.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%2F8e8v7edw2je476i09dz6.png" alt="IoT platform Reports section"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you click on the Create report button in the Reports section, you will see a form like this. As you can see, there is a place for an SQL query. This is a query right to the database, and you can read any data as you wish. Of course, you need to know SQL to get the result that you want (or use AI to help). &lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Map fields&lt;/strong&gt; input, you can rename columns. As you can see, I used it to translate the columns names to Slovak language. So now, when I open the report, header in the grid will be &lt;strong&gt;Názov&lt;/strong&gt; instead of &lt;strong&gt;name&lt;/strong&gt; and &lt;strong&gt;Hodnota&lt;/strong&gt; instead of &lt;strong&gt;value&lt;/strong&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%2Fncd4bnlbz9c6n4wjpopk.gif" 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%2Fncd4bnlbz9c6n4wjpopk.gif" alt="Report displayed in the application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, there is a new feature, that you can make an API from the report right in the form. You just need to check the checkbox &lt;strong&gt;Publish a value to an API endpoint&lt;/strong&gt;, that you can see in the image and then you can access this data via url address. This url address you can find in the menu for particular report.&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%2Fflswzy2jjww8kio2kz2r.gif" 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%2Fflswzy2jjww8kio2kz2r.gif" alt="Access the API endpoint"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just like this, you can &lt;strong&gt;create an API endpoint&lt;/strong&gt; for every report you need. &lt;/p&gt;

&lt;p&gt;If you would prefer to use reports with OpenReports application, &lt;strong&gt;it is still possible&lt;/strong&gt;. You can find this archived version in the same GitHub repository with functionality as it was before update.&lt;/p&gt;

&lt;h2&gt;
  
  
  Devices
&lt;/h2&gt;

&lt;p&gt;Devices went also through transformation. Listing of all devices is the same, but detail is switched to the box with more compact design which may be more appealing for orientation in the sensor values.&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%2Fbyl8neegsp2q944qo790.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%2Fbyl8neegsp2q944qo790.png" alt="New design of device detail"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the new design there stayed all functionality (e.g. changing of stats, hidding of unused sensors …) and we also added new features.&lt;/p&gt;

&lt;p&gt;For every device now you can add note and custom attributes. Also, &lt;strong&gt;you can publish every device you choose as API endpoint&lt;/strong&gt;. So now you do not need to create custom report for device you want to have access to via API, you just need to check it in the form.&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%2Fglqy19rlcku6bv5aworv.gif" 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%2Fglqy19rlcku6bv5aworv.gif" alt="Publishing device as an API endpoint"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From this endpoint, you will get information about a particular device as &lt;strong&gt;id&lt;/strong&gt;, &lt;strong&gt;driverid&lt;/strong&gt;, &lt;strong&gt;serial number&lt;/strong&gt;, &lt;strong&gt;locality&lt;/strong&gt;, &lt;strong&gt;custom attributes&lt;/strong&gt;, &lt;strong&gt;configuration&lt;/strong&gt;, and data for every sensor. Each sensor has data as &lt;strong&gt;current value&lt;/strong&gt;, &lt;strong&gt;date when value was received&lt;/strong&gt;, &lt;strong&gt;name&lt;/strong&gt;, &lt;strong&gt;id&lt;/strong&gt; and more.&lt;/p&gt;

&lt;p&gt;Also, if you need just data from particular sensor, you can easily get it in here by choosing an option for &lt;strong&gt;API endpoint&lt;/strong&gt; in options menu for that sensor.&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%2F8hbhbov504nuvms8sf4o.gif" 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%2F8hbhbov504nuvms8sf4o.gif" alt="API endpoint for sensor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, you can get their data like &lt;strong&gt;id&lt;/strong&gt;, &lt;strong&gt;name&lt;/strong&gt;, &lt;strong&gt;value&lt;/strong&gt;, &lt;strong&gt;format&lt;/strong&gt;, &lt;strong&gt;locality&lt;/strong&gt;, &lt;strong&gt;serial number&lt;/strong&gt;, &lt;strong&gt;date when value was received&lt;/strong&gt;, &lt;strong&gt;custom attributes&lt;/strong&gt; and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zones
&lt;/h2&gt;

&lt;p&gt;This section may seem the same as it was before, but we also added &lt;strong&gt;note&lt;/strong&gt; field and &lt;strong&gt;custom attributes&lt;/strong&gt; for every zone. Checkbox for &lt;strong&gt;publishing zone to an API endpoint&lt;/strong&gt; is here too and you can easily get information about your zone via API.&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%2Fyulscoayklyt6fagczsk.gif" 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%2Fyulscoayklyt6fagczsk.gif" alt="Publishing zone as an API endpoint"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, it is very easy to do and you can get information about your zone like &lt;strong&gt;id&lt;/strong&gt;, &lt;strong&gt;name&lt;/strong&gt;, &lt;strong&gt;locality&lt;/strong&gt;, &lt;strong&gt;custom attributes&lt;/strong&gt;, &lt;strong&gt;area&lt;/strong&gt; (object with points with latitude and longtidue as boundary points of the zone) and &lt;strong&gt;sensors&lt;/strong&gt;. This sensors includes informations like &lt;strong&gt;deviceid&lt;/strong&gt;, &lt;strong&gt;sensorid&lt;/strong&gt;, &lt;strong&gt;value&lt;/strong&gt;, &lt;strong&gt;type&lt;/strong&gt;, &lt;strong&gt;date when value was received&lt;/strong&gt;, &lt;strong&gt;name&lt;/strong&gt; and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Drivers
&lt;/h2&gt;

&lt;p&gt;In drivers, we changed design for listing of drivers. Functionality is still the same, you can search in drivers, there are still sections but it is still little more appearing for look.&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%2Fyvzimd89bvu92s884339.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%2Fyvzimd89bvu92s884339.png" alt="New drivers design"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Files
&lt;/h2&gt;

&lt;p&gt;You can see, that we added new section with a name &lt;strong&gt;Files&lt;/strong&gt;. There you can see every uploaded file to your IoT Platform (like created images for zones or uploaded files for simulations). You can see here &lt;strong&gt;name&lt;/strong&gt; of the file, &lt;strong&gt;type&lt;/strong&gt;, &lt;strong&gt;size&lt;/strong&gt;, &lt;strong&gt;date of upload&lt;/strong&gt; and you can also &lt;strong&gt;download&lt;/strong&gt; selected file. &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%2Fdgkldrlolr110f5xl5hd.gif" 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%2Fdgkldrlolr110f5xl5hd.gif" alt="New Files section"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;That is all for this blog. I hope you learned something new in this blog and that you will find these features useful in your case. If you want to stay informed about future updates of the &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;IoT Platform&lt;/a&gt;&lt;/strong&gt; you can subscribe to my blogs and I will happily share with you my knowledge not only about IoT Platform but about all &lt;strong&gt;&lt;a href="https://www.totaljs.com/" rel="noopener noreferrer"&gt;Total.js&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video:
&lt;/h2&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/e-RWPTqac1A"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

</description>
      <category>iot</category>
      <category>totaljs</category>
      <category>sensor</category>
      <category>industry40</category>
    </item>
    <item>
      <title>How to create Google Gemini AI component in Total.js Flow</title>
      <dc:creator>Pavol</dc:creator>
      <pubDate>Wed, 03 Sep 2025 07:14:26 +0000</pubDate>
      <link>https://forem.com/palo/how-to-create-google-gemini-ai-component-in-totaljs-flow-493h</link>
      <guid>https://forem.com/palo/how-to-create-google-gemini-ai-component-in-totaljs-flow-493h</guid>
      <description>&lt;p&gt;We live in the times, where everyone wants to use AI everywhere. It can be very useful for many cases and I think, that if you work with &lt;strong&gt;&lt;a href="https://www.totaljs.com/flow/" rel="noopener noreferrer"&gt;Flow application&lt;/a&gt;&lt;/strong&gt; from &lt;strong&gt;&lt;a href="https://www.totaljs.com/" rel="noopener noreferrer"&gt;Total.js&lt;/a&gt;&lt;/strong&gt;, you ask yourself at least once a question “Can I use AI here?”. Let's be honest, I do not know what is your use case, but I know how you can get your &lt;strong&gt;&lt;a href="https://gemini.google.com/app?hl=sk" rel="noopener noreferrer"&gt;Google Gemini AI&lt;/a&gt;&lt;/strong&gt; component to your Flow and now I will show it to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation of Flow application
&lt;/h2&gt;

&lt;p&gt;If you are here, I am sure, that you know how to install Flow, so I am not going to explain it here step by step. But if someone is completely new here, please go to one of my older blog posts about installing the Flow application (This blog was meant for the installation of Flow for the IoT platform, but you can go just through installation and then skip the rest of the blog).&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a new component
&lt;/h2&gt;

&lt;p&gt;Now, we need to click on the green plus button for create a new component.&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%2F0s76i8nau6q10mthajts.gif" 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%2F0s76i8nau6q10mthajts.gif" alt="Create a new component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now as you can see, there is already a predefined structure for Flow components. I will cut it into a few related units, to help you understand it.&lt;/p&gt;

&lt;h2&gt;
  
  
  General information
&lt;/h2&gt;

&lt;p&gt;First of all, we can see here some general information, I will fill them in and then we can go through them step by step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;geminiapi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Gemini API&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;icon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ti ti-google&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pavol Danko&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Services&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;apikey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gemini-1.5-flash&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
 &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}];&lt;/span&gt;
 &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Output&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above you can see that I filled in the &lt;strong&gt;id&lt;/strong&gt; as &lt;strong&gt;geminiapi&lt;/strong&gt;, where this value has to be unique for every component (if you accidentally use &lt;strong&gt;id&lt;/strong&gt; from another component, that component will be replaced).&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;name&lt;/strong&gt; is basically the name of our component and &lt;strong&gt;icon&lt;/strong&gt;, &lt;strong&gt;author&lt;/strong&gt;, and &lt;strong&gt;version&lt;/strong&gt; can tell you by their name what they are for.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;group&lt;/strong&gt; is for sorting components in the left panel in the Flow application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Config&lt;/strong&gt; is very important, data defined in this object we will use later in the settings. Some things we do not want to hard code, but we want to be able to change them in component configuration. Then every component of Google Gemini API used in our Flowstream can have a different configuration with some default values. In our case, we want to be able to set &lt;strong&gt;apikey&lt;/strong&gt; (&lt;strong&gt;it is indispensable&lt;/strong&gt;, for API calls), &lt;strong&gt;model&lt;/strong&gt; because we want to be able to change which model to use and &lt;strong&gt;output&lt;/strong&gt; because we want to be able to choose if we want to have a full response on the output or only text (if it doesn’t make sense to you now, keep reading and in the next section you will understand).&lt;/p&gt;

&lt;h2&gt;
  
  
  Create functionality
&lt;/h2&gt;

&lt;p&gt;As next we can see in predefined form of component &lt;strong&gt;exports.make&lt;/strong&gt; function and &lt;strong&gt;instance.message&lt;/strong&gt; function in it. It is all we need for our component. So this code, which will be explained below is all in the &lt;strong&gt;instance.message&lt;/strong&gt; function.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Follow through the entire blog and at the end you will find a link to the GitHub repository with this component.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We will divide this function into three parts, but it is everything inside of the &lt;strong&gt;instance.message&lt;/strong&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Input data are missing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apikey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You have to configure apikey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error: Wrong input format&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, what you can see here is, that we set our received data into a &lt;strong&gt;data&lt;/strong&gt; variable for better handling.&lt;/p&gt;

&lt;p&gt;Then there are some conditions, basically, it is just to check if we have all the data we need. Of course, we need &lt;strong&gt;input data&lt;/strong&gt;, we need &lt;strong&gt;apikey&lt;/strong&gt; and then there is a condition, that will handle the processing of our input data and just like this, we can receive a &lt;strong&gt;string&lt;/strong&gt; as input data or an &lt;strong&gt;object with text property&lt;/strong&gt;. If some of these conditions are evaluated as true, with &lt;strong&gt;$.send&lt;/strong&gt; function we will send a defined error message to the &lt;strong&gt;error&lt;/strong&gt; output of the component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;messageParts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="nx"&gt;messageParts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;messageParts&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This second part is just to modify input data into a structure, that can be handled by &lt;a href="https://ai.google.dev/gemini-api/docs#rest" rel="noopener noreferrer"&gt;Google Gemini API based on their documentation&lt;/a&gt;. Nothing complicated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;RESTBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://generativelanguage.googleapis.com/v1beta/models/{0}:generateContent?key={1}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apikey&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;candidates&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="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;candidates&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="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;candidates&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="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;textOutput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;candidates&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="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parts&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="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textOutput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This part can look too complicated, but in fact, it is a basic &lt;strong&gt;&lt;a href="https://docs.totaljs.com/total5/IbGpBV2Cx61f/" rel="noopener noreferrer"&gt;RESTBuilder&lt;/a&gt;&lt;/strong&gt; with a &lt;strong&gt;POST&lt;/strong&gt; method. There we have defined a URL address (based on Google Gemini API documentation) with a &lt;a href="https://docs.totaljs.com/total5/IbGpBV1mx61f/#IbGpBV4Lx60f" rel="noopener noreferrer"&gt;format function&lt;/a&gt;, for formatting our URL address with model and apikey. Next is our &lt;strong&gt;obj&lt;/strong&gt; object with structured data for this API.&lt;/p&gt;

&lt;p&gt;Then there is a &lt;strong&gt;header&lt;/strong&gt; with data required from the API. &lt;strong&gt;Timeout&lt;/strong&gt; is here for calls, that will take longer to get a response, so the value is higher than normal.&lt;/p&gt;

&lt;p&gt;And the last is a &lt;strong&gt;callback&lt;/strong&gt;, that will handle responses from Google Gemini API in case of a correct answer or even an error.&lt;/p&gt;

&lt;p&gt;In this &lt;strong&gt;callback&lt;/strong&gt; function, we can see two conditions. The first is for catching &lt;strong&gt;errors&lt;/strong&gt; received from an API call. The second one is here for parse response from API to the form we want (defined in &lt;strong&gt;config&lt;/strong&gt;). If we want to send only text to the output, the response will be as first check, if it includes data we need to parse, and then the response from API will be parsed and sent to the output with the function &lt;strong&gt;$.send&lt;/strong&gt;. If we want to get a fully received response from API to the output, we will go through the &lt;strong&gt;else branch&lt;/strong&gt; of our condition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Settings
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"padding"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"m"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"?.apikey"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"camouflage:1;required:1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;API key&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"help"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://aistudio.google.com/app/apikey"&lt;/span&gt; &lt;span class="na"&gt;target=&lt;/span&gt;&lt;span class="s"&gt;"_blank"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ti ti-external"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;Generate Gemini API key&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"grid-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"m"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"?.model"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"dirsource:gemini-pro|Gemini Pro,gemini-1.5-flash|Gemini 1.5 Flash,gemini-1.5-pro|Gemini 1.5 Pro"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Gemini Model&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"m"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"?.output"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"dirsource:all|Full response,text|Only output text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Output Type&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can remember, we added some config settings to our component. Now we have to create a form for a user, where they can set this configuration. This is basically a frontend code, which you will see when you double click on the component or choose &lt;strong&gt;Configure&lt;/strong&gt; option in the menu.&lt;/p&gt;

&lt;p&gt;We added there inputs for &lt;strong&gt;apikey&lt;/strong&gt;, which is required, and camouflage with help information, where you have a URL address to the Google Gemini web for getting your API key. Then we have here a &lt;strong&gt;model&lt;/strong&gt; with some predefined models from which you can choose (dropdown menu). The last part is &lt;strong&gt;output&lt;/strong&gt;, also as a dropdown menu with options for Full response or Only output text (Functionality for this we coded before in this blog).&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%2Fi5v18od83012r3pns4g1.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%2Fi5v18od83012r3pns4g1.png" alt="Component configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Readme
&lt;/h2&gt;

&lt;p&gt;Readme is just a text, where you can put some information about your component, to help other people (or yourself :) ) to understand what is the purpose of that component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;This component communicates with the Google Gemini API with text inputs and outputs.

Input:

// Object input format for Google Gemini API:
{
    text: String
}

// Or

text: String
For output, you can choose if you need the full response object from Gemini or only the extracted output text.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fh5q0wkqrhdffim136smv.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%2Fh5q0wkqrhdffim136smv.png" alt="Readme window"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Google Gemini AI component in use
&lt;/h2&gt;

&lt;p&gt;Now we can create a simple example for this component. I will use only the &lt;strong&gt;Trigger&lt;/strong&gt; component with the &lt;strong&gt;Print&lt;/strong&gt; component alongside our component.&lt;/p&gt;

&lt;p&gt;In the Trigger component I will send text: “Hello, how are you?” and we will see what we will get on the output.&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%2Finlp9ojtpbj8vlwq7rwa.gif" 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%2Finlp9ojtpbj8vlwq7rwa.gif" alt="A simple example of our component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the example, I used the Flow component with configuration settings, where the model is set to Gemini 1.5 Flash and output is set to Only output text.&lt;/p&gt;

&lt;p&gt;You can find this &lt;a href="https://github.com/PavolSK/tutorials/blob/main/flowcomponents/geminiapi.html" rel="noopener noreferrer"&gt;code on my GitHub&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;In this blog, we created a simple Total.js Flow component for communicating with Google Gemini AI.&lt;/p&gt;

&lt;p&gt;This is all from this blog. I hope, that you learned here something new and that it will help you in your future coding.&lt;/p&gt;

&lt;p&gt;Video part 1&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/prujtFiZQIk"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Video part 2&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/uMB0y_84g-Y"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>gemini</category>
      <category>ai</category>
      <category>low</category>
      <category>flow</category>
    </item>
    <item>
      <title>How to install OpenReports — IoT platform</title>
      <dc:creator>Pavol</dc:creator>
      <pubDate>Wed, 13 Aug 2025 12:48:40 +0000</pubDate>
      <link>https://forem.com/palo/how-to-install-openreports-iot-platform-leg</link>
      <guid>https://forem.com/palo/how-to-install-openreports-iot-platform-leg</guid>
      <description>&lt;p&gt;This is a continuation of a series for the installation of the &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;IoT platform&lt;/a&gt;&lt;/strong&gt;. In the previous blog, we talked about &lt;a href="https://dev.to/palo/how-to-install-stream-to-iot-platform-totaljs-2jg6"&gt;how to install Stream application&lt;/a&gt; and in this blog, we will continue with the installation of the &lt;strong&gt;&lt;a href="https://www.totaljs.com/openreports/" rel="noopener noreferrer"&gt;OpenReports&lt;/a&gt;&lt;/strong&gt; application. In the next blogs, we will install &lt;strong&gt;&lt;a href="https://www.totaljs.com/flow/" rel="noopener noreferrer"&gt;Flow&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://www.totaljs.com/openplatform/" rel="noopener noreferrer"&gt;OpenPlatform&lt;/a&gt;&lt;/strong&gt;, to show you, how you can use all these apps together, to get a great application to &lt;strong&gt;handle and analyze your data from diverse IoT devices&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you haven’t heard about the IoT platform or you want to get more information, please read &lt;a href="https://dev.to/palo/iot-platform-totaljs-ocp"&gt;this blog about the IoT platform&lt;/a&gt; first or watch this &lt;a href="https://www.youtube.com/watch?v=uCMibexXUb4&amp;amp;t=3s" rel="noopener noreferrer"&gt;video describing the IoT platform&lt;/a&gt;. Please, keep in mind, that this platform is part of &lt;a href="https://www.totaljs.com/enterprise/" rel="noopener noreferrer"&gt;Total.js enterprise&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do you need OpenReports?
&lt;/h2&gt;

&lt;p&gt;It is not necessary to use OpenReports with the IoT platform, but it can help you increase your ability to analyze and manage your data. &lt;strong&gt;OpenReports is an independent&lt;/strong&gt; application and you can use it also for other purposes, so if the IoT platform is not for your case, you can still use OpenReports for all different kinds of &lt;strong&gt;data based on your case&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is OpenReports?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.totaljs.com/openreports/" rel="noopener noreferrer"&gt;OpenReports is a powerful reporting tool&lt;/a&gt;&lt;/strong&gt; developed by &lt;strong&gt;&lt;a href="https://www.totaljs.com/" rel="noopener noreferrer"&gt;Total.js&lt;/a&gt;&lt;/strong&gt;. It is designed to simplify the creation and management of reports. It is a flexible application that can integrate with various data sources customizable based on your data architecture. It can generate reports in formats such as &lt;strong&gt;Excel or CSV&lt;/strong&gt; with a user-friendly interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation of OpenReports
&lt;/h2&gt;

&lt;p&gt;We will continue with the assumption, that you followed the previous blogs about IoT platform and stream, but this tutorial does not depend on it. So you can install OpenReports based on this blog and use it for also other cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download source code and install dependencies
&lt;/h2&gt;

&lt;p&gt;First, we have to download the application from a &lt;strong&gt;&lt;a href="https://github.com/totaljs/openreports" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;&lt;/strong&gt; and save it to a directory. We can do it via the terminal with 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;git clone https://github.com/totaljs/openreports.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We installed all dependencies in the previous tutorial, but if you are new here, just follow your terminal console or review previous blog posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update port
&lt;/h2&gt;

&lt;p&gt;We run the IoT platform and stream on ports 8000 and 8001, so we have to go to the index.js file and change the port to another, in this case, we will set it to port 8002.&lt;/p&gt;

&lt;p&gt;This is how our index.js can look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;total5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8002&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;release&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--release&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Service mode:&lt;/span&gt;
&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;servicemode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--servicemode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;Total&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="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can run the application by terminal command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fhwhfwhovb6gujqhj6cx7.gif" 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%2Fhwhfwhovb6gujqhj6cx7.gif" alt="Run OpenReports"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now our application is running on **port 8002 **and we can access it via a web browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect OpenReports to the database
&lt;/h2&gt;

&lt;p&gt;The next step is connecting to our database. When we enter OpenReports it is empty, so we will navigate to &lt;strong&gt;Settings&lt;/strong&gt; and fill in a connecting string to our database (same as for IoT platform and stream applications).&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%2F7xqphw782u7l2agqmal1.gif" 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%2F7xqphw782u7l2agqmal1.gif" alt="Add a connection string"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a view
&lt;/h2&gt;

&lt;p&gt;Then we can continue to create a view of our data. For this, we need to know our database architecture. In this example, I will use only basic data, for example purposes, but you can create views and then reports based on your case.&lt;/p&gt;

&lt;p&gt;We have to go to the section &lt;strong&gt;View&lt;/strong&gt; and click on the button &lt;strong&gt;Create&lt;/strong&gt;. Then we can add there a JSON to specify our view. This JSON should look like this:&lt;br&gt;
&lt;/p&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="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;"hourly"&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;"Hodinové"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sql"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SELECT a.sensor, b.max, a.device, b.ts AS date FROM view_sensor a INNER JOIN tbl_data_hourly b ON a.sensorid = b.sensorid AND a.deviceid = b.deviceid ORDER BY ts DESC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fields"&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;"output"&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;"column"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sensor"&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;"Senzor"&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;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"group"&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="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;"output"&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;"column"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"device"&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;"Zariadenie"&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;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"group"&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="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;"output"&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;"column"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"max"&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;"Max"&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;"number"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"group"&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="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;"output"&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;"column"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"date"&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;"Dátum"&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;"date"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"group"&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="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;&lt;strong&gt;id&lt;/strong&gt; is an identifier for our view, &lt;strong&gt;name&lt;/strong&gt; is name, &lt;strong&gt;SQL&lt;/strong&gt; is SQL query to our database and &lt;strong&gt;fields&lt;/strong&gt; are fields that we want to include with &lt;strong&gt;column&lt;/strong&gt; for data, &lt;strong&gt;name&lt;/strong&gt;, and &lt;strong&gt;data type&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a report
&lt;/h2&gt;

&lt;p&gt;With this, we can continue to create our first report. We have to navigate to the section &lt;strong&gt;Reports&lt;/strong&gt; and click on the button &lt;strong&gt;Create&lt;/strong&gt;. A form will appear, where we can modify our reports to our needs, but in this example, we will create just a simple report. We have to fill in a name for our report and choose a view, so in our case, we will use the name &lt;strong&gt;Test&lt;/strong&gt; and as a view, we will use the previously created view &lt;strong&gt;Hodinové&lt;/strong&gt; (which means &lt;strong&gt;Hourly&lt;/strong&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%2Fdtgccu2iweymbj1vdleg.gif" 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%2Fdtgccu2iweymbj1vdleg.gif" alt="Creating a report"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see on the gif report is usable right after creation. Just like this, you have access to all your data from your database and you can go through them via the OpenReports application, or you can download them as &lt;strong&gt;CSV or Excel&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;That is all to this blog. Now you are able to install the IoT platform, stream, and OpenReports and now you are able to create a view and report. There is a lot more that you can achieve with this application, but this was just a simple explanation of how to install it and start using it.&lt;/p&gt;

&lt;p&gt;I hope you learned something new with this blog and I will happily share with you more knowledge about Total.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video:
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/7VrOiluBO5E"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>iot</category>
      <category>industry40</category>
      <category>totaljs</category>
      <category>openreports</category>
    </item>
    <item>
      <title>IoT platform — Total.js</title>
      <dc:creator>Pavol</dc:creator>
      <pubDate>Wed, 13 Aug 2025 08:19:44 +0000</pubDate>
      <link>https://forem.com/palo/iot-platform-totaljs-41p4</link>
      <guid>https://forem.com/palo/iot-platform-totaljs-41p4</guid>
      <description>&lt;p&gt;This is the last blog from the series about installing the IoT platform, so if you are new here, you can go through the latest blogs to get these applications set as you will see here.&lt;/p&gt;

&lt;p&gt;After installing the &lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;IoT platform&lt;/a&gt;, stream, &lt;a href="https://www.totaljs.com/openreports/" rel="noopener noreferrer"&gt;OpenReports&lt;/a&gt;, &lt;a href="https://www.totaljs.com/flow/" rel="noopener noreferrer"&gt;Flow&lt;/a&gt;, and &lt;a href="https://www.totaljs.com/openplatform/" rel="noopener noreferrer"&gt;OpenPlatform&lt;/a&gt; we can achieve the full potential of what the IoT platform offers. In this blog, we will go through some simple examples to get an overview of what the platform offers.&lt;/p&gt;

&lt;p&gt;The main point of this application is to receive, save, and present real time data or historic data to the user. So the first thing we need is a method to get this data into the &lt;strong&gt;IoT platform&lt;/strong&gt;. For this purpose we installed stream, but we need to process data in the IoT platform and we can do that with drivers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Drivers
&lt;/h2&gt;

&lt;p&gt;Drivers are a core part of this application. They can receive and process data from different kinds of devices. Different devices will need different drivers. So for example, if you want to receive data from a meteo station and electrometer, you will need an individual driver for each. Bud for more meteo stations of one kind you will need just one driver.&lt;/p&gt;

&lt;p&gt;Because there are a lot of options for sensors, you can create custom drivers right in the IoT platform. There you can define which inputs and outputs it has to include, the endpoint, where you will receive data and you can code some operations with the data. It is also possible to create a driver, that will be connected to a camera for example and it can send requests for data at some intervals.&lt;/p&gt;

&lt;p&gt;Driver can also have configuration and settings if you need to set separate configurations for drivers. And in the driver, you can add storage, for saving custom data from the drivers. For example, if you connect your driver to a camera, which can send you data about passing cars, you can save to the current architecture only value, but in the driver, you can create a custom database, that can contain different kinds of data, like vehicle license plate, color, type and etc.&lt;/p&gt;

&lt;p&gt;Detailed information about how to create a driver can be find in the &lt;strong&gt;&lt;a href="https://docs.totaljs.com/iot/IebeqS1cW61f/" rel="noopener noreferrer"&gt;Total.js documentation&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Devices and sensors
&lt;/h2&gt;

&lt;p&gt;When we have our driver ready, we can go to the &lt;strong&gt;Device&lt;/strong&gt; section to create our device. After clicking on the &lt;strong&gt;Create&lt;/strong&gt; button, we have to choose a driver and then we can fill in information about the device. &lt;strong&gt;The serial number is very important&lt;/strong&gt; for every created device because based on it received data will be assigned to the device.&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%2Fz64qza6frv2qnov8kmbr.gif" 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%2Fz64qza6frv2qnov8kmbr.gif" alt="Creating a device"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also fill in here data like reference, color, icon, locality, latitude, and longitude.&lt;/p&gt;

&lt;p&gt;After submitting a new device, we can already see some meta information about the device with information about the chosen driver. Below that, we have listed all sensors associated with the device with their state, current value, and the date and time when the data was received.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sensors
&lt;/h2&gt;

&lt;p&gt;Sensors are created automatically after creating a device, based on a chosen driver. As we know from the previous part of this blog, every driver has their sensors defined in it.&lt;/p&gt;

&lt;p&gt;If we want to see all sensors listed in one place, we can do it in the &lt;strong&gt;Sensor&lt;/strong&gt; section. Here, we can see information about every sensor like locality, value, serial number, alerts, time, when the last value was received, and state. By clicking on a sensor, we will see a report with historic values received on that sensor with possibilities to &lt;strong&gt;filter in these values or export them to a CSV file&lt;/strong&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%2Fea39wxcichcrafa5l2op.gif" 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%2Fea39wxcichcrafa5l2op.gif" alt="Preview of the Sensors section"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Data ingestion in the IoT platform
&lt;/h2&gt;

&lt;p&gt;When we have prepared our device like this, it is ready to receive data. With this driver, data have to be sent to the endpoint &lt;strong&gt;/airq/&lt;/strong&gt;, and the data structure has to look like this:&lt;br&gt;
&lt;/p&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="err"&gt;devEUI:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;temperature:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;24.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;humidity:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;co&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1071&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;tvoc:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;122&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;battery:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.61&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;Where &lt;strong&gt;devEUI&lt;/strong&gt; has to be the same as the &lt;strong&gt;serial number&lt;/strong&gt; defined in the device. If in the received request is any value missing it will go through without error and other values will be processed.&lt;/p&gt;

&lt;p&gt;I will show you an example request in the application RapidAPI, of how the platform process received data. We will use data from above. The URL has to be &lt;strong&gt;&lt;a href="http://0.0.0.0:8001/airq" rel="noopener noreferrer"&gt;http://0.0.0.0:8001/airq&lt;/a&gt;&lt;/strong&gt; because our stream is running on this URL and the endpoint is dedicated to this driver. Do not forget about headers, when we have to have an &lt;strong&gt;x-token&lt;/strong&gt; with value &lt;strong&gt;Total&lt;/strong&gt;, because we set this value for a security token in this driver in the previous blog about IoT stream application.&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%2Fjts4aqynzpbq4zby463k.gif" 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%2Fjts4aqynzpbq4zby463k.gif" alt="Example of receiving data to the device"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, after sending a request, sensors change their state to online and values are displayed in the data grid.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dataviews
&lt;/h2&gt;

&lt;p&gt;If you have a case, where you need to combine data from more sensors, it is easily possible to do so in the &lt;strong&gt;Dataviews&lt;/strong&gt; section of the IoT platform. It is possible to choose sensors, operations, format, and decimals. In the example case, we want to make a &lt;strong&gt;Sum&lt;/strong&gt; operation of two temperatures. For this, we need to click on the &lt;strong&gt;Create&lt;/strong&gt; button, fill in a name, and operation, and select the temperature sensors, that we want to &lt;strong&gt;Sum&lt;/strong&gt;. You can put their different kinds of units, but in our case, we will fill into a formatted input a &lt;strong&gt;°C&lt;/strong&gt;, because we want to render the unit with the resulting value.&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%2F83erd3zieyl8l7nm8ych.gif" 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%2F83erd3zieyl8l7nm8ych.gif" alt="Creating a dataview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Zones and Map
&lt;/h2&gt;

&lt;p&gt;Values obtained with dataviews and sensors can be inserted into zones and then rendered on the map. First, we need to create a zone. The zone is the location on the map, where sensors are located. For creating a zone we need to know where we want to draw a zone. Then we can add sensors, which should be part of it.&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%2Fuzde5herc3g40tuf18jm.gif" 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%2Fuzde5herc3g40tuf18jm.gif" alt="Creating a zone with a sensor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, we can create a category for a zone. Each zone can be part of one category like parking, city building, school, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Map
&lt;/h2&gt;

&lt;p&gt;Every zone can be rendered on a map. In our example, we have only a zone &lt;strong&gt;Test&lt;/strong&gt; with sensor &lt;strong&gt;Temperature&lt;/strong&gt; in it. When we go into a &lt;strong&gt;Map&lt;/strong&gt; section, we can see our zone, after zooming in a box will appear above the zone with the name of a zone and sensor name with the last received value. By clicking on that box a bigger form will appear with listed sensors, their values, and graphs. Each graph has a filter, where we can set what types of values we want to see.&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%2Fqbx15whxqd7w3uj4v1hn.gif" 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%2Fqbx15whxqd7w3uj4v1hn.gif" alt="Map with a zone"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, if you have zones with categories, you can filter which categories you want to see on the map. With this is very easy to keep an eye on zones in your interest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reports
&lt;/h2&gt;

&lt;p&gt;We talked about reports already in the blog where we went through the installation of OpenReports, but here it is a slightly different approach. From reports created in OpenReports, we can get functional APIs with a few clicks. First of all, we have to pair our OpenReports with IoT platform application. We will do that by going to the OpenReports setting, &lt;strong&gt;allowing an API for reading&lt;/strong&gt; reports and copying a link. Then we will put this link in the &lt;strong&gt;IoT platform Settings section&lt;/strong&gt; in the part &lt;strong&gt;OpenReports&lt;/strong&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%2Fn7qum1oi18udvh7cfech.gif" 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%2Fn7qum1oi18udvh7cfech.gif" alt="Connecting OpenReports with IoT platform"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this setup, we can go to the &lt;strong&gt;Reports&lt;/strong&gt; section and create our first API access. Here, we have to click on the &lt;strong&gt;Create&lt;/strong&gt; button and choose one of the existing reports in the OpenReports. In our case, we have here only one with the name &lt;strong&gt;Test&lt;/strong&gt;, which created in the previous blog about the installation of the OpenReports application. When we click on it, we will get a form, where we can fill in some information about this report, we can &lt;strong&gt;make it inactive&lt;/strong&gt; or &lt;strong&gt;add token verification&lt;/strong&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%2F8qcrkq4spoynk31kl69k.gif" 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%2F8qcrkq4spoynk31kl69k.gif" alt="Creating a report"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After submitting a form, our report will appear on our page with information about how many times it was called and we can copy a link for this API here. After copying this URL address to the browser, we will &lt;strong&gt;get the report in the CSV form&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alerts
&lt;/h2&gt;

&lt;p&gt;Alerts are an important part of monitoring the states of devices. Every device can have some problems and with this, we can see them all in one place. These alerts can be invoked in more ways. It could be invoked in the driver, for example, if a camera, should be sending us data after the request is not responding or we can process data in the flow, evaluate them and based on some conditions we can create an alert.&lt;/p&gt;

&lt;p&gt;In this case, I will show you how to create an alert from the Flow application. In the previous blog about the Flow installation, we &lt;strong&gt;connected the received data with the Flow by TMS component&lt;/strong&gt;. Now we will expand our Flow with components &lt;strong&gt;Data sorter&lt;/strong&gt;, &lt;strong&gt;Alert message&lt;/strong&gt;, &lt;strong&gt;IoT Stream / alert&lt;/strong&gt;, and &lt;strong&gt;Print&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the Data sorter, I filled in a condition, that we want to send to the next component only data, where a &lt;strong&gt;sensorid&lt;/strong&gt; is &lt;strong&gt;airq_temperature&lt;/strong&gt; because it is an id for the temperature sensor and the value has to be more than 40 degrees. &lt;strong&gt;Alert message&lt;/strong&gt; component will extend our object with a message &lt;strong&gt;Temperature is higher than {value}&lt;/strong&gt;, where value will be replaced by real value. This is sent to the next component, which is the &lt;strong&gt;IoT Stream / alert&lt;/strong&gt;, which will send this alert to the IoT platform.&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%2Fdcwl4j4q0v1pqlynm05s.gif" 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%2Fdcwl4j4q0v1pqlynm05s.gif" alt="Creating an alert from the Flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Simulations
&lt;/h2&gt;

&lt;p&gt;This section is created only for testing purposes and shouldn't be a part of the production version. Its purpose is to simulate a physical device if we want to test the functionality of our platform without hardware.&lt;/p&gt;

&lt;p&gt;Here, we have to create an endpoint, where we want to send simulation data. Then we have to prepare a CSV file and upload it to the form, select one of the endpoints, and the frequency of sending data to the endpoint. We can also launch a request and choose if we want to circulate data from the simulation file or if it should go only once through this file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Panels
&lt;/h2&gt;

&lt;p&gt;Panels are implemented by creating a small page for information displays. For example, we can imagine a case, that we have meteo values from some school building, we can have a display in the entry room, where everyone can see measured values like temperature, humidity, and more. This page is updated dynamically by received data, so it is very easy to implement by just opening a URL address on that display.&lt;/p&gt;

&lt;p&gt;Now we can move to implementing panels in the IoT platform. First of all, we have to create a panel in the IoT platform. In the form, we will fill in a name, width, and height. After submitting this form, the panel will appear on the page and we can &lt;strong&gt;Copy the Flow URL address&lt;/strong&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%2Fmiidj8xi3dw1z52a1dd4.gif" 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%2Fmiidj8xi3dw1z52a1dd4.gif" alt="Creating a panel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this address, we have to go to the Flow application and create a component by clicking on the &lt;strong&gt;Create&lt;/strong&gt; button and choosing an option &lt;strong&gt;Link endpoint&lt;/strong&gt;. In the form, I will fill in a name, category, and copied URL address.&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%2Fxf6esqd08o8vim7r54we.gif" 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%2Fxf6esqd08o8vim7r54we.gif" alt="Creating a panel in the Flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we have prepared our components and now we need to create a simple flow architecture.&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%2F7b5a8qretzeg9l8yv19d.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%2F7b5a8qretzeg9l8yv19d.png" alt="Flow architecture for a panel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the architecture, we can see new components which are &lt;strong&gt;Tangular&lt;/strong&gt;, &lt;strong&gt;Transformer&lt;/strong&gt;, and &lt;strong&gt;Test panel&lt;/strong&gt;. Tangular is important because we need to put content for a panel page into &lt;strong&gt;HTML&lt;/strong&gt;. In this case, I want to render only one value, which is the temperature on a small page, so our HTML content can look like this (we will get there only values from the temperature sensor from a particular device, based on the condition in the Data sorter component):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: flex; justify-content: center; align-items: center; text-align: center; min-height:100px; font-size: 30px"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ value.value }}°C&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have to change the data structure to the form suitable for the &lt;strong&gt;Test panel component&lt;/strong&gt; and we can do that in the Transformer component with code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when our platform receives data, from a particular device, temperature data will go through this architecture and the value will be rendered to our small page.&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%2Ftwkifwfysb0j7g36znqh.gif" 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%2Ftwkifwfysb0j7g36znqh.gif" alt="Rendering of a received value to the panel page"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;That is all to our IoT platform series of blogs for now, I hope you learned something new from these blogs and I will happily share with you more knowledge about &lt;strong&gt;&lt;a href="https://www.totaljs.com/" rel="noopener noreferrer"&gt;Total.js&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video part 1:
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/G7UX8WuAHjk"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Video part 2:
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/L5J_Z0eOMVg"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>iot</category>
      <category>industry40</category>
      <category>smartcity</category>
      <category>totaljs</category>
    </item>
    <item>
      <title>How to install OpenPlatform — IoT platform</title>
      <dc:creator>Pavol</dc:creator>
      <pubDate>Wed, 06 Aug 2025 07:01:37 +0000</pubDate>
      <link>https://forem.com/palo/how-to-install-openplatform-iot-platform-55pe</link>
      <guid>https://forem.com/palo/how-to-install-openplatform-iot-platform-55pe</guid>
      <description>&lt;p&gt;This is a continuation of a series for the installation of the &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;IoT platform&lt;/a&gt;&lt;/strong&gt;. In the previous blog, we talked about how to install IoT platform application, stream application, &lt;strong&gt;&lt;a href="https://www.totaljs.com/openreports/" rel="noopener noreferrer"&gt;OpenReports application&lt;/a&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;a href="https://www.totaljs.com/flow/" rel="noopener noreferrer"&gt;Flow application&lt;/a&gt;&lt;/strong&gt; and in this blog, we will continue with the installation of &lt;strong&gt;&lt;a href="https://www.totaljs.com/openplatform/" rel="noopener noreferrer"&gt;OpenPlatform application&lt;/a&gt;&lt;/strong&gt;. This is the last part we need to install to make the whole IoT platform and then you can use all these apps together to get a great application to &lt;strong&gt;handle and analyze your data from diverse IoT devices&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you haven’t heard about IoT platform or you want to get more information, please &lt;a href="https://dev.to/palo/revolutionize-your-iot-management-with-totaljs-iot-platform-simplify-monitor-and-optimize-10pe"&gt;read this blog about the IoT platform&lt;/a&gt; first or &lt;a href="https://www.youtube.com/watch?v=uCMibexXUb4&amp;amp;t=3s" rel="noopener noreferrer"&gt;watch this video&lt;/a&gt; describing the IoT platform. Please, keep in mind, that this platform is part of &lt;a href="https://www.totaljs.com/enterprise/" rel="noopener noreferrer"&gt;Total.js enterprise&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do you need OpenPlatform?
&lt;/h2&gt;

&lt;p&gt;As with OpenReports and Flow, it is not necessary to use OpenPlatform in the IoT platform, but it enhances possibilities for various cases. We will integrate here IoT platform application, OpenReports application, and Flow application for easier access to all of them. This will make feeling, that all of these apps are one system and we will be able to create access for our users, manage their permissions, or add new modules to our app.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is OpenPlatform?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.totaljs.com/openplatform/" rel="noopener noreferrer"&gt;OpenPlatform is a portal&lt;/a&gt;&lt;/strong&gt; for running, integrating, and managing multiple 3rd party web applications. It includes user authentication and permissions management for connected applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation of OpenPlatform
&lt;/h2&gt;

&lt;p&gt;We will continue with the assumption, that you followed the previous blogs about IoT platform, stream, OpenReports, and Flow, but this tutorial does not depend on it. So you can install OpenPlatfoem based on this blog and use it also for other cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download source code and install dependencies
&lt;/h2&gt;

&lt;p&gt;First, we have to download an application from a &lt;a href="https://github.com/totaljs/openplatform" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; and save it to a directory. We can do it via the terminal with 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;git clone https://github.com/totaljs/openplatform.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We installed all dependencies in the previous tutorial, but if you are new here, just follow your terminal console or review previous blog posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update port
&lt;/h2&gt;

&lt;p&gt;We run the IoT platform, stream, and Open Reports on ports 8000, 8001, and 8002, so we have to go to the &lt;strong&gt;index.js&lt;/strong&gt; file and change port to another, in this case, we will set it to port &lt;strong&gt;8004&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is how our index.js can look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;total5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8004&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;release&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--release&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Service mode:&lt;/span&gt;
&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;servicemode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--servicemode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;Total&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="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Update the config with a connection string to the database
&lt;/h2&gt;

&lt;p&gt;OpenPlatform needs to create a database, so we have to go to the config file and update their connection string. We will add the same connection string as for our application because OpenPlatform will create a new schema in this database with its own architecture. But if you want to split these two databases and have your own database for every app, you can do it too. The updated config file can look like this:&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%2Fgs1vvczjuvf7b9ufzq0d.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%2Fgs1vvczjuvf7b9ufzq0d.png" alt="Updated config file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can run the application by terminal command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F3jopmy3dx220yrnk0kpe.gif" 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%2F3jopmy3dx220yrnk0kpe.gif" alt="Run OpenPlatform"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now our application is running on &lt;strong&gt;port 8004&lt;/strong&gt; and we can access it via a web browser.&lt;/p&gt;

&lt;p&gt;When we want to log in to the application for the first time, we have to use default credentials, which are:&lt;br&gt;
&lt;/p&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="nl"&gt;"login"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info@totaljs.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin"&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;You can find them in the readme file in the &lt;a href="https://github.com/totaljs/openplatform" rel="noopener noreferrer"&gt;GitHub repository of the OpenPlatform&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%2F40l1mt3qemj8be211565.gif" 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%2F40l1mt3qemj8be211565.gif" alt="First login into the OpenPlatform"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It is highly recommended to change your credentials after the first login.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding an applications
&lt;/h2&gt;

&lt;p&gt;As the first application, we can add an IoT platform. This approach will be the same as for other applications, so we will be more detailed here and the next applications will be only a quicker process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding an IoT platform application to OpenPlatform
&lt;/h2&gt;

&lt;p&gt;When we have already prepared our IoT platform app, we have to go to the &lt;strong&gt;Settings&lt;/strong&gt; section. There is already a part dedicated to OpenPlatform with prepared inputs for &lt;strong&gt;request and response tokens&lt;/strong&gt; and also an &lt;strong&gt;Importing link&lt;/strong&gt; to OpenPlatform. First, we have to copy this link and put it into the OpenPlatform &lt;strong&gt;Apps&lt;/strong&gt; section, where we can find the &lt;strong&gt;Import form&lt;/strong&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%2Fn34qvw8gjzcxkh3kxwjz.gif" 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%2Fn34qvw8gjzcxkh3kxwjz.gif" alt="Importing IoT platform application to OpenPlatform"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After importing an application a form will appear, where you can see some very important information, like &lt;strong&gt;name&lt;/strong&gt;, &lt;strong&gt;request&lt;/strong&gt; and &lt;strong&gt;response&lt;/strong&gt; token, and &lt;strong&gt;permissions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I will change the name to &lt;strong&gt;IoT&lt;/strong&gt;, and then we have to copy the request and response token to the previously mentioned inputs in the IoT platform Settings section and save our Import in the OpenPlatform application.&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%2Fcisz68se0wbd8tcknayp.gif" 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%2Fcisz68se0wbd8tcknayp.gif" alt="Importing IoT platform application to OpenPlatform"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now is IoT platform application imported into OpenPlatform, but we have to give access to users to this application in OpenPlatform. For this, we have to go to the &lt;strong&gt;Groups&lt;/strong&gt; section, there is right now just one group (you can create more and add new users to particular groups) and that is &lt;strong&gt;Admin&lt;/strong&gt;. We will click on this group, check the IoT platform application as an allowed app (as you can see there, you can allow access not only to the full application, but also just for particular plugins as you choose), and save a form. Then after refreshing the OpenPlatform app, the IoT platform will appear there and we can access it through OpenPlatform.&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%2F5xbohd5p67utoglnnh78.gif" 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%2F5xbohd5p67utoglnnh78.gif" alt="Allowing access to IoT platform application for Admin group in OpenPlatform"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding of an OpenReports and Flow applications to OpenPlatform
&lt;/h2&gt;

&lt;p&gt;We can use the same process for importing the OpenReports application and Flow application. Both of them have an &lt;strong&gt;OpenPlatform&lt;/strong&gt; part in the &lt;strong&gt;Settings section&lt;/strong&gt; with an &lt;strong&gt;Importing link&lt;/strong&gt; and inputs for &lt;strong&gt;request and response tokens&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then we have to add permissions to these applications to group &lt;strong&gt;Admins&lt;/strong&gt; in the OpenPlatform and then we can access them through the OpenPlatform application.&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%2Fz2lntpesjxcsutijp6g1.gif" 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%2Fz2lntpesjxcsutijp6g1.gif" alt="Imported applications in OpenPlatform"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only application, that we do not import here is &lt;strong&gt;stream application&lt;/strong&gt; because this is just for receiving data for sensors.&lt;/p&gt;

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

&lt;p&gt;That is all for this blog. Now you are able to install &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;IoT platform&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;stream&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://www.totaljs.com/openreports/" rel="noopener noreferrer"&gt;OpenReports&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://www.totaljs.com/flow/" rel="noopener noreferrer"&gt;Flow&lt;/a&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;a href="https://www.totaljs.com/openplatform/" rel="noopener noreferrer"&gt;OpenPlatform&lt;/a&gt;&lt;/strong&gt; with importing applications. There is a lot more that you can achieve with this application, but this was just a simple explanation of how to install it and start using it.&lt;/p&gt;

&lt;p&gt;I hope you learned something new with this blog and I will happily share with you more knowledge about &lt;strong&gt;Total.js&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/CFH1S2a6RBU"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>iot</category>
      <category>openplatform</category>
      <category>totaljs</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to install Flow — IoT platform</title>
      <dc:creator>Pavol</dc:creator>
      <pubDate>Wed, 30 Jul 2025 06:45:38 +0000</pubDate>
      <link>https://forem.com/palo/how-to-install-flow-iot-platform-59</link>
      <guid>https://forem.com/palo/how-to-install-flow-iot-platform-59</guid>
      <description>&lt;p&gt;This is a continuation of a series for the installation of the &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;IoT platform&lt;/a&gt;&lt;/strong&gt;. In the previous blog, we talked about how to install &lt;strong&gt;IoT platform&lt;/strong&gt; application, &lt;strong&gt;stream&lt;/strong&gt; application, and &lt;strong&gt;&lt;a href="https://www.totaljs.com/openreports/" rel="noopener noreferrer"&gt;OpenReports&lt;/a&gt;&lt;/strong&gt; application and in this blog, we will continue with the installation of the &lt;strong&gt;&lt;a href="https://www.totaljs.com/flow/" rel="noopener noreferrer"&gt;Flow application&lt;/a&gt;&lt;/strong&gt;. In the next blog, we will install &lt;strong&gt;OpenPlatform&lt;/strong&gt;, to show you, how you can use all these apps together to get a great application to &lt;strong&gt;handle and analyze your data from diverse IoT devices&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you haven’t heard about the IoT platform or you want to get more information, please read &lt;a href="https://dev.to/palo/iot-platform-totaljs-ocp"&gt;this blog about the IoT platform&lt;/a&gt; first or watch this &lt;a href="https://www.youtube.com/watch?v=uCMibexXUb4&amp;amp;t=3s" rel="noopener noreferrer"&gt;video describing the IoT platform&lt;/a&gt;. Please, keep in mind, that this platform is part of &lt;a href="https://www.totaljs.com/enterprise/" rel="noopener noreferrer"&gt;Total.js enterprise&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do you need Flow?
&lt;/h2&gt;

&lt;p&gt;As with OpenReports, it is not necessary to use Flow in the IoT platform, but it enhances possibilities for various cases. Flow is an independent application and you can use it also for other purposes, so if the IoT platform is not for your case, you can still use Flow for different kinds of cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Flow?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.totaljs.com/flow/" rel="noopener noreferrer"&gt;Flow is a low code visual programming interface&lt;/a&gt;&lt;/strong&gt; created by &lt;strong&gt;&lt;a href="https://www.totaljs.com/" rel="noopener noreferrer"&gt;Total.js&lt;/a&gt;&lt;/strong&gt; and it is an alternative to Node-red. It is designed to simplify the creation and management of data workflows and automation processes. Flow integrates effortlessly with the &lt;strong&gt;Total.js ecosystem&lt;/strong&gt;, as well as with external APIs and third-party services. Its versatility and seamless integration capabilities make it a valuable tool for automating tasks, streamlining operations, and enhancing productivity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation of OpenReports
&lt;/h2&gt;

&lt;p&gt;We will continue with the assumption, that you followed the previous blogs about IoT platform, stream, and OpenReports, but this tutorial does not depend on it. So you can install Flow based on this blog and use it also for other cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download source code and install dependencies
&lt;/h2&gt;

&lt;p&gt;First, we have to download an application from a &lt;a href="https://github.com/totaljs/flow" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; and save it to a directory. We can do it via the terminal with 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;git clone https://github.com/totaljs/flow.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We installed all dependencies in the previous tutorial, but if you are new here, just follow your terminal console or review previous blog posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update port
&lt;/h2&gt;

&lt;p&gt;We run the IoT platform, stream, and Open Reports on ports 8000, 8001, and 8002, so we have to go to the &lt;strong&gt;index.js&lt;/strong&gt; file and change port to another, in this case, we will set it to port &lt;strong&gt;8003&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is how our index.js can look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;total5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8003&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;release&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--release&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Service mode:&lt;/span&gt;
&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;servicemode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--servicemode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;Total&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="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can run the application by terminal command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Ffxx4i55yvdmkz7gi7u5m.gif" 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%2Ffxx4i55yvdmkz7gi7u5m.gif" alt="Run Flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now our application is running on &lt;strong&gt;port 8003&lt;/strong&gt; and we can access it via a web browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a flow stream
&lt;/h2&gt;

&lt;p&gt;When we access our Flow application we can log in with a predefined name and password (you should change that right after login). We will create a flowstream with the name &lt;strong&gt;Test&lt;/strong&gt; and a form with components to download will appear.&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%2Fy33ogz6bin6em0d20smj.gif" 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%2Fy33ogz6bin6em0d20smj.gif" alt="Accessing a Flow application with creating a flowstream"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a TMS connection
&lt;/h2&gt;

&lt;p&gt;Now we want to create a TMS connection between our IoT platform and Flow. This will give us an opportunity to process real-time data from our IoT platform. For example, we can create alerts based on values from sensors, send emails, create requests, and a lot more. In this example, we will only catch incoming data and print them.&lt;/p&gt;

&lt;p&gt;To do this, we need to add a &lt;strong&gt;TMS component&lt;/strong&gt; to drivers in the IoT platform and set a Token value. We will set value to &lt;strong&gt;123456&lt;/strong&gt; for example purposes.&lt;/p&gt;

&lt;p&gt;Then we need to go to Flow and add there TMS connection by clicking on the green plus button and choosing an option &lt;strong&gt;TMS sources&lt;/strong&gt;. There we will create a new source and fill in a value for &lt;strong&gt;TMS source&lt;/strong&gt; and &lt;strong&gt;Token&lt;/strong&gt;. The token value is as we said before 123456 and the TMS source value is &lt;a href="http://0.0.0.0:8001/$tms/" rel="noopener noreferrer"&gt;http://0.0.0.0:8001/$tms/&lt;/a&gt;. This url is port to our stream application with endpoint &lt;strong&gt;$tms&lt;/strong&gt; for TMS purposes.&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%2F0zu5rsyaotcsyxlvzddw.gif" 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%2F0zu5rsyaotcsyxlvzddw.gif" alt="Creating a TMS source"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see above, after creating a TMS source, new components are automatically added to our Flow. New components are streams for &lt;strong&gt;realtime data&lt;/strong&gt; and &lt;strong&gt;alerts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now we can create a small stream of data from the &lt;strong&gt;realtime&lt;/strong&gt; component, &lt;strong&gt;delay&lt;/strong&gt; component, and &lt;strong&gt;print&lt;/strong&gt; component. &lt;strong&gt;realtime&lt;/strong&gt; component is already downloaded, bud &lt;strong&gt;delay&lt;/strong&gt; and &lt;strong&gt;print&lt;/strong&gt; components we have to download. After that, we can just drag and drop these components into the workspace and connect them as we can see in the picture below.&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%2Flsg4r4h0u6dh6kpqqkk7.gif" 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%2Flsg4r4h0u6dh6kpqqkk7.gif" alt="Flow structure with incoming data"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see above when we can catch incoming data for every sensor without any further configuration. This gives us the possibility to process them in real time and use them for different purposes, like sending them to other applications or triggering some action based on a value or more.&lt;/p&gt;

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

&lt;p&gt;That is all for this blog. Now you are able to install &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;IoT platform&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;stream&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://www.totaljs.com/openreports/" rel="noopener noreferrer"&gt;OpenReports&lt;/a&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;a href="https://www.totaljs.com/flow/" rel="noopener noreferrer"&gt;Flow&lt;/a&gt;&lt;/strong&gt; with some basic architecture. There is a lot more that you can achieve with this application, but this was just a simple explanation of how to install it and start using it.&lt;/p&gt;

&lt;p&gt;I hope you learned something new with this blog and I will happily share with you more knowledge about &lt;strong&gt;Total.js&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Video:&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/9EE0T3SWB7E"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>flow</category>
      <category>iot</category>
      <category>lowcode</category>
      <category>smartcity</category>
    </item>
    <item>
      <title>How to install stream to IoT platform — Total.js</title>
      <dc:creator>Pavol</dc:creator>
      <pubDate>Wed, 16 Jul 2025 07:04:45 +0000</pubDate>
      <link>https://forem.com/palo/how-to-install-stream-to-iot-platform-totaljs-2jg6</link>
      <guid>https://forem.com/palo/how-to-install-stream-to-iot-platform-totaljs-2jg6</guid>
      <description>&lt;p&gt;This is a continuation of a series for the installation of the IoT platform. In the previous blog, we talked about &lt;strong&gt;&lt;a href="https://dev.to/palo/how-to-install-iot-platform-totaljs-240j"&gt;how to install IoT platform application&lt;/a&gt;&lt;/strong&gt; and in this blog, we will continue with the installation of &lt;strong&gt;stream&lt;/strong&gt; application. In the next blogs, we will install &lt;strong&gt;OpenReports&lt;/strong&gt;, &lt;strong&gt;Flow&lt;/strong&gt;, and &lt;strong&gt;OpenPlatform&lt;/strong&gt;, to show you, how you can use all these apps together, to get a great application to &lt;strong&gt;handle and analyze your data from diverse IoT devices&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you haven’t heard about this application or you want to get more information, &lt;a href="https://dev.to/palo/revolutionize-your-iot-management-with-totaljs-iot-platform-simplify-monitor-and-optimize-10pe"&gt;please read this blog about the IoT platform&lt;/a&gt; first or watch this &lt;a href="https://www.youtube.com/watch?v=uCMibexXUb4&amp;amp;t=3s" rel="noopener noreferrer"&gt;video describing the IoT platform&lt;/a&gt;. Please, keep in mind, that this platform is part of &lt;a href="https://www.totaljs.com/enterprise/" rel="noopener noreferrer"&gt;Total.js enterprise&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do you need a stream application?
&lt;/h2&gt;

&lt;p&gt;The stream application is used to capture incoming data. The domain on which the stream will be located will serve as the destination for the data sent from the sensors. Also by visiting the link, we can see a list of all devices along with statistics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation of stream application
&lt;/h2&gt;

&lt;p&gt;We will continue with the assumption that you followed the previous blog because this blog is a direct continuation of it. So if you haven't, please, go as first to this blog and then come back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download source code and install dependencies
&lt;/h2&gt;

&lt;p&gt;In the previous blog, we downloaded the source code also for the stream application and we installed npm packages in our root directory, so now we can skip this part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect database
&lt;/h2&gt;

&lt;p&gt;Stream application works with same the database as the IoT platform. We prepared this database in our previous blog, so now we need just the connection string, to connect stream to this database. To do this, we have to go to the file &lt;strong&gt;config&lt;/strong&gt; in the &lt;strong&gt;stream&lt;/strong&gt; directory and update the database property with the connection string.&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%2Fq5jzer5137fib87yra57.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%2Fq5jzer5137fib87yra57.png" alt="Updated config file with connection string"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Stream installation
&lt;/h2&gt;

&lt;p&gt;First, we have to move to the &lt;strong&gt;stream&lt;/strong&gt; directory in our terminal.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;stream&lt;/strong&gt; directory, we can see file &lt;strong&gt;index.js&lt;/strong&gt;. You can open this file and see there are some options for our application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;total5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="c1"&gt;// options.ip = '127.0.0.1';&lt;/span&gt;
&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8001&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// options.unixsocket = PATH.join(F.tmpdir, 'app_name.socket');&lt;/span&gt;
&lt;span class="c1"&gt;// options.unixsocket777 = true;&lt;/span&gt;
&lt;span class="c1"&gt;// options.config = { name: 'Total.js' };&lt;/span&gt;
&lt;span class="c1"&gt;// options.sleep = 3000;&lt;/span&gt;
&lt;span class="c1"&gt;// options.inspector = 9229;&lt;/span&gt;
&lt;span class="c1"&gt;// options.watch = ['private'];&lt;/span&gt;
&lt;span class="c1"&gt;// options.livereload = 'https://yourhostname';&lt;/span&gt;
&lt;span class="c1"&gt;// options.watcher = true; // enables watcher for the release mode only controlled by the app `F.restart()`&lt;/span&gt;
&lt;span class="c1"&gt;// options.edit = 'wss://www.yourcodeinstance.com/?id=projectname'&lt;/span&gt;
&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;release&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--release&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Service mode:&lt;/span&gt;
&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;servicemode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--servicemode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// options.servicemode = 'definitions,modules,config';&lt;/span&gt;

&lt;span class="c1"&gt;// Cluster:&lt;/span&gt;
&lt;span class="c1"&gt;// options.tz = 'utc';&lt;/span&gt;
&lt;span class="c1"&gt;// options.cluster = 'auto';&lt;/span&gt;
&lt;span class="c1"&gt;// options.limit = 10; // max 10. threads (works only with "auto" scaling)&lt;/span&gt;

&lt;span class="nx"&gt;F&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="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we know from the previous blog, here we can change some options for our application. You can see, that I changed the &lt;strong&gt;port&lt;/strong&gt; because the default port is &lt;strong&gt;8000&lt;/strong&gt; and on this port, we already have an IoT platform running. So I chose to change port to &lt;strong&gt;8001&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now we can run this application from our terminal with the command (do not forget to be in the stream directory):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F1gg7q2iuiafj6qw9ktsb.gif" 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%2F1gg7q2iuiafj6qw9ktsb.gif" alt="Run stream application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we enter our url, when the stream is running, we can see some statistics about the stream. For now, only the database is connected to our stream.&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%2Fwypo0xkhldasmi2y4918.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%2Fwypo0xkhldasmi2y4918.png" alt="Stream statistic"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;This is all for stream installation and now I will show you, why we needed it and how you can use these applications together.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Now, when we prepare our &lt;strong&gt;IoT platform&lt;/strong&gt; and &lt;strong&gt;stream&lt;/strong&gt;, I can show you how it works. You will see how you can get data from some sensors into the platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create driver
&lt;/h2&gt;

&lt;p&gt;The first thing we need to know is what data we can get from a device. Based on this, we will create a &lt;strong&gt;driver&lt;/strong&gt; for this type of device. In our case, we will use the driver from the &lt;strong&gt;drivers&lt;/strong&gt; directory, which we downloaded from GitHub. This driver is used for air quality devices, and in readme, we can see what data it can receive.&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%2F3sbtrlyr3igxi4w2xtkm.gif" 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%2F3sbtrlyr3igxi4w2xtkm.gif" alt="Driver example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in a gif, our driver can process objects with data &lt;strong&gt;temperature&lt;/strong&gt;, &lt;strong&gt;humidity&lt;/strong&gt;, &lt;strong&gt;co2&lt;/strong&gt;, &lt;strong&gt;tvoc&lt;/strong&gt;, &lt;strong&gt;battery&lt;/strong&gt;, and &lt;strong&gt;devEUI&lt;/strong&gt;. devEUI is for the serial number of the device and it has to be different for every device of this type.&lt;/p&gt;

&lt;p&gt;If you want to create a driver for your own special case, you can read more about &lt;a href="https://docs.totaljs.com/iot/IebeqS1cW61f/" rel="noopener noreferrer"&gt;creating a driver here&lt;/a&gt;, or you can use existing drivers as an example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create device
&lt;/h2&gt;

&lt;p&gt;After creating a driver, we can create a device based on this driver. We can do that on the &lt;strong&gt;Devices&lt;/strong&gt; page by clicking on &lt;strong&gt;Create&lt;/strong&gt; and then we can choose the driver for a new device.&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%2F6ekqr4e2g0n4v5xataky.gif" 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%2F6ekqr4e2g0n4v5xataky.gif" alt="Creating a device"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, we can fill in some information about our device. In our example, we will fill only the &lt;strong&gt;Device identifier&lt;/strong&gt;, which is used to pair received data with the existing device. I choose, that our serial number for this example will be &lt;em&gt;test123&lt;/em&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%2Fqh5ol7qe8tktxa8rnof6.gif" 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%2Fqh5ol7qe8tktxa8rnof6.gif" alt="Filling device info"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, all sensors for our device are made automatically after creating the device, because they are defined in our driver.&lt;/p&gt;

&lt;p&gt;Also, when we check url of our stream, we can see, that a new device was registered.&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%2Fuxrv16x3aro5795qmed7.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%2Fuxrv16x3aro5795qmed7.png" alt="Stream updated with a new device"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Security check
&lt;/h2&gt;

&lt;p&gt;To secure received data, the driver can be secured with a token. We will use this functionality in our example. In the driver we used is implemented checking &lt;strong&gt;x-token&lt;/strong&gt; from the header of received data with the token. This token we can set for our driver in our platform, by clicking on settings in the driver menu.&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%2Ffpvwkykqm2emw1gf46j9.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%2Ffpvwkykqm2emw1gf46j9.png" alt="Security token"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a value for a token, I used value &lt;em&gt;Total&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Receiving data
&lt;/h2&gt;

&lt;p&gt;In our example, I will send data to our platform with the RapidAPI app. When we want to create a request to send into our IoT platform, it has to contain a few things:&lt;/p&gt;

&lt;h2&gt;
  
  
  Url address
&lt;/h2&gt;

&lt;p&gt;The url address is url of our stream application plus the endpoint for the driver of that device. So in our example, url address is &lt;a href="http://0.0.0.0:8001/airq" rel="noopener noreferrer"&gt;http://0.0.0.0:8001/airq&lt;/a&gt; with the method &lt;strong&gt;POST&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Headers
&lt;/h2&gt;

&lt;p&gt;As I wrote before, to secure our data, we have to add a token for checking, if data are coming from our device. In our case, we will use a header with the name &lt;strong&gt;x-token&lt;/strong&gt; and with the value &lt;em&gt;Total&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data
&lt;/h2&gt;

&lt;p&gt;And the last part of our request is data. Data are in JSON format like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;devEUI&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;humidity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;co2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1032&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;tvoc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;3.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;battery&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;3.61&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we send this request, our sensors will go from &lt;strong&gt;offline&lt;/strong&gt; state to &lt;strong&gt;online&lt;/strong&gt; state and we can see actual values received in our IoT platform.&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%2Fxo9tlro10st2k4v7704f.gif" 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%2Fxo9tlro10st2k4v7704f.gif" alt="Example of receiving data"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is all to this blog. Now you are able to install an IoT platform and stream, you can create a driver, and a device and receive data from your IoT device. There is a lot more that you can achieve with this platform and I will show you some basics in upcoming blogs.&lt;/p&gt;

&lt;p&gt;I hope you learned something new with this blog and I will happily share with you more knowledge about Total.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video:
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/ZQmW0pq0eao"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>iot</category>
      <category>smartcity</category>
      <category>totaljs</category>
      <category>sensor</category>
    </item>
    <item>
      <title>How to install IoT platform — Total.js</title>
      <dc:creator>Pavol</dc:creator>
      <pubDate>Fri, 11 Jul 2025 07:38:59 +0000</pubDate>
      <link>https://forem.com/palo/how-to-install-iot-platform-totaljs-240j</link>
      <guid>https://forem.com/palo/how-to-install-iot-platform-totaljs-240j</guid>
      <description>&lt;p&gt;We got some questions about how to install this platform, so I decided to write you a blog about it, with step by step guidance. I will divide this blog into more parts. In this first, we will talk about installing the &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot" rel="noopener noreferrer"&gt;IoT platform&lt;/a&gt;&lt;/strong&gt;, in the next one we will install &lt;strong&gt;stream&lt;/strong&gt;, then &lt;strong&gt;&lt;a href="https://www.totaljs.com/openreports/" rel="noopener noreferrer"&gt;OpenReports&lt;/a&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;a href="https://www.totaljs.com/flow/" rel="noopener noreferrer"&gt;Flow&lt;/a&gt;&lt;/strong&gt;, and the last part will be installing &lt;strong&gt;&lt;a href="https://www.totaljs.com/openplatform/" rel="noopener noreferrer"&gt;OpenPlatform&lt;/a&gt;&lt;/strong&gt; and connecting it all in one.&lt;/p&gt;

&lt;p&gt;Now maybe you are asking what it even is an IoT platform. If you haven't heard about this application or you want to get more information, please &lt;a href="https://dev.to/palo/iot-platform-totaljs-ocp"&gt;read this blog about the IoT platform first&lt;/a&gt; or watch this &lt;a href="https://www.youtube.com/watch?v=uCMibexXUb4&amp;amp;t=3s" rel="noopener noreferrer"&gt;video describing the IoT platform&lt;/a&gt;. Please, keep in mind, that this platform is part of &lt;a href="https://www.totaljs.com/enterprise/" rel="noopener noreferrer"&gt;Total.js enterprise&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our recommendation of versions for use are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;PostgreSQL v15 +&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node.js v18+&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Total v5&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I start from the assumption, that you already have installed your PostgreSQL database and &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;. There are already many tutorials to do this, so we will focus only on installing the IoT platform and connecting it with the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  IoT platform
&lt;/h2&gt;

&lt;p&gt;We will divide this part into smaller parts for easier orientation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download
&lt;/h2&gt;

&lt;p&gt;First, we have to download our code from GitHub (I will not share a link here, because you have to be part of Total.js Enterprise to have access there) and save it into your folder.&lt;/p&gt;

&lt;p&gt;I want to work in the folder IoT, so I opened a terminal in this folder and I used the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &amp;lt;&lt;span class="k"&gt;***&lt;/span&gt;github &lt;span class="nb"&gt;link&lt;/span&gt;&lt;span class="k"&gt;***&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install dependencies
&lt;/h2&gt;

&lt;p&gt;In this case, both applications (IoT platform and stream) need to install npm packages &lt;strong&gt;total5&lt;/strong&gt; and &lt;strong&gt;querybuilderpg&lt;/strong&gt;. You can do that in their separate folders with the command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;But when we need it for both applications, we will install it in the root application with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;total5 querybuilderpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when we prepared our &lt;strong&gt;npm packages&lt;/strong&gt;, our directories can be organized like this:&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%2Fgcyll35veff7akl13qre.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%2Fgcyll35veff7akl13qre.png" alt="Directories organization"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create database
&lt;/h2&gt;

&lt;p&gt;Before installing the IoT platform, we have to prepare our database. In the &lt;strong&gt;admin&lt;/strong&gt; folder, we can find the file &lt;strong&gt;database.sql&lt;/strong&gt;. This is the script, which will create all our table structures for application. So we have to run this code in the database.&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%2Fiquawzo0ktvhmw4rbh5f.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%2Fiquawzo0ktvhmw4rbh5f.png" alt="Prepared database"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After running this script, we can see that everything is done and our database is prepared.&lt;/p&gt;

&lt;p&gt;To connect the IoT platform with this database, we have to open the file &lt;strong&gt;config&lt;/strong&gt; in the &lt;strong&gt;admin&lt;/strong&gt; directory and update the database with the connection string.&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%2Fvcc60ba0o7wxhkgfo2ev.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%2Fvcc60ba0o7wxhkgfo2ev.png" alt="Updated config file with connection string"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  IoT platform installation
&lt;/h2&gt;

&lt;p&gt;First, we have to move to the &lt;strong&gt;admin&lt;/strong&gt; directory in our terminal.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;admin&lt;/strong&gt; directory, we can see the file &lt;strong&gt;index.js&lt;/strong&gt;. You can open this file and see there are some options for our application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;total5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="c1"&gt;// options.ip = '127.0.0.1';&lt;/span&gt;
&lt;span class="c1"&gt;// options.port = parseInt(process.argv[2]);&lt;/span&gt;
&lt;span class="c1"&gt;// options.unixsocket = PATH.join(F.tmpdir, 'app_name.socket');&lt;/span&gt;
&lt;span class="c1"&gt;// options.unixsocket777 = true;&lt;/span&gt;
&lt;span class="c1"&gt;// options.config = { name: 'Total.js' };&lt;/span&gt;
&lt;span class="c1"&gt;// options.sleep = 3000;&lt;/span&gt;
&lt;span class="c1"&gt;// options.inspector = 9229;&lt;/span&gt;
&lt;span class="c1"&gt;// options.watch = ['private'];&lt;/span&gt;
&lt;span class="c1"&gt;// options.livereload = 'https://yourhostname';&lt;/span&gt;
&lt;span class="c1"&gt;// options.watcher = true; // enables watcher for the release mode only controlled by the app `F.restart()`&lt;/span&gt;
&lt;span class="c1"&gt;// options.edit = 'wss://www.yourcodeinstance.com/?id=projectname'&lt;/span&gt;
&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;release&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--release&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Service mode:&lt;/span&gt;
&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;servicemode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--servicemode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// options.servicemode = 'definitions,modules,config';&lt;/span&gt;

&lt;span class="c1"&gt;// Cluster:&lt;/span&gt;
&lt;span class="c1"&gt;// options.tz = 'utc';&lt;/span&gt;
&lt;span class="c1"&gt;// options.cluster = 'auto';&lt;/span&gt;
&lt;span class="c1"&gt;// options.limit = 10; // max 10. threads (works only with "auto" scaling)&lt;/span&gt;

&lt;span class="nx"&gt;F&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="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, the default port to start an application is &lt;strong&gt;8000&lt;/strong&gt;, so if you want to change it, you can do it here. I will continue with the unchanged file because I want to start my application like this.&lt;/p&gt;

&lt;p&gt;Now we can run this application from our terminal with the command (do not forget to be in the admin directory):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F3am4ygso9wxh740tfmwf.gif" 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%2F3am4ygso9wxh740tfmwf.gif" alt="Run IoT platform"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Login to the IoT platform
&lt;/h2&gt;

&lt;p&gt;We can now open url from our terminal in a browser.&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%2F4xrhdb9a83pdbhzsu20z.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%2F4xrhdb9a83pdbhzsu20z.png" alt="First start of application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, we got an &lt;strong&gt;Unauthorized 401&lt;/strong&gt; error. To log in we have to add endpoint &lt;strong&gt;/admin&lt;/strong&gt; to our url, so the full url will be in our case &lt;strong&gt;&lt;a href="http://0.0.0.0:8000/admin" rel="noopener noreferrer"&gt;http://0.0.0.0:8000/admin&lt;/a&gt;&lt;/strong&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%2Fmbhs2s8zxmw3szyzbd2f.gif" 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%2Fmbhs2s8zxmw3szyzbd2f.gif" alt="First login to the IoT platform"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After entering this endpoint, we are redirected to the login form. Here we can fill sign-in form with default credentials and enter the application. After entering the application you can change credentials to your preferences by clicking on the account icon and choosing the &lt;strong&gt;Change credentials&lt;/strong&gt; option from the menu.&lt;/p&gt;

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

&lt;p&gt;This was the first part of the IoT platform installation. We got an IoT application installed and you can now use everything in it. But to get your data to this application, you have to also install the &lt;strong&gt;stream&lt;/strong&gt; application. Because that is the application, that will catch requests and save new data in to database.&lt;/p&gt;

&lt;p&gt;In the next blog, we will continue with &lt;strong&gt;stream&lt;/strong&gt; installation and I will show you how you can send data to your stream and get them to your IoT platform for further processing and analysis.&lt;/p&gt;

&lt;p&gt;I hope you learned something new with this blog and I will happily share with you more knowledge about Total.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video:
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/ahq-mC01OFM"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>iot</category>
      <category>smartcity</category>
      <category>javascript</category>
      <category>totaljs</category>
    </item>
    <item>
      <title>Revolutionize Your IoT Management with Total.js IoT Platform: Simplify, Monitor, and Optimize</title>
      <dc:creator>Pavol</dc:creator>
      <pubDate>Thu, 03 Jul 2025 17:47:06 +0000</pubDate>
      <link>https://forem.com/palo/revolutionize-your-iot-management-with-totaljs-iot-platform-simplify-monitor-and-optimize-10pe</link>
      <guid>https://forem.com/palo/revolutionize-your-iot-management-with-totaljs-iot-platform-simplify-monitor-and-optimize-10pe</guid>
      <description>&lt;p&gt;With over 20 billion IoT devices in use today and &lt;a href="https://www.demandsage.com/number-of-iot-devices/" rel="noopener noreferrer"&gt;projections of 40 billion by 2030&lt;/a&gt;, managing this rapidly growing ecosystem is more crucial than ever.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overcoming Challenges in IoT Integration
&lt;/h2&gt;

&lt;p&gt;If you use IoT devices for &lt;strong&gt;monitoring environmental conditions&lt;/strong&gt;, &lt;strong&gt;managing smart city infrastructures&lt;/strong&gt;, &lt;strong&gt;optimizing industrial operations&lt;/strong&gt;, or you use IoT devices at all, it can be hard to keep track of every device. &lt;strong&gt;Managing&lt;/strong&gt; and &lt;strong&gt;visualizing&lt;/strong&gt; data from various IoT devices (like weather stations or electricity meters) can be challenging, especially with different manufacturers.&lt;/p&gt;

&lt;p&gt;Devices often use different protocols and formats, complicating their integration into one system. On top of that, setting up &lt;strong&gt;alerts&lt;/strong&gt;, &lt;strong&gt;reports&lt;/strong&gt;, &lt;strong&gt;APIs&lt;/strong&gt;, or &lt;strong&gt;simple dashboards&lt;/strong&gt; frequently demands considerable time and technical expertise.&lt;/p&gt;

&lt;p&gt;Without a centralized way to manage these devices, your IoT ecosystem can quickly become fragmented, inefficient, and hard to scale. This creates not only technical headaches but also missed opportunities to fully utilize your data and make smarter decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a Unified IoT Solution Matters
&lt;/h2&gt;

&lt;p&gt;Managing IoT devices without a centralized platform can quickly become overwhelming. Different devices often require &lt;strong&gt;separate applications&lt;/strong&gt;. This fragmented approach not only consumes time but also increases the risk of errors and inefficiencies.&lt;/p&gt;

&lt;p&gt;With a unified IoT solution, you gain the ability to streamline processes, integrate diverse devices seamlessly, and &lt;strong&gt;centralize all your data in one place&lt;/strong&gt;. A single platform allows you to keep track of your data, analyze them, and even automate responses in one application.&lt;/p&gt;

&lt;p&gt;Imagine the ability to set up &lt;strong&gt;real-time alerts&lt;/strong&gt;, &lt;strong&gt;generate detailed reports&lt;/strong&gt; and &lt;strong&gt;APIs&lt;/strong&gt;, &lt;strong&gt;create simple dashboards&lt;/strong&gt;, and &lt;strong&gt;access historical data&lt;/strong&gt; effortlessly, all from one interface. Beyond saving time, a unified solution enables you to &lt;strong&gt;focus on insights and decision-making&lt;/strong&gt; rather than troubleshooting and technical challenges.&lt;/p&gt;

&lt;p&gt;In an increasingly connected world, having a system that simplifies and enhances IoT management is no longer optional — it’s essential for staying ahead.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Total.js IoT Platform: Your All-in-One Solution
&lt;/h2&gt;

&lt;p&gt;Simplify IoT management with the Total.js IoT Platform — a powerful solution to streamline workflows and boost efficiency. By integrating modules like &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;IoT platform&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;Stream&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://www.totaljs.com/flow/" rel="noopener noreferrer"&gt;Flow&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://www.totaljs.com/openreports/" rel="noopener noreferrer"&gt;OpenReports&lt;/a&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;a href="https://www.totaljs.com/openplatform/" rel="noopener noreferrer"&gt;OpenPlatform&lt;/a&gt;&lt;/strong&gt;, you gain great control over your IoT ecosystem.&lt;/p&gt;

&lt;p&gt;With powerful features and a variety of integration options, this platform makes the &lt;strong&gt;Internet of Things (IoT) accessible&lt;/strong&gt;, &lt;strong&gt;efficient&lt;/strong&gt;, &lt;strong&gt;and tailored to your needs&lt;/strong&gt;. With the &lt;strong&gt;Total.js IoT Platform&lt;/strong&gt;, you can seamlessly connect, monitor, and manage diverse devices and sensors, no matter their type or manufacturer. The platform simplifies data processing, and visualization, allowing you to focus on insights rather than infrastructure, and on top of that it allows you to &lt;strong&gt;create custom reports&lt;/strong&gt;, &lt;strong&gt;APIs&lt;/strong&gt;, and &lt;strong&gt;dashboards&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Benefits of the Total.js IoT Platform:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Customizable drivers&lt;/strong&gt; — drivers process incoming data. You can &lt;a href="https://docs.totaljs.com/iot/IebeqS1cW61f/" rel="noopener noreferrer"&gt;customize drivers&lt;/a&gt; to handle data precisely according to your requirements. For example, you can create a driver, that can connect and receive data from any source (MQTT, Modbus, etc.), camera (&lt;a href="https://www.dahua.sk/" rel="noopener noreferrer"&gt;Dahua&lt;/a&gt;, &lt;a href="https://www.verkada.com/" rel="noopener noreferrer"&gt;Verkada&lt;/a&gt;, etc.), or you can create a driver with an endpoint, where you will receive data as REST API calls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple Device Management&lt;/strong&gt; —all of your IoT devices in one place with basic meta information, like a serial number, a reference, or a locality.&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%2Fuzfibrgfk1nsyygows8d.gif" 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%2Fuzfibrgfk1nsyygows8d.gif" alt="Device management"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-Time data&lt;/strong&gt; — real-time data is crucial for effective monitoring. Live updates from your devices allow you to gain immediate insights and faster decision making.&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%2Fqfu33lz6yri36h7axha4.gif" 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%2Fqfu33lz6yri36h7axha4.gif" alt="Real-time data from sensors"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom Alerts&lt;/strong&gt; — react instantly to events like temperature spikes or increased pollution levels.&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%2Fwrvvys5ulvjx1kkbbxcl.gif" 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%2Fwrvvys5ulvjx1kkbbxcl.gif" alt="Custom alerts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Map Visualization&lt;/strong&gt; — track your devices on an interactive map with real-time values.&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%2F3ur87opzg2xi2bai7uhm.gif" 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%2F3ur87opzg2xi2bai7uhm.gif" alt="Map visualization"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complex Reporting System&lt;/strong&gt; — Create custom reports to analyze trends, value evolutions, or key metrics based on your use case.&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%2Fj76nryyspxarq169kun9.gif" 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%2Fj76nryyspxarq169kun9.gif" alt="Custom reports"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple API Creation&lt;/strong&gt; — Quickly build APIs from your reports to connect your IoT ecosystem with other systems.&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%2Fai3714n6u9z15p3iq265.gif" 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%2Fai3714n6u9z15p3iq265.gif" alt="Custom APIs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dynamic Dashboards&lt;/strong&gt; — Custom simple dashboards to keep an eye on your important metrics in real-time for tailored monitoring experiences.&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%2Frq0v6hkf8blqpw0wmynd.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%2Frq0v6hkf8blqpw0wmynd.png" alt="Custom dynamic dashboards"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By choosing the &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;Total.js IoT Platform&lt;/a&gt;&lt;/strong&gt;, you gain a powerful, scalable, and user-friendly tool to transform your IoT operations. It’s not just a solution — &lt;strong&gt;it’s a game-changer&lt;/strong&gt; for businesses looking to harness the full potential of IoT technology.&lt;/p&gt;

&lt;p&gt;Visit &lt;strong&gt;&lt;a href="https://www.totaljs.com/" rel="noopener noreferrer"&gt;Total.js&lt;/a&gt;&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;IoT platform page&lt;/a&gt;&lt;/strong&gt; to explore its full potential and see how it can transform your operations. &lt;strong&gt;&lt;a href="https://www.totaljs.com/iot/" rel="noopener noreferrer"&gt;Don’t wait — explore the possibilities today&lt;/a&gt;&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Video:
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/gcExgjiA-NU"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>iot</category>
      <category>smartcity</category>
      <category>totaljs</category>
      <category>sensors</category>
    </item>
    <item>
      <title>j-Box - Total.js</title>
      <dc:creator>Pavol</dc:creator>
      <pubDate>Tue, 08 Apr 2025 09:33:40 +0000</pubDate>
      <link>https://forem.com/palo/j-box-totaljs-2bah</link>
      <guid>https://forem.com/palo/j-box-totaljs-2bah</guid>
      <description>&lt;p&gt;j-Box is part of the &lt;a href="https://www.totaljs.com/" rel="noopener noreferrer"&gt;jComponent UI library from Total.js&lt;/a&gt;. You can find more information about j-Box on&lt;a href="https://componentator.com/components/j-box/" rel="noopener noreferrer"&gt; componentator.com&lt;/a&gt; or &lt;a href="https://github.com/totaljs/components/tree/master/j-Box" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;j-Box is a great flexible UI component&lt;/strong&gt;, that can be used to implement a wide variety of pop-up windows to your web application. You can use it for forms, tooltips, notices, galleries, or whatever you need as a pop-up window.&lt;/p&gt;

&lt;p&gt;In the previous blog post, I wrote about j-Importer and already showed you a little bit of j-Box. In this blog, we will continue with the code from the previous blog, because we prepared there j-Importer for our j-Box. So if you are new here, please read the previous blog before, to fully understand the connections here and why we used both components together.&lt;/p&gt;

&lt;p&gt;Because we want to use j-Box as a pop-up window for an example form, we will create it as a new HTML file. This file we put in the forms folder in our directories and it will be imported by j-Importer, when we click on the button we already prepared in the previous blog. This HTML file can have &lt;strong&gt;HTML parts&lt;/strong&gt;, &lt;strong&gt;styles&lt;/strong&gt;, and also &lt;strong&gt;JavaScript PLUGIN&lt;/strong&gt; for itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use j-Box
&lt;/h2&gt;

&lt;p&gt;As the first step you have to know how to use the jComponent library. I wrote about it in my previous blog, so for more information please read this &lt;a href="https://dev.to/palo/jcomponent-totaljs-1m26"&gt;blog post about jComponent&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initialization
&lt;/h2&gt;

&lt;p&gt;We can initialize more j-Box components if we need them, but they have to be in different files if we want to use them separately. In this example, I will show you how to initialize one j-Box, and based on that you will learn, that it is very easy and you will be able to use it further.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"box"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"*form"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"if:CLASS;title:TEST;width:350;submit:?/submit;reload:?/reload"&lt;/span&gt; &lt;span class="na"&gt;plugin=&lt;/span&gt;&lt;span class="s"&gt;"CLASS"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hidden CLASS"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;nav&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"exec"&lt;/span&gt; &lt;span class="na"&gt;data-exec=&lt;/span&gt;&lt;span class="s"&gt;"?/menu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ti ti-angle-down"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;Menu&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"padding"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    CLASS
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;nav&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;SUBMIT&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"cancel"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;CANCEL&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see in this example the word &lt;strong&gt;CLASS&lt;/strong&gt; in multiple places. It is important to understand, that this word is in this case a reserved word (same as &lt;strong&gt;~PATH~&lt;/strong&gt;). Both will be replaced in the background for value, from the defined &lt;strong&gt;path&lt;/strong&gt;. In this case, it is a value &lt;strong&gt;testform&lt;/strong&gt;, because we used this path to invoke our j-Box and it is listening on that path.&lt;/p&gt;

&lt;p&gt;We used the same HTML tag as for other components - &lt;em&gt;ui-component&lt;/em&gt;. We used the same attributes as before, a &lt;strong&gt;name&lt;/strong&gt; with a value &lt;strong&gt;box&lt;/strong&gt; because we want to use component j-Box. Attribute &lt;strong&gt;path&lt;/strong&gt; with value &lt;em&gt;**form&lt;/em&gt;* where &lt;em&gt;(star) is in the background replaced for path &lt;em&gt;common&lt;/em&gt;, so final path is &lt;em&gt;common.form&lt;/em&gt;. The last attribute is **config&lt;/em&gt;* with settings &lt;strong&gt;if&lt;/strong&gt; with value &lt;strong&gt;CLASS&lt;/strong&gt; which is a condition for showing the form, it's compared with the value within of the defined &lt;strong&gt;path&lt;/strong&gt;. Setting &lt;strong&gt;title&lt;/strong&gt; with value &lt;strong&gt;TEST&lt;/strong&gt; which is a title for the form. &lt;strong&gt;width&lt;/strong&gt; with a value of &lt;strong&gt;350&lt;/strong&gt; which means, that the form will have a width of 350 pixels. &lt;strong&gt;submit&lt;/strong&gt; with value &lt;strong&gt;?/submit&lt;/strong&gt;, which means, that a function submit from a particular PLUGIN will be invoked after clicking on the button submit. And setting &lt;strong&gt;reload&lt;/strong&gt; with value &lt;strong&gt;?/reload&lt;/strong&gt;, which means, that function reload from particular PLUGIN will be invoked after reload.&lt;/p&gt;

&lt;p&gt;The next attribute is a &lt;strong&gt;plugin&lt;/strong&gt; with the value &lt;strong&gt;CLASS&lt;/strong&gt;, which sets our plugin value to &lt;strong&gt;testform&lt;/strong&gt; because as I wrote before, the word &lt;strong&gt;CLASS&lt;/strong&gt; will be replaced in the background.&lt;/p&gt;

&lt;p&gt;The last attribute is &lt;strong&gt;class&lt;/strong&gt;, which is basically a class, and we set their values &lt;strong&gt;hidden&lt;/strong&gt; and &lt;strong&gt;CLASS&lt;/strong&gt; because we want to use this as a unique class for our form. It is good for us when we do not want to mix our styles between different forms and app.&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%2F3sovffi7m082d0h0ydyg.gif" 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%2F3sovffi7m082d0h0ydyg.gif" alt="Example of j-Box displayed on the web"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see in the code, that this component has its inside divided into three parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Menu
&lt;/h2&gt;

&lt;p&gt;The first part is navigation with one button for the menu. This button you can see in the header of our component. You can remove this part, or implement there some pop-up menu with options. For this example, I implemented there menu. This menu is made with the &lt;a href="https://componentator.com/components/j-menu/" rel="noopener noreferrer"&gt;jComponent j-Menu&lt;/a&gt;. By clicking on the button &lt;strong&gt;Menu&lt;/strong&gt;, the function &lt;strong&gt;menu&lt;/strong&gt; from our PLUGIN is invoked and a menu will appear. (JavaScript PLUGIN is part of the &lt;strong&gt;test.html&lt;/strong&gt; file, which includes our component j-Box, so this PLUGIN is created exactly for this form and they are part of the same plugin - &lt;strong&gt;testform&lt;/strong&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;menu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;opt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eidt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Edit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ti ti-pencil&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;remove&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Remove&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ti ti-trash red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;align&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;right&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nc"&gt;SETTER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;menu/show&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this code, we will get a pop-up menu with two options - &lt;strong&gt;Edit&lt;/strong&gt; and &lt;strong&gt;Remove&lt;/strong&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%2F6aebe6pyw1enjmqjxmqa.gif" 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%2F6aebe6pyw1enjmqjxmqa.gif" alt="Example of pop-up menu in j-Box"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;p&gt;The middle part is for content in our j-Box. In the code, you can see, that I wrote there only the word &lt;strong&gt;CLASS&lt;/strong&gt;, but because it is replaced in the background, you can see the &lt;strong&gt;testform&lt;/strong&gt; rendered on the web.&lt;/p&gt;

&lt;p&gt;This is the part of the component, where you can put your content. It depends completely on your case if you use it for some information text, gallery, form, or whatever you need.&lt;/p&gt;

&lt;p&gt;You can put there for example some &lt;a href="https://componentator.com/components/j-input/" rel="noopener noreferrer"&gt;jComponent j-Input&lt;/a&gt; components and make a form from it. I will take some content from j-Input in componentator.com and I will show you how it will look.&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%2Fjdr6p2pypp122ncbfp2q.gif" 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%2Fjdr6p2pypp122ncbfp2q.gif" alt="Example of j-Box as a form"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code used in this example (only replaced middle part):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"padding"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"?.framework"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"placeholder:Choose a framework;dirsource:frameworks"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"m"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Framework&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"?.terms"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"type:checkbox"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"m"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;I agree with terms&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"?.notes"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"type:multiline;innerlabel:1;placeholder:Enter notes"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"m"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Notes&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"?.frameworks"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"placeholder:Select frameworks;multiple:true;dirsource:frameworks"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Frameworks&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"?.city"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"required:1;placeholder:Where do you live?;dirsource:cities;innerlabel:true;dircustom:true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;City&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"?.date"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"placeholder:Enter date;type:date;required:true;innerlabel:true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Date&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"?.search"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"placeholder:Search...;type:search;innerlabel:true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Search&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"?.password"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"placeholder:Type a password...;type:password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Password&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And because this form has defined also the &lt;strong&gt;plugin&lt;/strong&gt; attribute, all values are now available on this plugin path (&lt;strong&gt;testform&lt;/strong&gt; in this case).&lt;/p&gt;

&lt;h2&gt;
  
  
  Buttons
&lt;/h2&gt;

&lt;p&gt;The last section is buttons, which are rendered in the bottom part of the form. It is optional for you, you can use both these buttons, remove them, or use only one you need. In this example, I will show you how to use it. In the configuration for the j-Box component we defined, that we want to invoke the function &lt;strong&gt;submit&lt;/strong&gt; after clicking on the submit button. So we have to create this function in our &lt;strong&gt;PLUGIN&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;submit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SUBMIT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, after clicking on the submit button we will get text &lt;strong&gt;SUBMIT&lt;/strong&gt; in our console.&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%2Fxqvuv61l5cliiizp8ibl.gif" 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%2Fxqvuv61l5cliiizp8ibl.gif" alt="Example of submit button in j-Box"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can do the same also for the &lt;strong&gt;Cancel&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;Maybe it will help you more if you see the complete code in the &lt;strong&gt;test.html&lt;/strong&gt; file, so I will add it here.&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%2Fqd77lsmmyk4y51g1jryo.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%2Fqd77lsmmyk4y51g1jryo.png" alt="Complete code from the test.html file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope you learned something new with this blog, but do not forget, that this was only for example purposes and you can do a lot more with this component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Video tutorial&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/DGX4AI0IVhE"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>ui</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>totaljs</category>
    </item>
    <item>
      <title>j-Importer - Total.js</title>
      <dc:creator>Pavol</dc:creator>
      <pubDate>Tue, 18 Mar 2025 09:03:02 +0000</pubDate>
      <link>https://forem.com/palo/j-importer-totaljs-18kj</link>
      <guid>https://forem.com/palo/j-importer-totaljs-18kj</guid>
      <description>&lt;p&gt;j-Importer is part of the jComponent library from &lt;a href="https://www.totaljs.com/" rel="noopener noreferrer"&gt;Total.js&lt;/a&gt;. You can find more information about j-Importer on &lt;a href="https://componentator.com/components/j-importer/" rel="noopener noreferrer"&gt;componentator.com&lt;/a&gt; or &lt;a href="https://github.com/totaljs/components/tree/master/j-Importer" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Importer is a great component to use, when you want to import HTML templates, scripts, or styles to your page. You can do this import dynamically based on some condition on a path. &lt;/p&gt;

&lt;p&gt;In this blog, I will show you how to use j-Importer to import pop-up form, and in the next one, I will show you how to work with that form. So these two blogs will be related and for total understanding, please read both of them. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to use j-Importer
&lt;/h2&gt;

&lt;p&gt;As the first step you have to know how to use the jComponent library. I wrote about it in my previous blog, so for more information please read this &lt;a href="https://dev.to/palo/jcomponent-totaljs-1m26"&gt;blog post&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initialization
&lt;/h3&gt;

&lt;p&gt;We can initialize as many j-Importers as we need. In this example, I will show you how to initialize one j-Importer, and based on that you will learn, that it is very easy and you will be able to use it further.&lt;/p&gt;

&lt;p&gt;Case for this example will be importing one pop up form in our page by clicking on button &lt;strong&gt;Open form&lt;/strong&gt;. This form will be empty and I will tell you more about it in the next blog.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"importer"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"*form"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"if:testform;url:../forms/test.html;reload:?/reload"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We used the same HTML tag as for other components - &lt;em&gt;ui-component&lt;/em&gt;. You can see in the example three attributes, &lt;strong&gt;name&lt;/strong&gt;, &lt;strong&gt;path&lt;/strong&gt;, and &lt;strong&gt;config&lt;/strong&gt;. In the first attribute, we wrote value &lt;strong&gt;importer&lt;/strong&gt;, because that is the name of the component we want to use. The second attribute is the &lt;strong&gt;path&lt;/strong&gt; with value &lt;em&gt;*form&lt;/em&gt;, where * (star) is in the background replaced for path common. So the final path will look like a common.form. In the &lt;strong&gt;config&lt;/strong&gt;, we have settings &lt;strong&gt;if&lt;/strong&gt; with value &lt;strong&gt;testform&lt;/strong&gt;, which is a condition for importing. &lt;strong&gt;url&lt;/strong&gt; with value &lt;strong&gt;../forms/test.html&lt;/strong&gt;, which is the address to the document we want to import (in this case it is &lt;strong&gt;test.html&lt;/strong&gt; in folder &lt;strong&gt;forms&lt;/strong&gt;). The last one is &lt;strong&gt;reload&lt;/strong&gt; with value &lt;strong&gt;?/reload&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Settings like this mean, that when we set the value on path &lt;em&gt;common.form&lt;/em&gt; to &lt;strong&gt;testform&lt;/strong&gt;, file &lt;strong&gt;test.html&lt;/strong&gt; from folder &lt;strong&gt;forms&lt;/strong&gt; will be imported to our page and function &lt;strong&gt;reload&lt;/strong&gt; in this file will be invoked.&lt;/p&gt;

&lt;p&gt;So now, when we have prepared our importer, we can create a button and function to invoke it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"exec open"&lt;/span&gt; &lt;span class="na"&gt;data-exec=&lt;/span&gt;&lt;span class="s"&gt;"?/openform"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Open form&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our button has a text &lt;strong&gt;Open form&lt;/strong&gt; and by clicking on this button we want to invoke function &lt;strong&gt;?/openform&lt;/strong&gt; in JavaScript PLUGIN.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;openform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;SET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testform&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see in the &lt;strong&gt;openform&lt;/strong&gt; function, we only need to set value in the &lt;em&gt;common.form&lt;/em&gt; to &lt;strong&gt;testform&lt;/strong&gt; to invoke our j-Importer. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example code in test.html:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ui-component&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"box"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"*form"&lt;/span&gt; &lt;span class="na"&gt;config=&lt;/span&gt;&lt;span class="s"&gt;"if:CLASS;title:TEST;width:350;reload:?/reload"&lt;/span&gt; &lt;span class="na"&gt;plugin=&lt;/span&gt;&lt;span class="s"&gt;"CLASS"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hidden CLASS"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"padding"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    CLASS
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ui-component&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We used component &lt;a href="https://componentator.com/components/j-box/" rel="noopener noreferrer"&gt;j-Box&lt;/a&gt; in this file, but we will talk more about this component in the next blog, this is only for example usage.&lt;/p&gt;

&lt;p&gt;Now when we click on the &lt;strong&gt;Open form&lt;/strong&gt; button, j-Box will appear thanks to j-Importer.&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%2F8lv2bhg1bju4zj0b3m3m.gif" 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%2F8lv2bhg1bju4zj0b3m3m.gif" alt="Example of j-Importer" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can remember, we also added the setting &lt;strong&gt;reload&lt;/strong&gt; to our j-Importer. So we can expand our example and add function &lt;strong&gt;exports.reload&lt;/strong&gt; to the form file. This function will be invoked automatically after importing the &lt;strong&gt;test.html&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;PLUGIN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HERE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After importing the form, we want to get text &lt;strong&gt;HERE&lt;/strong&gt; in our console.&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%2Fmanp61g3f05eon5neuc2.gif" 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%2Fmanp61g3f05eon5neuc2.gif" alt="Example of j-Importer with invoking reload function" width="934" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the example, the text &lt;strong&gt;HERE&lt;/strong&gt; will appear in the console after every invoking of our form. It means that the function &lt;strong&gt;reload&lt;/strong&gt; in JavaScript PLUGIN of our form is invoked every time by j-Importer. You can use this for example for getting some data to your form or whatever you want to render in the j-Box component. It does not have to be a form, it can be some popup window, notice, tooltip, and more.&lt;/p&gt;

&lt;p&gt;I hope you learned something new with this blog, but do not forget, that this was only for example purposes and you can do a lot more with this component.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video tutorial
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/49VmOcK9qsQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ui</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
