<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mikk Mangus</title>
    <description>The latest articles on DEV Community by Mikk Mangus (@murjam).</description>
    <link>https://dev.to/murjam</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%2F175642%2F8f2566ab-8248-41a7-b040-3d7874e63b77.png</url>
      <title>DEV Community: Mikk Mangus</title>
      <link>https://dev.to/murjam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/murjam"/>
    <language>en</language>
    <item>
      <title>Controlling RGBW LED strip from Node-RED</title>
      <dc:creator>Mikk Mangus</dc:creator>
      <pubDate>Mon, 19 Apr 2021 22:28:33 +0000</pubDate>
      <link>https://dev.to/murjam/controlling-rgbw-led-strip-from-node-red-12f7</link>
      <guid>https://dev.to/murjam/controlling-rgbw-led-strip-from-node-red-12f7</guid>
      <description>&lt;p&gt;Considering the discreet style I usually utilize at home, I would have never imagined myself installing some RGB LED strips for lighting, but this is exactly what I recently did.&lt;/p&gt;

&lt;p&gt;There is a wooden skirting board on the wall of my living room and for some reason, I got stuck to the idea of attaching lighting on top of that.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5wk1sf4woka2nevkhhj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5wk1sf4woka2nevkhhj.jpg" alt="The skirting board"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I knew from the very beginning that at minimum the LED strip I was adding there had to have addressable warm white LEDs. Why addressable? Because I am a developer and just changing the brightness by applying different voltage does not sound anywhere as fun as being able to tweak each LED by code individually. But to make it even more fun, why not add the RGB capability to the mix 🤔&lt;/p&gt;
&lt;h2&gt;
  
  
  RGBW - easy peasy to find one! No?
&lt;/h2&gt;

&lt;p&gt;So there I was, searching for an addressable LED strip that would have RGB + warm white and was using 12V power. 12V was needed because the whole line is about 15m in length and I do not want to have multiple power sources nor additional wiring for injecting power to the middle of the strip.&lt;br&gt;
Although there are many RGB LED strips available, it took me a while to find the right strip. Most of them are either not addressable at all, or when addressable, using 5V for power. And you might find one that is 12V addressable RGB, but it probably lacks the separate warm white output. By the way, there is the need to have a separate warm white light emitter because just mixing up RGB to get a good warm white simply does not work.&lt;/p&gt;

&lt;p&gt;Anyways, eventually, I did find the right strips I needed from Aliexpress 🎉. They are 12V RGB + warm white driven by an SK6812 chip, 60 LEDs per meter, no dust/water resistance of course.&lt;/p&gt;
&lt;h2&gt;
  
  
  The aluminum rail
&lt;/h2&gt;

&lt;p&gt;At first, I bought an uncolored aluminum rail for the LEDs, and it looked nice, but then realized that the white-colored rail would give a stealthier look. That was a really good decision to switch to white rails.&lt;br&gt;
Here is a picture of the cutting process:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbkivjshk9nh4a7xnf1l9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbkivjshk9nh4a7xnf1l9.jpg" alt="The cutting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're after a picture where the rail is attached on top of the skirting board, take a look at the previous picture - it is already on the picture 😉&lt;br&gt;
The rail got attached using mostly double-sided tape and a few screws here and there.&lt;/p&gt;
&lt;h2&gt;
  
  
  Zigbee
&lt;/h2&gt;

&lt;p&gt;I was more than sure of from the very beginning that I need to be able to control the LED strip from my home automation system which consists of a few &lt;a href="https://nodered.org/" rel="noopener noreferrer"&gt;Node-RED&lt;/a&gt; instances running on top of &lt;a href="https://www.zigbee2mqtt.io/" rel="noopener noreferrer"&gt;zigbee2mqtt&lt;/a&gt; inside a Raspberry Pi 4. As I was planning to install the controller for the LED strip to the other side of the room then the Raspberry is sitting anyways, I had in mind to transmit the commands over Zigbee as most of the other smart devices at my home are communicating with.&lt;/p&gt;

&lt;p&gt;So I was researching standalone Zigbee controllers, Arduino Zigbee shields, XBee, ESP32, etc. But I did not come up with any good setup for what I was trying to achieve - build a device that would connect to my Zigbee network, take commands from there and be able to connect the RGBW LED strip. It all would be fairly simple to implement over Bluetooth or Wifi, but I had the urge to use Zigbee - and there are reasons for this 😆.&lt;/p&gt;
&lt;h3&gt;
  
  
  Arduino + XBee
&lt;/h3&gt;

&lt;p&gt;The most straight forward would probably have been to have an Arduino with a shield for XBee and an XBee module on top of that - but that option I did not like for multiple reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It would be physically a huge pile of boards&lt;/li&gt;
&lt;li&gt;I just do not like the way XBee boards are configured 🙈 (you need to use a proprietary Windows software)&lt;/li&gt;
&lt;li&gt;Each board separately (Arduino, XBee) has the potential to drive the LED strip, but I still would have needed to have them both 🤷&lt;/li&gt;
&lt;li&gt;How come this pile of boards will cost you about $100 while you can buy a well-built Zigbee device for $10 🙄&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  CC2530
&lt;/h3&gt;

&lt;p&gt;There is a cheap Texas Instrument chip widely available that is made for Zigbee. It is trivial to burn onto that chip software that connects it to my Zigbee network as a router but would need some low-level C programming (compared to using an available library for Arduino) with proprietary tools to make it control the RGBW strip. I do not want to go down that rabbit hole either. It would be the right thing to do if I made this thing a product, but this time I wanted to just make my idea happen.&lt;/p&gt;
&lt;h3&gt;
  
  
  CC2530 + Arduino
&lt;/h3&gt;

&lt;p&gt;The combination of CC2530 for communicating over Zigbee plus Arduino that would control the LED strip and talk to CC2530 over a serial interface seems appealing. I must admit I did order the CC2530 in many forms, but as none of them physically easily plugged into Arduino and I had (still have) some bits missing in the puzzle of putting them together and exposing the right interface through Zigbee, I gave up before truly trying to make this happen.&lt;/p&gt;
&lt;h3&gt;
  
  
  Microduino 🤔
&lt;/h3&gt;

&lt;p&gt;The best possible option I found from the market would have been &lt;a href="https://wiki.microduinoinc.com/Microduino-Module_CoreRF" rel="noopener noreferrer"&gt;Microduino Module CoreRF&lt;/a&gt;. In theory, it should support Zigbee and can easily use libraries built for Arduino. But there is some lack of information on how exactly to use this, with no recent updates it seems like a dead project, and I could not find it anywhere in stock.&lt;br&gt;
Although visiting the page now when writing this very article, I did find a &lt;a href="https://microduinoinc.com/product/zigbee-diy/" rel="noopener noreferrer"&gt;Microduino Zigbee module&lt;/a&gt; available in their web store. I will probably get myself one 😎&lt;/p&gt;
&lt;h2&gt;
  
  
  No wireless - no problem
&lt;/h2&gt;

&lt;p&gt;While being a little stuck with my progress to have a neat controller I could easily control the RGBW light strip with, I started to curve my living room around in a different way and realized I could wire it all together in a way that would bring the controller very close to the Raspberry. That's what got me into thinking of dropping the wireless (Zigbee) connection idea.&lt;/p&gt;

&lt;p&gt;As I did have some Arduinos laying around, I started from there. The device at hand appears to be an Arduino Nano v3.0 if you're curious.&lt;/p&gt;
&lt;h2&gt;
  
  
  FastLED
&lt;/h2&gt;

&lt;p&gt;Controlling Addressable LEDs with Arduino is very simple - there is a ready-made library to use: &lt;a href="https://www.arduino.cc/reference/en/libraries/fastled/" rel="noopener noreferrer"&gt;FastLED&lt;/a&gt;. The only issue was that it is not supporting SK6812 chipset and RGB+W output.&lt;/p&gt;

&lt;p&gt;Luckily, Arduino is a well-established platform and there is a &lt;a href="https://www.partsnotincluded.com/fastled-rgbw-neopixels-sk6812/" rel="noopener noreferrer"&gt;patch for FastLED&lt;/a&gt; to support the extra channel. I only needed to do some modifications for the values to represent the right color channels. 🌈&lt;/p&gt;
&lt;h2&gt;
  
  
  Physical installation
&lt;/h2&gt;

&lt;p&gt;This is the first test run of the LED strip:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ejyrv8eme4oz5pmnkiy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ejyrv8eme4oz5pmnkiy.jpg" alt="Testrun"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the LED strip cutting and soldering in action. The picture does not paint the whole truth I must say. The floor was that clean only in the beginning 😆&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvh8ls5j58l5dnlqmrviv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvh8ls5j58l5dnlqmrviv.jpg" alt="Cutting and soldering LED strip"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the strip cut, inserted into the rail, and soldered to the following strip:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fomjvw04o9v9hrz29uhyc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fomjvw04o9v9hrz29uhyc.jpg" alt="LED strip installed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the first test run of part of the strip is installed to the rail:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fze23wol5dnaroiypvr1i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fze23wol5dnaroiypvr1i.jpg" alt="The half test run"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same run from a different angle - don't try this at home 😄&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22lnbxs3zehst8gy0azq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22lnbxs3zehst8gy0azq.jpg" alt="Power to the test"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here it is with the cover/diffusor installed on top of the rail and Arduino installed without an enclosure (also what it looks like today):&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8e55c0ycl84idxcz2yqg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8e55c0ycl84idxcz2yqg.jpg" alt="The result"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The problems
&lt;/h2&gt;

&lt;p&gt;Did you expect it all to go without any issues from here on? Oh well, it did not. Once I had the whole strip installed, I used up many days to debug/cut/resolder the strips to figure out why the signal was not spreading on all of the LED strip.&lt;/p&gt;

&lt;p&gt;It was just cut off at a random place.&lt;br&gt;
It all did function when I first tried it on the table 😟&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpqs4s5s77plgz9sdi1c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpqs4s5s77plgz9sdi1c.jpg" alt="Signal cut off"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Maybe just some voltage drop in the supply power?
&lt;/h3&gt;

&lt;p&gt;Of course, this was my initial thought as well, but that got debunked with the simplest math: the power was supplied to the strip from the other end - from where the strip was not lightened up.&lt;/p&gt;
&lt;h3&gt;
  
  
  Maybe bad ground connection?
&lt;/h3&gt;

&lt;p&gt;I must say - my experience tells me - when you ever observe some electrical anomalies, look for bad ground connections. But this time it was not the case. As said, the power was applied from the other end, the cutoff was about 30th LED from the digital signal provided by Arduino.&lt;/p&gt;
&lt;h3&gt;
  
  
  There is just one LED broken that does not pass the signal
&lt;/h3&gt;

&lt;p&gt;It was clear that this is the problem. After all, addressable LEDs must pass the data signal to the following LEDs and if they do not for some reason, the signal is cut off.&lt;/p&gt;

&lt;p&gt;The only problem was that ... now that I hassled to unsolder, cut off, reinstall the last working LED in the strip ... the exact same problem was still there 😳&lt;/p&gt;
&lt;h3&gt;
  
  
  Maybe there is an LED in the middle that somehow messes up a bit in the data signal?
&lt;/h3&gt;

&lt;p&gt;So I did cut, course, test, resolder many parts of the strip, but the outcome was always the same - the LED strip just did not lighten up from somewhere on. But I did observe something interesting when doing this: there was always the same number of LEDs lighting up. I.e taking two LEDs away from the lightened part of the strip made the cutoff to move by two LEDs forward 🤔&lt;/p&gt;
&lt;h3&gt;
  
  
  Maybe the FastLED hack messed up with addressing the LEDs?
&lt;/h3&gt;

&lt;p&gt;Well, it all was perfectly working on the table, but I did tweak it here and there to test this assumption up without a success.&lt;/p&gt;
&lt;h3&gt;
  
  
  Then what?
&lt;/h3&gt;

&lt;p&gt;Then I just trialed and errored more. At some point, I started to cut off the beginning of the strip and move Arduino to different places in the strip realizing there was a spot where the strip lightened up fully! I had found the broken LED! Only that, I had not. After another round of cut-course-resolder I found out the strip was once again not lighting from the same point on 😕&lt;/p&gt;

&lt;p&gt;I started to suspect a wire that was connecting the sides of a doorway already long before, but there was no evidence this could have been the problem. The signal was not moving forward about 10 LEDs after the wire. The spot where I had to attach Arduino for the signal to pass through all the strip was 2 LEDs before the wire.&lt;/p&gt;

&lt;p&gt;Nevertheless, I replaced the wire. It was a regular power cable with non-solid 1.5mm2 wires that got replaced by a CAT5 cable (using a pair for each of the three wires). And that did the trick. Yup, that's the whole story. Apparently, the data signal does not like a regular cable 📝. I got it all lighted up and could move forward. ☺️&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp59n5zqn39gyrblo49th.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp59n5zqn39gyrblo49th.jpg" alt="The problematic wire"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Control with Arduino
&lt;/h2&gt;

&lt;p&gt;From that point on I felt pretty comfortable writing some LEDs-controlling code for Arduino. The main aim is that Arduino must be able to take commands from the Node-RED. I used the USB-serial connection that automatically gets created when Arduino is plugged into Raspberry Pi. That is very convenient because the same USB connection is used for powering up the Arduino.&lt;/p&gt;

&lt;p&gt;At first, I was keeping the data sent very simple, serial-communication-like if you will but then realized I almost always need to include many parameters (i.e &lt;code&gt;red&lt;/code&gt;, &lt;code&gt;green&lt;/code&gt;, &lt;code&gt;blue&lt;/code&gt;, &lt;code&gt;white&lt;/code&gt;, &lt;code&gt;brightness&lt;/code&gt;, &lt;code&gt;mode&lt;/code&gt;) and switched to Arduino processing JSON string. It is overkill, I know, but it does work and is convenient to use on the other side.&lt;/p&gt;

&lt;p&gt;Just pasting the whole Arduino code I have at the moment for you to review, not that it is polished nor I am proud of it, but maybe there is a thing or two you might find interesting.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  The window
&lt;/h3&gt;

&lt;p&gt;Maybe you noticed in the code that there are some LEDs "within" a window. What it actually means, is that I installed the LED lights also on top of the window blind tree because I thought the window might be too big of a gap of darkness.&lt;br&gt;
But once I had it installed, I was dissatisfied how the ceiling got lighted up by the LEDs on the blind tree.&lt;/p&gt;

&lt;p&gt;This is a perfect example of why addressable LEDs are cool though! I was able to simply dim down the LEDs on top of the blind tree to create an even better effect that makes the lighting look very similar to how it does on other areas in the room. 🎉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbbumdv013fn3daixugy5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbbumdv013fn3daixugy5.jpg" alt="LEDs on blind tree"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Node-RED
&lt;/h2&gt;

&lt;p&gt;My main Node-RED instance runs in a docker container that does not have access to the system hardware. But I do have another Node-RED instance that does and is there only to route some of the hardware signals to the MQTT and vice versa. This was an easy task to convert serial to MQTT:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvdrh6us5keo79xxicrf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvdrh6us5keo79xxicrf.png" alt="Serial to main Node-RED"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The picture does show &lt;code&gt;/dev/ttyUSB0&lt;/code&gt;, but this is actually mapped in my &lt;code&gt;docker-compose&lt;/code&gt; to the serial from &lt;code&gt;/dev/serial/by-id/:theSerialDeviceId&lt;/code&gt; - you should always point to the device by ID to be sure it is the same device after next plug-in.&lt;/p&gt;

&lt;p&gt;One more minor thing to bring out is that although the LEDs can be commanded to turn themselves off, I'm using an external Zigbee relay to cut the power wholly when the LEDs are turned off. It does not look pretty under the windowsill 🙈 and I pinky-promise I will tidy up the wiring once the lock-down backs up a little and stores get opened, but this is how the relay and 200W 12V AC/DC converter is hooked up under the windowsill right now:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxcadydvbl0f7vie0aup.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxcadydvbl0f7vie0aup.jpg" alt="Under the windowsill"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Any conclusions?
&lt;/h2&gt;

&lt;p&gt;Would like to still get my hands on building custom Zigbee devices, but this time I am happy with just hooking up Raspberry to Arduino with a USB cable.&lt;/p&gt;

&lt;p&gt;The next step I want to add to this is an array of microphones for input to create some cool audiovisual effects 🌟, but giving out no promises here 😄&lt;/p&gt;

&lt;p&gt;Sharing an awkward video of the lights in action. The party mode as you see does not engage on the first click - find the issue in the provided Arduino code 😉&lt;br&gt;
I do have some ideas, but feel free to share yours on how to improve the code for Arduino?&lt;/p&gt;

&lt;p&gt;Have fun!&lt;/p&gt;

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

</description>
      <category>arduino</category>
      <category>rgb</category>
      <category>rgbw</category>
      <category>raspberrypi</category>
    </item>
    <item>
      <title>Making the Sommer Twist 200E motorized gate smarter with Node-RED</title>
      <dc:creator>Mikk Mangus</dc:creator>
      <pubDate>Mon, 01 Feb 2021 22:47:01 +0000</pubDate>
      <link>https://dev.to/murjam/making-the-sommer-twist-200e-motorized-gate-smarter-with-node-red-22e</link>
      <guid>https://dev.to/murjam/making-the-sommer-twist-200e-motorized-gate-smarter-with-node-red-22e</guid>
      <description>&lt;p&gt;I had recently a &lt;a href="https://www.manualslib.com/manual/1290705/Sommer-Twist-200-E.html?page=14#manual"&gt;Sommer Twist 200E&lt;/a&gt; controller installed for my car gate. As I already have a &lt;a href="https://nodered.org/"&gt;Node-RED&lt;/a&gt; and &lt;a href="https://www.zigbee2mqtt.io/"&gt;Zigbee2mqtt&lt;/a&gt; set up for my home automations, and, most importantly, operating a gate by pressing a button on a remote is so 1990s, I knew right away I want to be able to connect it to my Node-RED somehow.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hardware setup
&lt;/h2&gt;

&lt;p&gt;To do that, I had a CAT6 cable installed between the controller and my house. The way to send signals to the gate controller is to use the two button-input interfaces it provides: one for opening/closing one side of the gate, the other one for opening/closing both sides of the gate.&lt;/p&gt;

&lt;p&gt;To mimic the click of a button, I found it easiest to use a relay that I could control via Zigbee. Although I could not see a need for more than 2 relays, bought &lt;a href="https://www.tindie.com/products/a_lab_technology/zigbee-4-channel-relay/"&gt;one with 4 relays&lt;/a&gt; that has the relays outputs not connected to the power. Unfortunately, the case for the module was out of stock, so got myself only a board.&lt;/p&gt;

&lt;p&gt;By the time the module arrived, I had realized I could use the same module to control the lock of another foot gate. I attached the Zigbee board into a box together with the 12V power supply for the electric lock for that gate. Here is a picture of the board, power supply for the other gate, and a generic box to accommodate it all:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jnVPGy-g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wk10gk64rtv4ymqvcaat.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jnVPGy-g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wk10gk64rtv4ymqvcaat.jpg" alt="The components" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The 12V power supply had spots for mounting it which accidentally precisely matched with some holes at the bottom of the box when the power supply was slightly tilted. Used screws to keep it in place. To attach the Zigbee board on top of it, I used 4 raisers that match the holes in the corners of the board.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3qnOTjBa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4wq4s3uctbjjtcnk4boi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3qnOTjBa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4wq4s3uctbjjtcnk4boi.jpg" alt="The raisers" width="880" height="1173"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xZYXJehN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vc40997ifzo2n96j9q6z.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xZYXJehN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vc40997ifzo2n96j9q6z.jpg" alt="Board fastened" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The button inputs the Sommer Twist 200E has either open or close the gate depending on the current state of the gate. For my Node-RED instance to know the state of the gate, I installed a &lt;a href="https://www.zigbee2mqtt.io/devices/SNZB-04.html"&gt;SONOFF Zigbee contact sensor&lt;/a&gt; for my gate. It is a lovely winter outside here in Estonia right now, fortunately the sensor seems to not bother about heavy raining nor cold 🎉&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yi-n6Fkw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/illhbaem7e6kwpemytc6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yi-n6Fkw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/illhbaem7e6kwpemytc6.jpg" alt="Zigbee contact sensror outside" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The dummy controller
&lt;/h2&gt;

&lt;p&gt;To close the gate, Sommer Twist 200E supports in general two modes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;the gate will close only if the button is pressed while the gate is open;&lt;/li&gt;
&lt;li&gt;the gate will automatically close after 5 seconds the photosensor installed on the line of the gate sees something (i.e a car goes through the gate).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is easy to use one of the provided modes, but there's no option to switch between them other than changing the states of microswitches on the controller. I do like the auto-close function, but I felt I cannot live with that only, because I sometimes want to keep the gate open - i.e while waiting for the guests to arrive.&lt;/p&gt;

&lt;p&gt;At first, I switched on the mode 1 and tried to achieve the auto-close function with some delays and a Zigbee PIR sensor that I had already installed anyways next to the gate, but it turned out to be not precise enough. I could have closed the gate if the PIR sensor saw something and then did not see anything for a few minutes, but by that time, I would have driven already far from home. I did like the auto-close functionality the controller supports on its own in combination with its photosensor.&lt;/p&gt;

&lt;p&gt;So, the next attempt was to turn on the auto-close mode and try to somehow make it keep the gate open when needed. I had many (crazy) ideas on how to achieve that, for instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let the gate automatically close, but reopen it right away if the state is set to "keep open"&lt;/li&gt;
&lt;li&gt;Cut the micro-switches and use relays to change the state of the switches on the fly&lt;/li&gt;
&lt;li&gt;Attach a servo motor with a blind to the photosensor that would keep something in front of it if I want to keep the gate open -- it wouldn't close if there's something on the way 🙈.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was already close to trying out those crazy ideas, but luckily found a much easier and cleaner way to keep the gate open - I just cut the signal going to the photosensor with a relay. Almost installed another relay into the box of the gate controller, but realized I could use the CAT6 cable and the relay module I already had installed. Funnily, now that I did that, I have all the 4 relays hooked up -- two for operating the car gate inputs, one for unlocking the other gate and one for cutting the photosensor signal. Remember, I did not think there could be a way I'd need the module to have that many relays 😆&lt;/p&gt;

&lt;p&gt;The connections in the gate controller box (the single blue line is used for routing the photosensor signal through the relay):&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Uk-Nxi9C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4koyr3tj18xfwyr3fcuj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Uk-Nxi9C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4koyr3tj18xfwyr3fcuj.jpg" alt="Gate controller" width="880" height="1173"&gt;&lt;/a&gt;&lt;br&gt;
The relay box now with all 4 relays in use:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G12T3MBp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6n0prtd88hqcxipzz48f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G12T3MBp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6n0prtd88hqcxipzz48f.jpg" alt="Zigbee 4-channel relay module" width="880" height="1173"&gt;&lt;/a&gt;&lt;br&gt;
I like it a lot that the photosensor connection is cut using a "normally closed" pin of the relay -- another nice feature the &lt;a href="https://www.tindie.com/products/a_lab_technology/zigbee-4-channel-relay/"&gt;4-channel relay board&lt;/a&gt; has. It also has a 5th output attached to a buzzer on the board and 4 inputs on its own that could be used for triggering anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The benefits
&lt;/h2&gt;

&lt;p&gt;Although, at first glance, connecting the gate to my home automation system does not seem to make it that much smarter, it actually brings many of the benefits that can be achieved with minimal effort:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The gate is kept open if wanted&lt;/li&gt;
&lt;li&gt;The gate can be operated from my phone or from my dashboard&lt;/li&gt;
&lt;li&gt;The gate can be operated remotely&lt;/li&gt;
&lt;li&gt;The gate can be operated using voice commands&lt;/li&gt;
&lt;li&gt;The gate can automatically open when approaching or leaving home (haven't been able to successfully set it up using &lt;a href="https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm&amp;amp;hl=en_US&amp;amp;gl=US"&gt;Tasker&lt;/a&gt; yet)&lt;/li&gt;
&lt;li&gt;Any other functionality you come up with can be added with ease 😄&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nodered</category>
      <category>homeautomation</category>
      <category>zigbee2mqtt</category>
    </item>
    <item>
      <title>Steady room temperature with node-red</title>
      <dc:creator>Mikk Mangus</dc:creator>
      <pubDate>Sun, 17 Jan 2021 11:16:38 +0000</pubDate>
      <link>https://dev.to/murjam/steady-room-temperature-with-node-red-40a4</link>
      <guid>https://dev.to/murjam/steady-room-temperature-with-node-red-40a4</guid>
      <description>&lt;p&gt;Most of the rooms at my home are heated using electric radiators. The radiators have a thermostat built in and a dial that controls the temperature.&lt;/p&gt;

&lt;p&gt;But the problem is that this dial mostly controls the temperature of the radiator itself, not the room. Without touching the dial, the temperature in the room fluctuates about ±1°C every 24h. Moreover, if it gets colder or warmer outside, the dial needs to be adjusted accordingly to keep the warmth in the room temperate.&lt;/p&gt;

&lt;p&gt;This is an article on how I achieved a steady temperature at home.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hardware
&lt;/h2&gt;

&lt;p&gt;As I was already running &lt;a href="https://www.zigbee2mqtt.io/" rel="noopener noreferrer"&gt;zigbee2mqtt&lt;/a&gt; and &lt;a href="https://nodered.org/" rel="noopener noreferrer"&gt;Node-RED&lt;/a&gt; on a Rasberry to control some automations I have set up at home, I chose to use the same stack. I already had different Zigbee temperature sensors installed to each room and the information about the temperature available.&lt;/p&gt;

&lt;p&gt;Bought a pack of Tuya Zigbee relays that are rated at 4000W, which is plenty for my heaters that use 1250W. The relays cost about $10 each.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5i4qd5mtp0xbv64ieong.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5i4qd5mtp0xbv64ieong.jpg" alt="Tuya Zigbee relay"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The relays got installed in series to the radiators meaning the only function they provide is to cutoff the power to the radiator.&lt;/p&gt;

&lt;p&gt;This is how it looked like with the radiator off the wall and the cover of the connections-box removed (sorry about the dust):&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feeb6il1n3pbiejldolgj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feeb6il1n3pbiejldolgj.jpg" alt="The power connections"&gt;&lt;/a&gt;&lt;br&gt;
And this is how it looks with the relay in series:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgnlg15nkadplu3206el7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgnlg15nkadplu3206el7.jpg" alt="The result"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The software
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The Simplest is not always the best
&lt;/h3&gt;

&lt;p&gt;The initial algorithm I tried for controlling the temperature was the simplest imaginable: cut off the power once the temperature reaches the setpoint, otherwise keep the power on. This unfortunately did not make the temperature any steadier. As it usually takes an hour to raise the temperature about 1°C, once the power was cut off, the temperature was overshooting more than 1°C from the setpoint and then 3 hours later undershooting more than 1°C.&lt;/p&gt;

&lt;p&gt;That clearly wasn't good enough, it was even worse than without the relays 😞&lt;/p&gt;

&lt;p&gt;I have worked quite a lot with different &lt;a href="https://en.wikipedia.org/wiki/PID_controller" rel="noopener noreferrer"&gt;PID&lt;/a&gt; setups, but this time I felt a truly PID algorithm was hard to put to use because you need to factor in the position of the dial on the radiator as well as the update rate of the zigbee temperature sensors.&lt;/p&gt;
&lt;h3&gt;
  
  
  The second iteration
&lt;/h3&gt;

&lt;p&gt;With the second iteration, I introduced another piece of state for the heater in my software, which I call &lt;code&gt;onPercentage&lt;/code&gt;. As the name suggests, it is the percentage of the time the heater should be on. Instead of keeping the heater on all the time, it now is turned on and off every 10 minutes according to the &lt;code&gt;onPercentage&lt;/code&gt; as follows:&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;temperature&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;setPoint&lt;/span&gt;&lt;span class="p"&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;minute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&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;minute&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;onPercentage&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;off&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// to avoid turning all heaters on at the same moment&lt;/span&gt;
    &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;on&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 from the code, I also added some randomness when turning on the heaters, because there's always a momentary spike in load whenever switching on an electrical device, and as the algorithm switches on all the heaters at once when &lt;code&gt;minute % 10 === 0&lt;/code&gt;, I felt it might become necessary.&lt;/p&gt;

&lt;p&gt;That's only half of the algorithm, the &lt;code&gt;onPercentage&lt;/code&gt; itself is adjusted by the overshooting and undershooting of the temperature reading. If the temperature is still increasing while the setpoint has been reached, the &lt;code&gt;onPercentage&lt;/code&gt; is lowered by 10% and vice versa. This is how it looks in the code:&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;const&lt;/span&gt; &lt;span class="nx"&gt;room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;room&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;onPercentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;room&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.heater_on_percentage`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;50&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;setPoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;room&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.temperature_setpoint`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;21&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;previous&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;room&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.temperature`&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;current&lt;/span&gt; &lt;span class="o"&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;temperature&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;increasing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;previous&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;decreasing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;previous&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;setPoint&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;previous&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;increasing&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;onPercentage&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;onPercentage&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;10&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setPoint&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;previous&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;decreasing&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;onPercentage&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;onPercentage&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// not returning anything means the previous value is retained&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essentially it is like a simplified version of using only the proportional (turned on when setpoint not reached) and integral (&lt;code&gt;onPercentage&lt;/code&gt; controlled by overshooting) parts of the &lt;a href="https://en.wikipedia.org/wiki/PID_controller" rel="noopener noreferrer"&gt;PID&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Anyways, when I had the &lt;code&gt;onPercentage&lt;/code&gt; implemented, I was amazed how well it turned out! It has now been a few months since I made this change and I have not touched the code after the first deploy 🎉. The temperature has been rock steady next to the setpoint throughout every day even with the temperature outside changing. I have set the dial on the radiator a little higher than before to allow it reach the setpoint easily. I have only adjusted some of the dials once when it got a lot colder outside and the &lt;code&gt;onPercentage&lt;/code&gt; maxxed out.&lt;/p&gt;

&lt;p&gt;An added benefit is that I can now control the heating/temperature programmatically and/or remotely.&lt;/p&gt;

&lt;p&gt;A sight to my node-red flow that does the temperature controlling:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnktiicso3e73uagt2vks.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnktiicso3e73uagt2vks.jpg" alt="Controlling temperature with node-red"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you happen to be more familiar with Node-RED, you might notice the function nodes without an input and the blue nodes on the right bottom of the screen -- yes, those are custom built nodes for modifying the state and subscribing to the state changes in a "React hooks"-like way.&lt;br&gt;
I might release that node-red-contribution soon™️, but need to clean the implementation up a little before I do 🙂&lt;/p&gt;

&lt;p&gt;Have fun!&lt;/p&gt;

</description>
      <category>nodered</category>
      <category>zigbee</category>
      <category>zigbee2mqtt</category>
      <category>homeautomation</category>
    </item>
    <item>
      <title>A journey of setting up Dahua cameras with Hikvision NVR</title>
      <dc:creator>Mikk Mangus</dc:creator>
      <pubDate>Sun, 22 Nov 2020 19:50:14 +0000</pubDate>
      <link>https://dev.to/murjam/a-journey-of-setting-up-dahua-cameras-with-hikvision-nvr-hib</link>
      <guid>https://dev.to/murjam/a-journey-of-setting-up-dahua-cameras-with-hikvision-nvr-hib</guid>
      <description>&lt;p&gt;The previous owner of my home had already installed surveillance cameras with power-over-ethernet support. There were the cameras and the wiring in place, but nothing connected to them.&lt;/p&gt;

&lt;p&gt;As I have a Raspberry PI already constantly running Node-RED for my home automation, I had thought of buying a PoE switch, hooking the cameras to the Raspberry, and enabling the system with some kind of recording software. I knew this would require quite a lot of DIY work and maintenance, so recently went in the other supposedly simpler direction: bought a Hikvision DS-7600 Network Video Recorder. I thought that must be an easy way to get the cameras running, just plug in the devices, and should be ready to go.&lt;/p&gt;

&lt;p&gt;Oh boy, I could not have been more wrong! Those cameras did not just plug-and-play.&lt;/p&gt;

&lt;h2&gt;
  
  
  A hint from Youtube
&lt;/h2&gt;

&lt;p&gt;As it turned out, the Dahua HFW-1300SP cameras were unable to connect to Hikvision NVR, no matter how I tried to configure them from the NVR.&lt;/p&gt;

&lt;p&gt;Even though I figured out the name of the cameras after some googling -- at first I thought the manufacturer was called "Alhua" 😂 --, I failed to find much help from the internet, almost every bit of information said I cannot connect the devices of those two manufacturers 😞.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b3338p2P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nawqew1e50wrna8d1yio.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b3338p2P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nawqew1e50wrna8d1yio.jpg" alt="Alhua or Dahua?" title="Alhua or Dahua?" width="880" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only promising hint I found was from a Youtube video that suggested Dahua camera to be configured with the following parameters that would make them connect the Hikvision network:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Static IP: 192.168.254.10 (increase the last number as needed)
Subnet mask: 255.255.255.0
Gateway: 192.168.254.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h2&gt;
  
  
  No PoE switch? DIY!
&lt;/h2&gt;

&lt;p&gt;As I did not have a regular PoE switch at hand, took my ladder and screwdriver, unscrewed the cameras and had them on the table trying to figure out how to power them up.&lt;/p&gt;

&lt;p&gt;I looked into my graveyard of old electronics, found an ancient Nokia phone charger which plug matched the 12V extra input the cameras have -- only that one gave out 5V instead of 12V. I almost cut in half the 15V charger of an old IBM laptop to test frying the cameras with higher voltage, but luckily found another power adapter for some old Motorola device, which had 12V output. After a little cutting and soldering, the new power adapter for the cameras was ready to roll.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PrSkhsXr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tq1srdrssrdboai7gv8r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PrSkhsXr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tq1srdrssrdboai7gv8r.jpg" alt="The power adapter" title="Sorry, I did not have heatshrink" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Resetting the cameras
&lt;/h2&gt;

&lt;p&gt;The cameras did boot up with my newly made adapter 🚀,  and I got the &lt;a href="https://dahuawiki.com/Update_Firmware_ConfigTool_4_05"&gt;Dahua configuration tool&lt;/a&gt; running in a Windows virtual machine, but there was another problem: the configuration tool was unable to connect to the cameras, probably because someone had changed the default passwords. That can usually be fixed with a simple "hold down the reset", but when I opened up the case of the camera, there was nothing marked as "reset" nor any buttons on the board 🤷&lt;/p&gt;

&lt;p&gt;I was almost giving up at that point, but there was a &lt;a href="http://www.forum.vidimost.com/viewtopic.php?f=58&amp;amp;t=3877"&gt;forum post in Russian&lt;/a&gt;, which I understood only with the help from Google translate, that helped me a step forward towards the goal.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KvM7EVuX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/llac9ezv6ecleamgj429.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KvM7EVuX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/llac9ezv6ecleamgj429.png" alt="Reset Dahua DH-IPC-HFW1300SP" width="880" height="387"&gt;&lt;/a&gt;&lt;br&gt;
Connected the holes marked in the picture for 30+s, and after some fiddling with the network settings of my computer, the Dahua configuration tool was able to connect the device 🎉.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fqWsvFfq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ugx711bwychhgvw2t171.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fqWsvFfq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ugx711bwychhgvw2t171.png" alt="The configuration tool" width="880" height="614"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Configuring the cameras
&lt;/h2&gt;

&lt;p&gt;Now it was just the matter of getting the right configuration persisted within the cameras, but for whatever the reason, that did not work with the configuration tool 🙈. The cameras still did not connect to Hikvision, and loading the IP configuration from the camera revealed that it was not saved:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fz48Q-RC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g747zt9qf2g6hk08y136.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fz48Q-RC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g747zt9qf2g6hk08y136.png" alt="No IP saved" width="600" height="316"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The web configuration tool
&lt;/h3&gt;

&lt;p&gt;I thought I had found a solution to the configuration tool not working when I just opened up the camera's IP address and discovered the cameras serve a web-based configuration interface, but there turned out to be one more obstacle on my way: the login screen had a nasty bug which cleared the form after every keystroke or moment, making me unable to insert "admin:admin" to the form 😠.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c6C7Uubm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c99a8pdfstwi1ultdwv9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c6C7Uubm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c99a8pdfstwi1ultdwv9.gif" alt="Web form not working" title="Can you can insert the credentials" width="621" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tried turning off Javascript, but the web-based tool functionality is written using &lt;a href="https://mootools.net/"&gt;Mootools&lt;/a&gt; and does not work with Javascript turned off. Also tried other browsers, even tested out with Internet Explorer, still no luck.&lt;/p&gt;
&lt;h3&gt;
  
  
  Professionally, I am a web developer 🤔
&lt;/h3&gt;

&lt;p&gt;It took me some time, but I did find a way to submit the form! I wrote Javascript functions to submit the forms in one shot without letting some buggy callback to clear the form meanwhile 😎.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZXyryamf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hvrkz7ud9hp00k4zdcv1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZXyryamf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hvrkz7ud9hp00k4zdcv1.png" alt="The login function" width="875" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same bug was present within the web tool itself, once logged in, but now I already knew how to tackle this problem. This is the call to get the configuration saved to the device when navigated to the right page:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;configure&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcpip_v4_address_0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;192&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcpip_v4_address_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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;168&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcpip_v4_address_2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;254&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcpip_v4_address_3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;12&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcpip_v4_subnet_mask_0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;255&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcpip_v4_subnet_mask_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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;255&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcpip_v4_subnet_mask_2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;255&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcpip_v4_subnet_mask_3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&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="nx"&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;tcpip_v4_gateway_0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;192&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcpip_v4_gateway_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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;168&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcpip_v4_gateway_2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;254&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcpip_v4_gateway_3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&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;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcpip_confirm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;click&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;You might be thinking the CSS selectors within the jQuery function are not correct, but this is not jQuery, this is Mootools 🤓&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Hikvision setup
&lt;/h2&gt;

&lt;p&gt;From there it was just the matter of plugging the cameras to the Hikvision NVR and configuring them as needed 😊.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Lg5QDhwY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/eazxlrho51r1lhdncm7v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Lg5QDhwY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/eazxlrho51r1lhdncm7v.jpg" alt="Hikvision setup screen" width="880" height="660"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P3BRDFWg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xh73d3u39iexvgigcjfx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P3BRDFWg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xh73d3u39iexvgigcjfx.jpg" alt="Cameras working" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Aftermath
&lt;/h2&gt;

&lt;p&gt;The whole process of getting the cameras connected to the NVR took me about 5 hours. I had many moments where I did not have enough equipment or information and thought I was stuck for good. When I finally succeeded at about 2AM, I could not believe it. I still have my mind blown on how I had to collect the hints from all over the internet, how much luck I had, and how many different skills I had to put to use in order to succeed.&lt;/p&gt;

&lt;p&gt;💡 Never ever expect devices from different manufacturers to just plug-and-play. And never give up 💪&lt;/p&gt;

&lt;p&gt;Have fun!&lt;/p&gt;

</description>
      <category>camera</category>
      <category>poe</category>
      <category>troubleshooting</category>
    </item>
  </channel>
</rss>
