<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.1">Jekyll</generator><link href="https://sumitbirla.me/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sumitbirla.me/" rel="alternate" type="text/html" /><updated>2026-06-06T14:31:32-04:00</updated><id>https://sumitbirla.me/feed.xml</id><title type="html">Sumit Birla</title><subtitle>Random blog posts and musings.</subtitle><author><name>Sumit Birla</name><email>inquiries@sumitbirla.me?subject=Email from sumitbirla.me</email></author><entry><title type="html">блог на русском языке</title><link href="https://sumitbirla.me/2022/12/learning-russian-language/" rel="alternate" type="text/html" title="блог на русском языке" /><published>2022-12-09T00:00:00-05:00</published><updated>2022-12-09T00:00:00-05:00</updated><id>https://sumitbirla.me/2022/12/learning-russian-language</id><content type="html" xml:base="https://sumitbirla.me/2022/12/learning-russian-language/"><![CDATA[<p>Всем привет и добро пожаловать в мой блог на русском языке. Я пишу это для практики. Я начал изучать русский язык год назад. Люди часто спрашивают меня - почему я учу этот язык, а не французский или немецкий. Есть несколько причин.</p>

<ol>
  <li>Я люблю путешествовать. Я хочу поехать в страны когда-нибудь, где люди говорят по-русски -
Россия, Украина, Беларусь, Узбекистан, Грузия, Азербайджан и другие.</li>
  <li>В мире более 200 миллионов человек говорят на русском языке.</li>
  <li>Изучение нового языка — это вызов для меня</li>
</ol>

<p>Я думаю, что русский язык труден для изучения. Как бы я хотел,  что начать когда был маленьким. Я надеюсь, что однажды я смогу говорить с людьми на их языке.</p>

<p>Немного информации о себе - Меня зовут Сумит, я живу в Тампе. Я люблю путешествовать, фотографировать и технологии. Из этого блога вы можете узнать, что мне также нравится узнавать о других культурах и пробовать разные кухни.</p>

<p>Это все. Желаю всем счастливого нового года.</p>

<p>Пока-пока!</p>]]></content><author><name>Sumit Birla</name></author><summary type="html"><![CDATA[Всем привет и добро пожаловать в мой блог на русском языке. Я пишу это для практики. Я начал изучать русский язык год назад. Люди часто спрашивают меня - почему я учу этот язык, а не французский или немецкий. Есть несколько причин.]]></summary></entry><entry><title type="html">DIY Level 2 EV Charger Build</title><link href="https://sumitbirla.me/2022/01/diy-ev-charger-build/" rel="alternate" type="text/html" title="DIY Level 2 EV Charger Build" /><published>2022-01-25T00:00:00-05:00</published><updated>2022-01-25T00:00:00-05:00</updated><id>https://sumitbirla.me/2022/01/diy-ev-charger-build</id><content type="html" xml:base="https://sumitbirla.me/2022/01/diy-ev-charger-build/"><![CDATA[<figure class="third ">
  
    
      <a href="/assets/images/2022/01/EVSE-1.jpg" title="J1772 Connector and Panel in background">
          <img src="/assets/images/2022/01/EVSE-1.jpg" alt="" />
      </a>
    
  
    
      <a href="/assets/images/2022/01/EVSE-2.jpg" title="Connected to Nissan LEAF">
          <img src="/assets/images/2022/01/EVSE-2.jpg" alt="" />
      </a>
    
  
    
      <a href="/assets/images/2022/01/EVSE-3.jpg" title="EVSE Info Display">
          <img src="/assets/images/2022/01/EVSE-3.jpg" alt="" />
      </a>
    
  
  
</figure>

<p>Let’s start off by correcting a popular misconception - a level 2 “EV Charger” does not actually
perform the function of charging your car’s battery pack.   Instead it simply advertises that
maximum AC current it can supply and engages a contactor/relay when the car is ready.   The actual
charging circuitry resides within the car. The correct term for these home chargers is <em>Electric
Vehicle Supply Equipment</em> (EVSE).  It’s only job is to deliver power in a safe manner.</p>

<p>My initial plan when I purchased my Nissan LEAF was to buy an EVSE on Amazon and have an
electrician install it for me.   Looking at the features of various devices,  I was a bit irritated
at the “smart features” which required a WiFi connection and an app or browser to configure.  I
assumed a simple home charger would be a passive device what would just work when plugged-in.   No
high-tech complications required.  In fact,  my car came with such a device,  but it only charges at
1kW which is too slow if I intend to drive every day.</p>

<p>Doing some more research,  I learnt how the J1772 connector actually functions.  Understanding it
isn’t difficult if you are electrically-savvy.   You can find the details here:</p>

<p><img src="/assets/images/2022/01/J1772_CCS1.svg_.png" alt="SAE J1772 Connector" class="align-right" width="150" /></p>

<p>Only the top portion of the connector is used for Level 2 charging. The DC+ and DC- pins are for
fast charging at 50kW or more and are part of the CCS standard.</p>

<p>On the J1772 connector, three out of the 5 pins simply deliver 240VAC (L1, N + PE) to the car. The
additional two pins: Proximity Pilot (PP) and Control Pilot (CP) are involved in letting the car
know when the cable is connected and how much power the EVSE can deliver.</p>

<p>Delivering power to the L1, N and PE pins doesn’t require any sophisticated electronics. All you
need is a circuit-breaker (GFCI preferably) and a contactor. The circuit breaker prevents the car
from drawing too much current and also protects against short circuits. The PP pin functionality is
built into the J1772 handle. The last piece of the puzzle is the CP pin. This pin provides a PWM
signal to the car indicating how many amps the EVSE can deliver. For this, I used a ready-made
device from Viridian called EVSE Protocol Controller. Its job is to communicate with the car to set
a charging current limit. Once the car is ready (it informs its status by changing voltage on the CP
pin), it turns on the contactor so that current can start flowing.</p>

<p><img src="/assets/images/2022/01/IMG_4246-2.jpeg" alt="Circuit Assembly" /></p>

<p>As you can see from the diagram below, the system is fairly simple in theory (this schematic is for
communicating the general idea only and is missing some connections).</p>

<p><img src="/assets/images/2022/01/EVSE_Diagram-2.png" alt="Circuit Diagram" /></p>

<p>There are some areas that need to be paid special attention:</p>

<p>The system is designed to deliver a maximum of 32 amps. So the use of adequate gauge wire to handle
the load is essential. Otherwise, you could overheat the wires and start a fire. I ended up using
10AWG (6 mm2) wires in my control panel and 8AWG (10 mm2) wires to bring power to the panel itself.
Use a circuit breaker with GFCI protection. In most countries, you would have a 240V live wire and a
Neutral, however in the USA, you have two live wires. So make sure your breaker is designed to work
in a split-phase system which breaks contact on both wires.  Make sure your contacts are solid. Use
ferrules any time you have stranded wires.  Use certified products only (UL listed or CE) I happened
to have a control panel already installed in my garage. It is used in my other home automation
projects. However, you could buy an enclosure for a project such as this and mount the components on
a DIN rail.</p>

<p>In the video above, you see that I am able to control the charge current also. I have two settings –
a slow charge (1.8kW) and normal charge at (7.7kW). This is accomplished by connecting a 220Ω
resister between the 0V and IC pins. Since I have a PLC nearby, I used a relay on it to connect and
disconnect the resistor as needed.</p>

<p><img src="/assets/images/2022/01/charge-rate-control.png" alt="Charge Current Control" class="align-center" /></p>

<p>The rest of the project involved programming the existing PLC and HMI in the control panel to
display the stats on the screen. There is also a AC current transducer that is used to collect the
energy delivered information.</p>]]></content><author><name>Sumit Birla</name><email>inquiries@sumitbirla.me?subject=Email from sumitbirla.me</email></author><category term="DIY" /><category term="Electric" /><summary type="html"><![CDATA[How I built my own EV charger using off-the-shelf components.]]></summary></entry><entry><title type="html">How I Tamed My Swimming Pool</title><link href="https://sumitbirla.me/2020/05/how-i-tamed-my-swimming-pool/" rel="alternate" type="text/html" title="How I Tamed My Swimming Pool" /><published>2020-05-15T00:00:00-04:00</published><updated>2020-05-15T00:00:00-04:00</updated><id>https://sumitbirla.me/2020/05/how-i-tamed-my-swimming-pool</id><content type="html" xml:base="https://sumitbirla.me/2020/05/how-i-tamed-my-swimming-pool/"><![CDATA[<p>One of the joys of living is Florida is having a swimming pool in the backyard. All that sunshine,
warm weather is perfect for water activities. Or so I thought.</p>

<p>In reality, if you are not paying attention to your pool, it can go haywire fairly quickly. It 
takes only couple of hot days or rainstorms to turn the pool
green. You end up spending a lot on chemicals before you get to see sparkling blue water again. By
that time you are fed up and probably don’t want to go in the pool at all.</p>

<p>One of the biggest frustrations for me has been the difficulty in finding authoritative information
about pool chemistry. Do a search on Google for any pool related question, the first 50 results are
all from companies trying to sell their products. Then there are forums with self-professed 
experts. “I have been in the industry for 30 years so I know what I am talking about”. There 
appears to be a phenomenon online which turns everyone into experts. The herd seems to keep peddling 
the same “truths.”</p>

<p>It all began earlier this year (2020) when I noticed my pool was the color of bright emerald green.
One couldn’t see the floor of the pool at all. So what is one to do? I checked the pH and total
alkalinity. I brought them into acceptable range by adding Hydrochloric acid (HCl) and Sodium
Bicarbonate (NaHCO₃) respectively. Then I went and purchased 10 gallons of liquid chlorine and
shocked the pool repeatedly. This killed some of the algae, but the pool was still light green. I
took a sample to the local pool store and they told me that cyanuric acid (CYA) level was too high
in the pool. I did my own test and it indicated the level was too low! 🤔 Who to believe? (Bottom
line - my test was correct).</p>

<p>Fast forward, after months of adding chemicals, the pool was looking clearer. But when I would brush
the floor, there still appeared to be some yellow algae present. It seemed that it was immune to
chlorine. I kept shocking the pool, but the stubborn algae refused to disappear.</p>

<p>So began my Internet research to find possible cause. Everyone was pretty much regurgitating the
same conventional wisdom - keep adding more chlorine. Then by chance I came across “pool ionizers”
which generate copper ions (Cu²⁺) which are considered powerful disinfectants. They are effective
against all types of algae and many bacteria. In fact, NASA has used Copper and Silver ions to
disinfect drinking water in space[4]. But our herd of Internet experts kept repeating the same
mantra - 1) it is dangerous to humans, 2) it stains your pool, 3) turns your hair green, 4) you
still need chlorine to sanitize.</p>

<p>All of the points above are valid, except that they leave out the fact that it is perfectly safe in
small amounts. The acceptable level of copper in drinking water is 2 ppm. A pool requires only 0.3
ppm - 0.5 ppm concentration to kill most algae and bacteria in the pool. Also at this concentration,
there is no staining of pool liner. Furthermore, unlike Chlorine, Cu²⁺ level does not drop that
fast. It stays in the water longer and keeps working. Of course, you must still test regularly to
make sure the concentration is in the acceptable range. Also for maximum efficacy, pH must be
between 7.2 and 7.6 and total alkalinity around 100ppm. You would have to maintain these levels with
a Chlorine-based system also.</p>

<p><img src="/assets/images/2020/05/copper-sulphate-1.jpg" alt="Copper Sulphate" class="align-right" width="200" /> Now
comes the big revelation. Should I buy a pool ionizer for $500 - $600? NO! You can buy some very
pretty copper sulphate pentahydrate (CuSO<sub>4</sub>.5H<sub>2</sub>O) for around $5 for a small
quantity (4 oz). That’s all you really need. This chemical has been used since the 19th century for
disinfecting. I have used it in high school for electro-plating experiments. Thankfully no one told
me back then that I would get metal poisoning if I touched the chemical. But I turned out
<strong>O</strong>blerpl..3,14;<strong>K</strong> 🤪. I think.</p>

<p>Let’s calculate how much Copper Sulphate you need. Say you have a 50,000 liter pool (yes, we are
going to stick to Metric system). We need to raise the Cu²⁺ ion concentration by 0.3 ppm if you are
starting from zero.</p>

<p><code class="language-plaintext highlighter-rouge">Copper -  63.546 g/mole    CuSO4.5H2O - 249.69 g/mol</code></p>

<p>So 1 kg of the blue powder has 63.546 / 249.69 = 0.255 <strong>kg</strong> of elemental copper.</p>

<p>As you know 1 liter of water has a mass of 1 kg. So to achieve an increase of 0.3 ppm elemental Cu
in the 50,000 kg pool, we need to add 0.015 kg of elemental copper. To get this amount of elemental
copper from blue powder - 0.015 / 0.255 = 0.058 kg or 58 grams.</p>

<p>So there you have it, add less than 60 grams (2 oz.) of blue powder to achieve full disinfection of
your pool. Best way is to dissolve it in a bucket of water first and then spread it out in the pool.
After this you can let your chlorine level drop down to 0.5 ppm or so.</p>

<figure> <img src="/assets/images/2020/05/IMG_3568.jpeg" /> <figcaption>Measure copper
sulphate</figcaption> </figure>

<figure class="aligncenter"> <img src="/assets/images/2020/05/IMG_3573.jpeg" /> <figcaption>Dissolve
in bucket and disperse in pool</figcaption> </figure>

<p>The very next day after I added copper sulphate to the pool, the stubborn yellow algae was gone and
the pool was blue again. I have let chlorine levels drop to around 0.5 ppm. So far the pool is
holding, there are no stains, no one has turned green - so all good.</p>

<p><strong>Did you know</strong>? copper sulphate is sold in many different forms. Algaecides, “Root Kill” etc. Look
at the ingredients - they all have the same stuff, but sell at different prices. Just get 99% pure
copper sulphate online - it will be super cheap and you have to use it sparingly. One thing to do is
invest in a good copper test kit [3].</p>

<figure> <img src="/assets/images/2020/05/IMG_3571-1.jpeg" /> <figcaption>Active ingredient in root
kill is Copper Sulphate</figcaption> </figure>

<p><strong style="color: red;">WARNING</strong> - you will be tempted to Google “How to Add Copper
Sulfate to Pools”. The very first hit tells you to add 2 lbs to 6 lbs of the chemical to your pool.
DON’T DO IT!! That is super-dangerous, overkill amount.</p>

<h3 id="references">REFERENCES</h3>

<div style="font-size: 0.7em;">
1. <i><a href="https://www.nitt.edu/home/students/facilitiesnservices/sportscenter/swimmingpool/SwimmingPoolMaintenance.pdf">Swimming
Pool Maintenance Steps to remove algae in swimming pools.</a></i> National Institute of Technology,
Tiruchirappalli.<br />
2. Yahya, M.T., Landeen, L.K., Kutz, S.M., Gerba, C.P., <i><a href="https://www.jstor.org/stable/pdf/44533962.pdf">Swimming Pool Disinfection: An Evaluation of
the Efficacy of Copper/Silver Ions.</a></i> Journal of Environmental Health 51:282-285, 1989.<br />
3. <a href="https://www.lamotte.com/en/pool-spa/kits-reagents/specialty-test-kits/3619.html">LaMotte
Copper Test Kit</a><br />
4. <a href="https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20020083175.pdf">NASA Article on
Water Purification</a><br />
5. Guido Socher, <i><a href="http://tuxgraphics.org/common/src2/article11081/low-chlorine-pool/">Low chlorine pool care</a></i>. tuxgraphics.org, 2011.
&lt;/dev&gt;
</div>]]></content><author><name>Sumit Birla</name></author><summary type="html"><![CDATA[One of the joys of living is Florida is having a swimming pool in the backyard. All that sunshine, warm weather is perfect for water activities. Or so I thought.]]></summary></entry><entry><title type="html">Home Automation Philosophy</title><link href="https://sumitbirla.me/2020/04/home-automation-philosophy/" rel="alternate" type="text/html" title="Home Automation Philosophy" /><published>2020-04-22T11:11:47-04:00</published><updated>2020-04-22T11:11:47-04:00</updated><id>https://sumitbirla.me/2020/04/home-automation-philosophy</id><content type="html" xml:base="https://sumitbirla.me/2020/04/home-automation-philosophy/"><![CDATA[<p>In order to build a reliable and long-lasting system, I try to follow these rules:</p>

<h4 id="1-fixed-wires-for-fixed-devices">1. Fixed wires for fixed devices</h4>

<p>If a home automation device doesn’t move around and is fixed in place, run wires to it from central controller. This method is more reliable than wireless setups and eliminates the need for batteries. This applies to both sensors and actuators.</p>

<h4 id="2-no-high-level-programming-for-low-level-control">2. No high level programming for low-level control</h4>

<p>Do not use high level programming platforms running on general-purpose computers to control devices such as thermostats and irrigation systems. Implement core logic on the controller device itself so that it continues to operate normally even if network is not available.</p>

<h4 id="3-avoid-cloud-connected-devices">3. Avoid cloud-connected devices</h4>

<p>Make sure your home automation continues to operate normally even when Internet is not available or a manufacturer of a device goes out of business. If you do need to push data to the cloud, use an auxiliary gateway device.</p>

<h4 id="4-avoid-proprietary-technology">4. Avoid proprietary technology</h4>

<p>Implement everything using interoperable standards. For example, use MQTT or Modbus for communication rather than a proprietary API.</p>

<h4 id="5-no-loose-wires">5. No loose wires</h4>

<p>Use DIN-rail mounted components when possible. Use terminal blocks and avoid custom-built circuits. When possible, use industrial components which tend to be well documented, certified and of high quality.</p>

<h4 id="6-learn-underlying-principles">6. Learn underlying principles</h4>

<p>For any device you wish to control, understand how it works. For example, a thermostat is essentially 3-4 relays that turn on based on input from a temperature sensor. There is no magic happening in your “Smart Thermostat.”</p>

<h4 id="7-keep-cost-low">7. Keep cost low</h4>

<p>Determine what you need and then monitor Amazon, eBay and AliExpress for lowest price. It may take many days for a deal to pop-up, but they do eventually show up.</p>

<h4 id="8-document-everything">8. Document everything</h4>

<p>One day when your memory starts failing and you need to modify behavior of a device, make sure you have enough documentation to be able to do so.</p>

<hr />

<h2 id="example">Example</h2>

<p>Say you want to replace your old-school thermostat with something you can control remotely:</p>

<h4 id="understand-how-thermostats-work"><strong>Understand how thermostats work</strong></h4>

<p>This diagram explains very clearly what role a thermostat plays in controlling your HVAC system:</p>

<figure>
	<img src="/assets/images/2020/04/thermostat_wiring.png" />
	<figcaption>The circle is your thermostat[^1]</figcaption>
</figure>

<p>Essentially you need 3 relays which need to be turned ON or OFF based on temperature set-point. Your HVAC systems has a 24VAC transformer. You simply need to pass this signal (available on Red wire) on to Green wire for blower, Yellow for compressor and White for heater.</p>

<h4 id="select-hardware-to-implement-this-functionality"><strong>Select hardware to implement this functionality</strong></h4>

<p>A Siemens LOGO! or a CLICK PLC<sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">1</a></sup> has all the prerequisites to implement a thermostat:</p>

<table class="">
  <tr>
    <td class="has-text-align-center" data-align="center">
      <img style="width: 250px;" src="/assets/images/2020/04/pv_c012dre1d_02.jpg" />
    </td>
    
    <td class="has-text-align-center" data-align="center">
      <img style="width: 300px;" src="/assets/images/2020/04/siemens-logo-plcOBA8.jpg" />
    </td>
  </tr>
</table>

<p>You could use any PLC really from a dozen different manufacturers, but I have invested time in learning the LOGO!, so that is what I analyze for this purpose:</p>

<table>
  <thead>
    <tr>
      <th>Function</th>
      <th> </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>✅ RELAYS</td>
      <td>4 relays available with maximum current of 10A. A thermostat typically needs to handle less than 2A</td>
    </tr>
    <tr>
      <td>✅ Analog Inputs</td>
      <td>0-10V analog inputs can be used to connect an industrial temperature sensor</td>
    </tr>
    <tr>
      <td>✅ Programming</td>
      <td>LOGO! is programmed using FBD. No spaghetti code possible.</td>
    </tr>
    <tr>
      <td>✅ Network</td>
      <td>Onboard ethernet that speaks Siemens S7 protocol or Modbus-TCP. Very convenient to interface with node-red or HomeAssistant.</td>
    </tr>
    <tr>
      <td>✅ COST</td>
      <td>This PLC typically sells for around $160, however you are plenty of used ones available on eBay. I got mine at AliExpress for $67.</td>
    </tr>
  </tbody>
</table>

<p>Sure you can implement the same functionality using a ESP8266, Arduino or a Raspberry Pi. But I have written another article<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup> about why I would not use these devices for such purposes.</p>

<p><strong>Footnotes:</strong></p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:3" role="doc-endnote">
      <p><a href="https://www.automationdirect.com/adc/shopping/catalog/programmable_controllers/click_series_plcs_(stackable_micro_brick)">Click PLC at Automation Direct</a> <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p><a href="https://sumitbirla.me/2020/01/using-plc-for-home-automation">Using PLC for Home Automation</a> <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Sumit Birla</name></author><category term="Home Tech" /><summary type="html"><![CDATA[In order to build a reliable and long-lasting system, I try to follow these rules:]]></summary></entry><entry><title type="html">My Pool Control Panel</title><link href="https://sumitbirla.me/2020/01/my-pool-control-panel/" rel="alternate" type="text/html" title="My Pool Control Panel" /><published>2020-01-17T11:30:23-05:00</published><updated>2020-01-17T11:30:23-05:00</updated><id>https://sumitbirla.me/2020/01/my-pool-control-panel</id><content type="html" xml:base="https://sumitbirla.me/2020/01/my-pool-control-panel/"><![CDATA[<p>This blog post describes my PLC-based pool controller panel.  It is a complete replacement of the existing electrical panel.   I built this as a learning-experience project in Industrial Automation techniques.   I have used a PLC and other DIN-rail mounted components such as contactors and circuit-breakers to achieve the same functionality as the existing panel.  Furthermore because I am using a network-connected PLC,  I can remotely control and monitor the status of my pool pump.<figure class="wp-block-table aligncenter is-style-stripes"></figure></p>

<table class="">
  <tr>
    <td>
      <img class="wp-image-1231" style="width: 300px;" src="/assets/images/2020/01/IMG_2229.jpg" alt="" />
    </td>
    
    <td>
      →
    </td>
    
    <td>
      <img class="wp-image-1232" style="width: 300px;" src="/assets/images/2020/01/IMG_2331.jpg" alt="" />
    </td>
  </tr>
  
  <tr>
    <td>
      Existing panel with mechanical timer
    </td>
    
    <td>
    </td>
    
    <td>
      New PLC based control panel
    </td>
  </tr>
</table>

<p>As you can see above, the new panel looks quite a bit different. But many of the components are the same. For example, the circuit-breakers for the pool pump (16A), heater (50A) and one for an electrical outlet (16A) mirror the old installation. Instead of a mechanical timer, I now use a PLC. The benefit of using a PLC (other than being just plain fun to learn to use) is that I can set a separate pump schedule for each day of the week. Because the PLC has an ethernet connection, I can add the control panel to my larger home automation network and turn pump on/off remotely. At some point in the future, I plan to add sensors to read pH and water temperature since the PLC already has inputs to handle these.</p>

<hr />

<h3 id="bill-of-materials">Bill of Materials</h3>

<table>
  <thead>
    <tr>
      <th>Item</th>
      <th>Qty</th>
      <th>Price</th>
      <th>Source</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Siemens LOGO! 12/24 RCE</td>
      <td>1</td>
      <td>$70</td>
      <td>AliExpress</td>
    </tr>
    <tr>
      <td>Altelix NEMA Enclosure 17x14x6</td>
      <td>1</td>
      <td>$80</td>
      <td>Amazon</td>
    </tr>
    <tr>
      <td>Mean Well DR-15-24 Power Supply, 24 Volt, 0.63 Amp</td>
      <td>1</td>
      <td>$13</td>
      <td>Amazon</td>
    </tr>
    <tr>
      <td>Baomain AC Contactor HC1-63 110V 63A 2 Pole</td>
      <td>1</td>
      <td>$17</td>
      <td>Amazon</td>
    </tr>
    <tr>
      <td>uxcell 1 Pole 50A 230/400V Miniature Circuit Breaker</td>
      <td>1</td>
      <td>$9</td>
      <td>Amazon</td>
    </tr>
    <tr>
      <td>uxcell 1 Pole 16A 230/400V Miniature Circuit Breaker</td>
      <td>2</td>
      <td>$9</td>
      <td>Amazon</td>
    </tr>
    <tr>
      <td>DIN Rail Terminal Blocks, 6-20 AWG, 60 Amp</td>
      <td>1</td>
      <td>$30</td>
      <td>Amazon</td>
    </tr>
    <tr>
      <td>CHINT NP9 push button switch card DIN rail button (red &amp; green)</td>
      <td>2</td>
      <td>$5</td>
      <td>AliExpress</td>
    </tr>
    <tr>
      <td>12 Gauge Silicone wire 10 ft red and 10 ft black</td>
      <td>1</td>
      <td>$11</td>
      <td>Amazon</td>
    </tr>
    <tr>
      <td>Ferrule Crimping Tool Kit</td>
      <td>1</td>
      <td>$26</td>
      <td>Amazon</td>
    </tr>
    <tr>
      <td>DIN Rail 250mm<em>35mm</em>7.5mm Steel (10-Pak)</td>
      <td>1</td>
      <td>$14</td>
      <td>eBay</td>
    </tr>
    <tr>
      <td> </td>
      <td> </td>
      <td> </td>
      <td><strong>~$300</strong></td>
    </tr>
  </tbody>
</table>

<h3 id="programming">Programming</h3>

<p>Although Ladder Logic is the most common way to program in the automation world, I used Function Block Diagram (FBD) just because there seems to be more support online for this method of programming for the Siemens LOGO!</p>

<p><img src="/assets/images/2020/01/PoolPumpSoftware.png" alt="" class="wp-image-1185" /></p>

<ul>
  <li><a href="/assets/images/2020/08/Pool-Pump-Control.lsc">Download</a> the program (open using LOGO! Soft Comfort)</li>
  <li><a rel="noreferrer noopener" aria-label="PDF Version (opens in a new tab)" href="/assets/images/2020/01/Pool-Pump-Control.pdf" target="_blank"><u>PDF Version</u></a> – for viewing if you don’t have LOGO software</li>
</ul>]]></content><author><name>Sumit Birla</name></author><category term="Home Automation" /><category term="Swimming Pool" /><summary type="html"><![CDATA[This blog post describes my PLC-based pool controller panel.  It is a complete replacement of the existing electrical panel.   I built this as a learning-experience project in Industrial Automation techniques.   I have used a PLC and other DIN-rail mounted components such as contactors and circuit-breakers to achieve the same functionality as the existing panel.  Furthermore because I am using a network-connected PLC,  I can remotely control and monitor the status of my pool pump.]]></summary></entry><entry><title type="html">Using PLC for Home Automation</title><link href="https://sumitbirla.me/2020/01/using-plc-for-home-automation/" rel="alternate" type="text/html" title="Using PLC for Home Automation" /><published>2020-01-06T13:01:09-05:00</published><updated>2020-01-06T13:01:09-05:00</updated><id>https://sumitbirla.me/2020/01/using-plc-for-home-automation</id><content type="html" xml:base="https://sumitbirla.me/2020/01/using-plc-for-home-automation/"><![CDATA[<blockquote>
  <p>This post is not meant to teach you what a PLC is. If you are unfamiliar with it, I suggest you 
make a quick read of the following before returning to this page: 
<a href="https://www.amci.com/industrial-automation-resources/plc-automation-tutorials/what-plc/">What is a
PLC?</a></p>
</blockquote>

<p>Automating routine tasks around the house has been a goal of mine for as long as I can remember. Examples of such tasks are:</p>

<ul>
  <li>Turn on outdoor lights at dusk and turn them off at dawn</li>
  <li>Turn off HVAC when no one is at home</li>
  <li>Turn off closet lights automatically 30 minutes after being turned on</li>
  <li>Turn off the sprinkler system when it has rained</li>
</ul>

<p>In addition to controlling “things” I also want to be able read data from sensors
remotely. Example of such sensors are: temperature, humidity, electricity consumption, water-flow, doors/windows status etc.</p>

<p>Ideally all “smart devices” have a local human interface and are also controllable over a network (WiFi, Ethernet, Zigbee, Z-Wave, RS485 etc.) Network control allows one to build higher-level dashboards with big touchscreens and also interface with voice assistants such as Alexa and Google Home. Couple of popular software options for building interfaces are Node Red and HomeAssistant.</p>

<p>The problem with deploying “smart devices” has always been related to reliability (remember X10), proprietary nature of the products and just plain poor implementation. There is no way I am going to install a proprietary App to control a light bulb! There are a few checkboxes that need to be ticked for a “smart home” device to be incorporated:</p>

<table>
  <thead>
    <tr>
      <th> </th>
      <th> </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>NON_SMART_MODE</td>
      <td>It should work as a standard “non-smart” device also.</td>
    </tr>
    <tr>
      <td>NETWORKED</td>
      <td>Should be controllable over a data network, but not depend on it. I.e. all logic necessary to operate must exist on the device itself. Device should be unaffected by network failures.</td>
    </tr>
    <tr>
      <td>RELIABILITY</td>
      <td>Will the device still function in 10 years not requiring an upgrade or reboot?</td>
    </tr>
    <tr>
      <td>MAINTAINABILITY</td>
      <td>Can someone other than me troubleshoot in case a device stops working? Are industry-standard protocols and techniques used.</td>
    </tr>
    <tr>
      <td>COST</td>
      <td>Should not cost an exorbitant amount, after all this is probably a hobby project for you.</td>
    </tr>
  </tbody>
</table>

<p>As far as hardware goes, the popular choices are Arduino, ESP8266-based boards and Raspberry Pi. In
fact such a large portion of the Home Automation enthusiast community uses one of these platforms,
that it will be difficult for you to find sample code or help if you use anything else. On
message-boards, you are unlikely to find anyone recommending the use of PLCs.</p>

<figure class="third ">
  
    
      <a href="/assets/images/2020/01/Arduino_Uno_-_R3.jpg" title="Arduino Uno R3">
          <img src="/assets/images/2020/01/Arduino_Uno_-_R3.jpg" alt="" />
      </a>
    
  
    
      <a href="/assets/images/2020/01/D1-Mini-Board-800x800.jpg" title="D1 Mini (ESP8266)">
          <img src="/assets/images/2020/01/D1-Mini-Board-800x800.jpg" alt="" />
      </a>
    
  
    
      <a href="/assets/images/2020/01/800px-Raspberry_Pi_3_B_39906369025.png" title="Raspberry Pi 3B">
          <img src="/assets/images/2020/01/800px-Raspberry_Pi_3_B_39906369025.png" alt="" />
      </a>
    
  
  
</figure>

<p>Granted that Arduino has been a huge step up in terms of rapid prototyping and has led to really fascinating projects being built by people with little electrical engineering background. A quick Google search will show you basically anything you want to build, someone has already done it and posted their schematic and code online. But my question always comes back to its longevity. Past the fun-build stage, will I enjoy maintaining it? If I am not around, will anyone be able to make heads or tails of what I have built? Does it actually simplify my everyday routine in someway, or just add another thing that needs to be maintained?</p>

<h2 id="why-plc">Why PLC?</h2>

<p>Well, let’s see how the various devices fare when it comes to the above-listed criteria:</p>

<table>
  <thead>
    <tr>
      <th> </th>
      <th>Arduino</th>
      <th>ESP8266</th>
      <th>Raspberry PI</th>
      <th>PLC</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>NETWORKED</td>
      <td>❌</td>
      <td>✅</td>
      <td>✅</td>
      <td>✅</td>
    </tr>
    <tr>
      <td>RELIABILITY</td>
      <td>❌</td>
      <td>❌</td>
      <td>❌</td>
      <td>✅</td>
    </tr>
    <tr>
      <td>MAINTAINABILITY</td>
      <td>❌</td>
      <td>❌</td>
      <td>❌</td>
      <td>✅</td>
    </tr>
    <tr>
      <td>COST</td>
      <td>✅</td>
      <td>✅</td>
      <td>✅</td>
      <td>❌</td>
    </tr>
  </tbody>
</table>

<p>I think the table above probably has caused some disagreements in your mind. Especially ones related
to “reliability” and “maintainability”. Let me give you simple example: you have a networked esp8266 switch that turns ON/OFF your pool pump motor. You have soldered a bunch of wires to relays and one day it does not turn on. What do you do about it? Will someone other than you be able to resolve this issue? Is it a software problem or hardware?</p>

<p>I have been running Node-Red at home which does a whole bunch of functions. Everything from sending signals to turn ON/OFF lights to reading sensors. Some of the sensors are 433MHz sensors decoded using RTL dongle, some are Z-Wave and some are WiFi. Every now and then I am forced to update my Linux server because I need the update to be able to run some software. Guess what, WiFi AP may not come back online, certain Node-Red flows may fail until I address the underlying issue. The point is a seemingly benign operation on a computer may have unexpected effect with rest of the system. That is why you will never see a Windows or Linux directly controlling safety-critical industrial equipment.</p>

<p>Let’s look at an example PLC that I have chosen to use for some of my projects:</p>

<p><img src="/assets/images/2020/01/6ed1052-1cc08-0ba0-nfs.jpg" alt="Siemens LOGO! PLC" class="align-right" width="200" /></p>

<h4 id="siemens-logo-1224-rce">Siemens LOGO! 12/24 RCE</h4>

<ul>
  <li>Logic module with display</li>
  <li>Power supply: 12/24 VDC</li>
  <li>8 DI (Digital Input) 4 of which can be used as AI (Analog Inputs)</li>
  <li>4 DO (Digital Output) Relay</li>
  <li>Real Time Clock (RTC)</li>
  <li>Memory: 400 blocks</li>
  <li>modularly expandable</li>
  <li>Ethernet</li>
  <li>Integrated web server</li>
</ul>

<p>Notice the neatly packaged module. It has a built-in display with buttons for basic configuration. The 4 Relay output can be used to switch currents up to 2.0A each. There are 8 general purpose inputs, 2 of which can also take 0-10V analog input. 0-10V sensors are an industrial standard along with 4-20mA. Ethernet is built-in along with a web server for building Human Machine Interface (HMI). So for the price of a single PLC, you are getting quite a bit!</p>

<p>Why not pick a different brand of PLC like Allen-Bradley or Schneider Electric? Well, in my case the decision was made for me. Siemens LOGO! appears to be the only PLC whose programming software runs on Linux and Mac. Based on YouTube videos I have watched, I would say programming on most systems will be very similar, so I don’t feel like I have invested time in a brand-specific system.</p>

<p>Now, let’s look at the software. On Arduino, you use a subset of C programming language to control your hardware. You have to manage your own switch debounce, interrupts, logic-level shifting and power for driving delays. If you have any time-based scheduling function involved, you may also need to add an RTC. Also you are responsible for adding your own interface (buttons, displays etc.) How much time and cost do you think will be needed to add the above to a base-arduino? Will you have complete confidence in the functioning of the hardware once you are done with the project? Will you need to create a 3-D printed enclosure to neatly package your project? Again – calculate how much it will cost.</p>

<p>As a final point of the blog post, let’s talk about the software. On Arduino or Raspberry Pi, you can pretty much write code any way you like. Five years from now, will you remember what your code is doing? Will someone else be able to access your code (without access to you) and figure out the functionality?</p>

<p>For one of my first PLC projects, I created the program below using Functional Block Diagram (FBD). The more commonly accepted programming paradigm is Ladder Logic which I didn’t use for no particular reason. By showing you this program, I just want to give an idea how “high level” programming on a PLC is. Truly, you just have to worry about the logic. The low level details are taken care of by the CPU and related hardware.<figure class="wp-block-image size-large"></figure></p>

<p><img src="/assets/images/2020/01/PoolPumpSoftware.png" alt="Pool Pump Programming" /></p>

<p>This program is complete software for the control of my pool pump motor. It should be easy to understand to anyone with Industrial Automation background. Even if you don’t, it essentially boils down to basic digital logic. It is not hard to figure out what each block does by reading its documentation.</p>

<p><img src="/assets/images/2020/01/80759179_10156932012767076_649938223874703360_o.jpg" alt="Control Panel Internals" /></p>

<p>Above program implements the following functions:</p>

<ol>
  <li>Manual START / STOP buttons</li>
  <li>Network START / STOP functions</li>
  <li>Network SET / READ schedule</li>
  <li>Local Display to SET schedule</li>
  <li>Local Display to show current status and configuration</li>
</ol>

<p>As you see you can implement a robust solution with just a little extra cost upfront. It actually may turn out cheaper to use a PLC if you look for deals. For example, I bought mine for $66 on AliExpress.</p>

<p>If you think about it, there are a lot of appliances and devices around the house whose controlling circuitry are essentially single-purpose “PLC” under the hood:</p>

<ul>
  <li>Thermostat</li>
  <li>Sprinkler System Controller</li>
  <li>Pool Pump Controller</li>
  <li>Oven / Cooking Stove / Microwave</li>
  <li>Dishwasher / Clothes Washer / Dryer</li>
  <li>Coffee Machine</li>
  <li>Garage Door Opener</li>
</ul>

<p>What if all of the above were built using a general purpose PLC that you could connect to over the Ethernet and add remote control and diagnostics capabilities. That would be a home-automators dream!</p>

<h4 id="other-examples-of-plc-use">Other examples of PLC use</h4>

<ul>
  <li>Traffic Lights</li>
  <li>Elevators / Lift</li>
  <li>Theme park rides</li>
  <li>Automatic car wash</li>
</ul>

<p>When you are out and about, look for control panel enclosures with emergency stop buttons. You will
see how widespread PLC-based automation is.</p>]]></content><author><name>Sumit Birla</name></author><category term="DIY" /><summary type="html"><![CDATA[This post is not meant to teach you what a PLC is. If you are unfamiliar with it, I suggest you make a quick read of the following before returning to this page: What is a PLC?]]></summary></entry><entry><title type="html">Evolution of the Home Server</title><link href="https://sumitbirla.me/2016/11/evolution-of-the-home-server/" rel="alternate" type="text/html" title="Evolution of the Home Server" /><published>2016-11-21T11:12:32-05:00</published><updated>2016-11-21T11:12:32-05:00</updated><id>https://sumitbirla.me/2016/11/evolution-of-the-home-server</id><content type="html" xml:base="https://sumitbirla.me/2016/11/evolution-of-the-home-server/"><![CDATA[<p>Ever since broadband became available (around 1998), I have always run a general purpose Linux home server. I have used it as a router, a file server and to experiment with programming various things. The earliest servers were full-fledged tower computers, then I moved over to ITX form-factor and finally to an Intel NUC. While the Intel NUC is a very nice, compact and low power device, it only has one ethernet port. So I needed an additional network switch to connect my desktop, TV and printer. As many know, I am allergic to clutter comprising of cable, power supplies, and devices in general. Ideally, a single low power device should be able to do it all.</p>

<p>After a couple of years of running the Intel NUC, I finally found my close-to-ideal computer to act as the following:</p>

<ol>
  <li>Network Switch</li>
  <li>Router</li>
  <li>Wireless Access Point</li>
  <li>Network Attached Storage (NAS)</li>
  <li>Plex Media Server</li>
  <li>TV Tuner Streaming</li>
</ol>

<p>The little IBOX-N10a has 4 gigabit ethernet ports, two mSATA slots which I can use for SSD and wifi card. The device runs Intel Celeron J1900, Quad Core CPU at 2.00 GHz (turbo 2.4 GHz) and it is fanless with the chassis acting as a big heatsink. I have installed 4GB of RAM and a 1TB SSD from Samsung.</p>

<p><img src="/assets/images/2016/11/819cMXejIvL._SL1500_.jpg" alt="IBOX-N10a" /></p>

<ul>
  <li><a href="https://www.amazon.com/dp/B01MEGSMRZ">iBOX-N10A</a> fanless aluminium chassis</li>
  <li>Celeron J1900, Quad Core Bay Trail 2.0GHz (turbo 2.42GHz), 2MB L2 Cache, 10W TDP</li>
  <li>Intel 82583V Gigabit Ethernet – 4 ports</li>
  <li>Crucial 4GB Single DDR3L 1600 MT/s (PC3-12800) SODIMM 204-pin</li>
  <li>Samsung 850 EVO – 1TB – mSATA Internal SSD</li>
  <li>IMC Networks 802.11 n/g/b Wireless LAN USB Mini-Card</li>
  <li>APC Back-UPS Connect BGE90M – 3 hours backup power</li>
</ul>

<p>The output of `lspci` is shown below. It is fairly simply system with the Celeron J1900 processor providing 4 lanes of PCIe, each connected to a single Intel 82583V Gigabit Network chip. The integrated SATA II controller connects to the mSATA slot while the WIFI card uses the USB signal lines on the second mSATA slot.</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@ibox:~# lspci <span class="nt">-vt</span>
-[0000:00]-+-00.0  Intel Corporation Atom Processor Z36xxx/Z37xxx Series SoC Transaction Register
+-02.0  Intel Corporation Atom Processor Z36xxx/Z37xxx Series Graphics &amp;amp<span class="p">;</span>amp<span class="p">;</span>amp<span class="p">;</span> Display
+-13.0  Intel Corporation Atom Processor E3800 Series SATA AHCI Controller
+-1a.0  Intel Corporation Atom Processor Z36xxx/Z37xxx Series Trusted Execution Engine
+-1b.0  Intel Corporation Atom Processor Z36xxx/Z37xxx Series High Definition Audio Controller
+-1c.0-[01]----00.0  Intel Corporation 82583V Gigabit Network Connection
+-1c.1-[02]----00.0  Intel Corporation 82583V Gigabit Network Connection
+-1c.2-[03]----00.0  Intel Corporation 82583V Gigabit Network Connection
+-1c.3-[04]----00.0  Intel Corporation 82583V Gigabit Network Connection
+-1d.0  Intel Corporation Atom Processor Z36xxx/Z37xxx Series USB EHCI
+-1f.0  Intel Corporation Atom Processor Z36xxx/Z37xxx Series Power Control Unit
<span class="se">\-</span>1f.3  Intel Corporation Atom Processor E3800 Series SMBus Controller
</code></pre></div></div>

<p>The power consumption when idle is around 8W. When playing a HEVC x265 video via Plex requiring transcoding, the power usage jumps to 15W. The chassis still doesn’t get too hot. The rest of the applications (dnsmasq, samba, tvheadend) barely use any CPU.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@ibox:~# sensors
coretemp-isa-0000
Adapter: ISA adapter
Core 0:       +38.0°C  (high = +105.0°C, crit = +105.0°C)
Core 1:       +38.0°C  (high = +105.0°C, crit = +105.0°C)
Core 2:       +40.0°C  (high = +105.0°C, crit = +105.0°C)
Core 3:       +40.0°C  (high = +105.0°C, crit = +105.0°C)
</code></pre></div></div>

<p>I am currently running Ubuntu 16.04 LTS Server on this box as the base operating system. dnsmasq acts as DHCP server and caching DNS. hostapd provides the wireless access point functionality. Samba turns the system into a file server while Plex and tvheadend handle the media functions. Plex is able to stream my videos directly to Samsung Smart TV which has a Plex client built in. tvheadend takes the input from the USB TV tuner and makes broadcast channels available over the network much like the hdhomerun devices. With all this software running, the system only uses around 300MB of RAM (out of 4GB). So I am confident that this system to serve me well in the foreseeable future.</p>

<h3 id="product-and-installation-images">Product and installation images</h3>

<figure class="third ">
  
    
      <a href="/assets/images/2016/11/81hjCxFfW-L._SL1500_.jpg" title="Motherboard inside">
          <img src="/assets/images/2016/11/81hjCxFfW-L._SL1500_.jpg" alt="" />
      </a>
    
  
    
      <a href="/assets/images/2016/11/61CHJrmyZ6L._SL1074_.jpg" title="Rear ports">
          <img src="/assets/images/2016/11/61CHJrmyZ6L._SL1074_.jpg" alt="" />
      </a>
    
  
    
      <a href="/assets/images/2016/11/IMG_9254-682x1024.jpeg" title="Mounted on the wall">
          <img src="/assets/images/2016/11/IMG_9254-682x1024.jpeg" alt="" />
      </a>
    
  
  
</figure>]]></content><author><name>Sumit Birla</name></author><category term="Home Automation" /><category term="Linux" /><category term="Networking" /><category term="Technology" /><summary type="html"><![CDATA[Ever since broadband became available (around 1998), I have always run a general purpose Linux home server. I have used it as a router, a file server and to experiment with programming various things. The earliest servers were full-fledged tower computers, then I moved over to ITX form-factor and finally to an Intel NUC. While the Intel NUC is a very nice, compact and low power device, it only has one ethernet port. So I needed an additional network switch to connect my desktop, TV and printer. As many know, I am allergic to clutter comprising of cable, power supplies, and devices in general. Ideally, a single low power device should be able to do it all.]]></summary></entry><entry><title type="html">OpenSIPS #3: Basic Accounting</title><link href="https://sumitbirla.me/2016/03/opensips-basic-accounting/" rel="alternate" type="text/html" title="OpenSIPS #3: Basic Accounting" /><published>2016-03-20T22:27:07-04:00</published><updated>2016-03-20T22:27:07-04:00</updated><id>https://sumitbirla.me/2016/03/opensips-basic-accounting</id><content type="html" xml:base="https://sumitbirla.me/2016/03/opensips-basic-accounting/"><![CDATA[<p>With any phone system, you want to log the calls and certain details related to each call. You may do this to perform billing or generate reports of some kind. By default, OpenSIPS performs very basic logging of events. So for a given call, you may have numerous rows in database and you are supposed to match an INVITE with corresponding BYE (or cancel) event and determine the bill_duration. This is quite a bit of work as you can imagine a lot of things can go wrong between the INVITE and the BYE.</p>

<p>There is another way to log successful calls by using the <a href="http://www.opensips.org/html/docs/modules/2.1.x/dialog">dialog module</a> of OpenSIPS in conjunction with the standard <a href="http://www.opensips.org/html/docs/modules/2.1.x/acc">acc</a> (for accounting) module. Essentially, you create a database table that has columns that OpenSIPS expects by default. In addition you create columns for any additional information you would like to store per call. In my example below, I have chosen to store the src_user, src_domain, dst_user and dst_domain. You are free to store anything else if you prefer. You tell acc what to store in the “db_extra” parameter.</p>

<p>Once the module and database are configure, it is just a matter of setting the appropriate flag on INVITE and OpenSIPS will take care of the rest for you.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mysql&gt; describe acc;
+---------------+------------------+------+-----+---------+----------------+
| Field         | Type             | Null | Key | Default | Extra          |
+---------------+------------------+------+-----+---------+----------------+
| id            | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| method        | char(16)         | NO   |     |         |                |
| src_user      | varchar(64)      | YES  |     | NULL    |                |
| src_domain    | varchar(64)      | YES  |     | NULL    |                |
| dst_user      | varchar(64)      | YES  |     | NULL    |                |
| dst_domain    | varchar(64)      | YES  |     | NULL    |                |
| from_tag      | char(64)         | NO   |     |         |                |
| to_tag        | char(64)         | NO   |     |         |                |
| callid        | char(64)         | NO   | MUL |         |                |
| sip_code      | char(3)          | NO   |     |         |                |
| sip_reason    | char(32)         | NO   |     |         |                |
| time          | datetime         | NO   |     | NULL    |                |
| duration      | int(11) unsigned | NO   |     | 0       |                |
| setuptime     | int(11) unsigned | NO   |     | 0       |                |
| created       | datetime         | YES  |     | NULL    |                |
+---------------+------------------+------+-----+---------+----------------+
</code></pre></div></div>

<p>As always, the following script is for illustration purposes only. It has very few checks and may not work in your network setup. Pay attention to the use of DB_FLAG.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">####### Global Parameters #########
</span>
<span class="n">debug</span><span class="o">=</span><span class="mi">3</span>
<span class="n">log_stderror</span><span class="o">=</span><span class="n">no</span>
<span class="n">log_facility</span><span class="o">=</span><span class="n">LOG_LOCAL0</span>
<span class="n">fork</span><span class="o">=</span><span class="n">yes</span>
<span class="n">children</span><span class="o">=</span><span class="mi">2</span>
<span class="n">auto_aliases</span><span class="o">=</span><span class="n">no</span>

<span class="n">mhomed</span><span class="o">=</span><span class="mi">1</span>
<span class="n">listen</span><span class="o">=</span><span class="n">udp</span><span class="o">:</span><span class="mf">192.168.32.8</span><span class="o">:</span><span class="mi">5060</span>    <span class="err">#</span> <span class="n">LAN</span> <span class="n">Interface</span>
<span class="n">listen</span><span class="o">=</span><span class="n">udp</span><span class="o">:</span><span class="mf">6.7.8.9</span><span class="o">:</span><span class="mi">5060</span>   <span class="err">#</span> <span class="n">WAN</span> <span class="n">Interface</span>


<span class="cp">####### Modules Section ########
</span>
<span class="n">mpath</span><span class="o">=</span><span class="s">"/usr/lib/opensips/modules/"</span>

<span class="n">loadmodule</span> <span class="s">"signaling.so"</span>
<span class="n">loadmodule</span> <span class="s">"sl.so"</span>
<span class="n">loadmodule</span> <span class="s">"registrar.so"</span>
<span class="n">loadmodule</span> <span class="s">"proto_udp.so"</span>
<span class="n">loadmodule</span> <span class="s">"tm.so"</span>
<span class="n">loadmodule</span> <span class="s">"uri.so"</span>
<span class="n">loadmodule</span> <span class="s">"rr.so"</span>

<span class="n">loadmodule</span> <span class="s">"mi_fifo.so"</span>
<span class="n">modparam</span><span class="p">(</span><span class="s">"mi_fifo"</span><span class="p">,</span> <span class="s">"fifo_name"</span><span class="p">,</span> <span class="s">"/tmp/opensips_fifo"</span><span class="p">)</span>

<span class="n">loadmodule</span> <span class="s">"acc.so"</span>
<span class="n">loadmodule</span> <span class="s">"dialog.so"</span>
<span class="n">modparam</span><span class="p">(</span><span class="s">"acc"</span><span class="p">,</span> <span class="s">"db_flag"</span><span class="p">,</span> <span class="s">"DB_FLAG"</span><span class="p">)</span>
<span class="n">modparam</span><span class="p">(</span><span class="s">"acc"</span><span class="p">,</span> <span class="s">"cdr_flag"</span><span class="p">,</span> <span class="s">"DB_FLAG"</span><span class="p">)</span>
<span class="n">modparam</span><span class="p">(</span><span class="s">"acc"</span><span class="p">,</span> <span class="s">"db_extra"</span><span class="p">,</span>
    <span class="s">"src_user=$fU;src_domain=$fd;dst_user=$tU;dst_domain=$rd"</span><span class="p">)</span>
<span class="n">modparam</span><span class="p">(</span><span class="s">"acc"</span><span class="p">,</span> <span class="s">"db_url"</span><span class="p">,</span>
    <span class="s">"mysql://opensips:opensipsrw@127.0.0.1/opensips_new"</span><span class="p">)</span>

<span class="cp">####### Routing Logic ########
</span>
<span class="n">route</span><span class="p">{</span>
    <span class="cp"># process sequential requests
</span>    <span class="k">if</span> <span class="p">(</span><span class="n">has_totag</span><span class="p">())</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">loose_route</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">t_check_trans</span><span class="p">()</span> <span class="p">)</span> <span class="p">{</span>
            <span class="n">sl_send_reply</span><span class="p">(</span><span class="s">"404"</span><span class="p">,</span><span class="s">"Not here"</span><span class="p">);</span>
            <span class="n">exit</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="n">t_relay</span><span class="p">();</span>
        <span class="n">exit</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">method</span> <span class="o">==</span> <span class="s">"INVITE"</span><span class="p">)</span> <span class="p">{</span>
        <span class="cp"># accounting
</span>        <span class="n">create_dialog</span><span class="p">(</span><span class="s">"B"</span><span class="p">);</span>
        <span class="n">setflag</span><span class="p">(</span><span class="n">DB_FLAG</span><span class="p">);</span>    
    <span class="p">}</span>

    <span class="n">record_route</span><span class="p">();</span>

    <span class="cp"># relay request in stateful manner to R-URI
</span>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">t_relay</span><span class="p">())</span>
        <span class="n">sl_reply_error</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Sumit Birla</name></author><category term="OpenSIPS" /><category term="VoIP" /><category term="Coding" /><summary type="html"><![CDATA[With any phone system, you want to log the calls and certain details related to each call. You may do this to perform billing or generate reports of some kind. By default, OpenSIPS performs very basic logging of events. So for a given call, you may have numerous rows in database and you are supposed to match an INVITE with corresponding BYE (or cancel) event and determine the bill_duration. This is quite a bit of work as you can imagine a lot of things can go wrong between the INVITE and the BYE.]]></summary></entry><entry><title type="html">OpenSIPS #2: Connecting to PSTN</title><link href="https://sumitbirla.me/2015/11/opensips-connecting-to-pstn/" rel="alternate" type="text/html" title="OpenSIPS #2: Connecting to PSTN" /><published>2015-11-25T00:40:28-05:00</published><updated>2015-11-25T00:40:28-05:00</updated><id>https://sumitbirla.me/2015/11/opensips-connecting-to-pstn</id><content type="html" xml:base="https://sumitbirla.me/2015/11/opensips-connecting-to-pstn/"><![CDATA[<blockquote>
  <p><strong>Note:</strong> updated for OpenSIPS 2.2 (long term support) on May 10th, 2017.</p>
</blockquote>

<p>Building on top of the simple example of previous article, we add connectivity to a PSTN gateway. This allows you to make outbound calls from your SIP phone. Since we will be running OpenSIPS on the WAN interface, please keep in mind the security ramifications of doing do, especially since we have no authentication mechanism in place.</p>

<p>Forwarding INVITE’s to the PSTN gateway is actually straight forward. We look the the request user field ($rU) to see if it is a local extension (3 digits). If so, we connect the call as always. If not, we rewrite the IP address ($rd) to that of the gateway and relay the packet.</p>

<p>To our script, we also add a few lines of code to handle sequential requests. This allows us to use <a href="https://vimeo.com/140267478">loose routing</a> to relay the packets without having to determine the routing logic all over again. Also note the `mhomed=1` and the listen lines at the top of the script. We are not binding to local and WAN interfaces on the server running OpenSIPS.</p>

<p><a href="/assets/images/2015/11/OpenSIPS_-PSTN-New-Page.png"><img src="/assets/images/2015/11/OpenSIPS_-PSTN-New-Page.png" alt="OpenSIPS_ PSTN - New Page" width="550" class="aligncenter size-full wp-image-1030" srcset="/assets/images/2015/11/OpenSIPS_-PSTN-New-Page.png 761w, /assets/images/2015/11/OpenSIPS_-PSTN-New-Page-300x233.png 300w" sizes="(max-width: 761px) 100vw, 761px" /></a></p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">####### Global Parameters #########
</span>
<span class="n">log_stderror</span><span class="o">=</span><span class="n">no</span>
<span class="n">log_facility</span><span class="o">=</span><span class="n">LOG_LOCAL0</span>
<span class="n">log_level</span><span class="o">=</span><span class="mi">3</span>
<span class="n">children</span><span class="o">=</span><span class="mi">2</span>
<span class="n">auto_aliases</span><span class="o">=</span><span class="n">no</span>

<span class="n">mhomed</span><span class="o">=</span><span class="mi">1</span>
<span class="n">listen</span><span class="o">=</span><span class="n">udp</span><span class="o">:</span><span class="mf">192.168.32.8</span><span class="o">:</span><span class="mi">5060</span>    <span class="err">#</span> <span class="n">LAN</span> <span class="n">Interface</span>
<span class="n">listen</span><span class="o">=</span><span class="n">udp</span><span class="o">:</span><span class="mf">6.7.8.9</span><span class="o">:</span><span class="mi">5060</span>         <span class="err">#</span> <span class="n">WAN</span> <span class="n">Interface</span>


<span class="cp">####### Modules Section ########
</span>
<span class="n">mpath</span><span class="o">=</span><span class="s">"/usr/lib/opensips/modules/"</span>

<span class="n">loadmodule</span> <span class="s">"signaling.so"</span>
<span class="n">loadmodule</span> <span class="s">"sl.so"</span>
<span class="n">loadmodule</span> <span class="s">"registrar.so"</span>
<span class="n">loadmodule</span> <span class="s">"proto_udp.so"</span>
<span class="n">loadmodule</span> <span class="s">"tm.so"</span>
<span class="n">loadmodule</span> <span class="s">"uri.so"</span>
<span class="n">loadmodule</span> <span class="s">"rr.so"</span>

<span class="n">loadmodule</span> <span class="s">"mi_fifo.so"</span>
<span class="n">modparam</span><span class="p">(</span><span class="s">"mi_fifo"</span><span class="p">,</span> <span class="s">"fifo_name"</span><span class="p">,</span> <span class="s">"/tmp/opensips_fifo"</span><span class="p">)</span>

<span class="n">loadmodule</span> <span class="s">"usrloc.so"</span>
<span class="n">modparam</span><span class="p">(</span><span class="s">"usrloc"</span><span class="p">,</span> <span class="s">"db_mode"</span><span class="p">,</span>   <span class="mi">0</span><span class="p">)</span>


<span class="cp">####### Routing Logic ########
</span>
<span class="n">route</span><span class="p">{</span>
    <span class="cp"># process sequential requests
</span>    <span class="k">if</span> <span class="p">(</span><span class="n">has_totag</span><span class="p">())</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">loose_route</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">t_check_trans</span><span class="p">()</span> <span class="p">)</span> <span class="p">{</span>
            <span class="n">sl_send_reply</span><span class="p">(</span><span class="s">"404"</span><span class="p">,</span><span class="s">"Not here"</span><span class="p">);</span>
            <span class="n">exit</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="n">t_relay</span><span class="p">();</span>
        <span class="n">exit</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="cp"># register user location without authentication
</span>    <span class="k">if</span> <span class="p">(</span><span class="n">method</span> <span class="o">==</span> <span class="s">"REGISTER"</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">xlog</span><span class="p">(</span><span class="s">"registering $tU </span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
        <span class="n">save</span><span class="p">(</span><span class="s">"nuc"</span><span class="p">);</span>
        <span class="n">exit</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="cp"># lookup requested user. if registered, below will replace R-URI with
</span>    <span class="cp"># registered user's contact.  Otherwise forward to PSTN gateway
</span>    <span class="k">if</span> <span class="p">(</span><span class="n">method</span> <span class="o">==</span> <span class="s">"INVITE"</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">xlog</span><span class="p">(</span><span class="s">"calling $tU </span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>

        <span class="k">if</span> <span class="p">(</span><span class="err">$</span><span class="n">rU</span> <span class="o">=~</span> <span class="s">"^1[0-9][0-9]$"</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">lookup</span><span class="p">(</span><span class="s">"nuc"</span><span class="p">))</span> <span class="p">{</span>
                <span class="n">sl_send_reply</span><span class="p">(</span><span class="s">"404"</span><span class="p">,</span> <span class="s">"User not found"</span><span class="p">);</span>
                <span class="n">exit</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="err">$</span><span class="n">rd</span> <span class="o">=</span> <span class="s">"1.2.3.4:5060"</span><span class="p">;</span>  <span class="err">#</span> <span class="n">send</span> <span class="n">to</span> <span class="n">gateway</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="cp"># make sure this node stays in the communication path
</span>    <span class="n">record_route</span><span class="p">();</span>

    <span class="cp"># relay request in stateful manner to R-URI
</span>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">t_relay</span><span class="p">())</span>
        <span class="n">sl_reply_error</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>When you run the above script, you should be able to make outbound PSTN calls (provided your gateway allows it). You may not have 2-way audio because the gateway has no way of reaching your phone which has a private IP address (read how RTP streams work with SIP). This is a major source of headache in VoIP applications and will be addressed in the next article.</p>]]></content><author><name>Sumit Birla</name></author><category term="OpenSIPS" /><category term="VoIP" /><category term="Coding" /><summary type="html"><![CDATA[Note: updated for OpenSIPS 2.2 (long term support) on May 10th, 2017.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://sumitbirla.me/wp-content/uploads/2015/11/fMjXFg41_400x400.png" /><media:content medium="image" url="https://sumitbirla.me/wp-content/uploads/2015/11/fMjXFg41_400x400.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">OpenSIPS #1: A Basic Script</title><link href="https://sumitbirla.me/2015/11/a-basic-opensips-script/" rel="alternate" type="text/html" title="OpenSIPS #1: A Basic Script" /><published>2015-11-20T08:00:19-05:00</published><updated>2015-11-20T08:00:19-05:00</updated><id>https://sumitbirla.me/2015/11/a-basic-opensips-script</id><content type="html" xml:base="https://sumitbirla.me/2015/11/a-basic-opensips-script/"><![CDATA[<blockquote>
  <p><strong>Note:</strong> updated for OpenSIPS 2.2 (long term support) on May 10th, 2017.</p>
</blockquote>

<p>Looking at a full-fledged OpenSIPS script for the first time can be a bewildering experience. It takes a lot of reading, testing and learning to get comfortable with it. However, for some instant gratification, you can try this. The script below is allows you to register SIP phones on your LAN and make calls to each other. It does not handle PSTN calls or any other fancy features. It doesn’t even check for your credentials, so you can pass in anything you like. If two phones are set up with the same extension, both will ring.<br />
<a href="/assets/images/2015/11/OpenSIPS_-Basic.png"><img src="/assets/images/2015/11/OpenSIPS_-Basic.png" alt="OpenSIPS_ Basic" width="500" class="aligncenter size-full wp-image-1027" srcset="/assets/images/2015/11/OpenSIPS_-Basic.png 678w, /assets/images/2015/11/OpenSIPS_-Basic-300x225.png 300w" sizes="(max-width: 678px) 100vw, 678px" /></a></p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">log_stderror</span><span class="o">=</span><span class="n">no</span>
<span class="n">log_facility</span><span class="o">=</span><span class="n">LOG_LOCAL0</span>
<span class="n">log_level</span><span class="o">=</span><span class="mi">3</span>
<span class="n">children</span><span class="o">=</span><span class="mi">2</span>
<span class="n">auto_aliases</span><span class="o">=</span><span class="n">no</span>
<span class="n">listen</span><span class="o">=</span><span class="n">udp</span><span class="o">:</span><span class="mf">10.0.9.1</span><span class="o">:</span><span class="mi">5060</span>  <span class="err">#</span> <span class="n">CHANGE</span> <span class="n">MY</span> <span class="n">IP</span> <span class="n">ADDRESS</span><span class="o">!</span>


<span class="cp">####### Modules Section ########
</span><span class="n">mpath</span><span class="o">=</span><span class="s">"/usr/lib/opensips/modules/"</span>

<span class="n">loadmodule</span> <span class="s">"signaling.so"</span>
<span class="n">loadmodule</span> <span class="s">"sl.so"</span>
<span class="n">loadmodule</span> <span class="s">"registrar.so"</span>
<span class="n">loadmodule</span> <span class="s">"proto_udp.so"</span>
<span class="n">loadmodule</span> <span class="s">"tm.so"</span>

<span class="n">loadmodule</span> <span class="s">"mi_fifo.so"</span>
<span class="n">modparam</span><span class="p">(</span><span class="s">"mi_fifo"</span><span class="p">,</span> <span class="s">"fifo_name"</span><span class="p">,</span> <span class="s">"/tmp/opensips_fifo"</span><span class="p">)</span>

<span class="n">loadmodule</span> <span class="s">"usrloc.so"</span>
<span class="n">modparam</span><span class="p">(</span><span class="s">"usrloc"</span><span class="p">,</span> <span class="s">"db_mode"</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>


<span class="cp">####### Routing Logic ########
</span><span class="n">route</span><span class="p">{</span>
    <span class="cp"># register user location without authentication
</span>    <span class="k">if</span> <span class="p">(</span><span class="n">method</span> <span class="o">==</span> <span class="s">"REGISTER"</span><span class="p">)</span> <span class="p">{</span>

        <span class="n">xlog</span><span class="p">(</span><span class="s">"registering $tU </span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
        <span class="n">save</span><span class="p">(</span><span class="s">"nuc"</span><span class="p">);</span>
        <span class="n">exit</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="cp"># lookup requested user, if registered, below will replace 
</span>    <span class="cp"># R-URI with registered user's contact
</span>    <span class="k">if</span> <span class="p">(</span><span class="n">method</span> <span class="o">==</span> <span class="s">"INVITE"</span><span class="p">)</span> <span class="p">{</span>

        <span class="n">xlog</span><span class="p">(</span><span class="s">"calling $tU </span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">lookup</span><span class="p">(</span><span class="s">"nuc"</span><span class="p">))</span> <span class="p">{</span>
            <span class="n">sl_send_reply</span><span class="p">(</span><span class="s">"404"</span><span class="p">,</span> <span class="s">"User not found"</span><span class="p">);</span>
            <span class="n">exit</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="cp"># relay request in stateful manner to R-URI
</span>    <span class="n">t_relay</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Run the script and watch your syslog for register and calling messages. You can also view registered users with the following command:</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Domain:: nuc <span class="nv">table</span><span class="o">=</span>512 <span class="nv">records</span><span class="o">=</span>2
	AOR:: 102
		Contact:: sip:102@192.168.32.118:2048<span class="p">;</span><span class="nv">line</span><span class="o">=</span>7dga26nf <span class="nv">Q</span><span class="o">=</span>1
			Expires:: 3337
			Callid:: 313434373937393735303238383034-1soqnqfjhn95
			Cseq:: 26
			User-agent:: n/a
			State:: CS_NEW
			Flags:: 0
			Cflags::
			Socket:: udp:192.168.32.8:5060
			Methods:: 7999
			SIP_instance:: &amp;lt<span class="p">;</span>urn:uuid:ecea5aa1-09b1-4f2e-8272-0004134AAB2B&gt;
	AOR:: 101
		Contact:: sip:101@192.168.32.3:52500<span class="p">;</span><span class="nv">rinstance</span><span class="o">=</span>4d64f6f35eb88aa6 <span class="nv">Q</span><span class="o">=</span>
			Expires:: 1155
			Callid:: 78102MWJiZmRhY2VkMTJkNjZmMjhmZjQyMThhNjZmYjIwMGU
			Cseq:: 12
			User-agent:: X-Lite release 4.9.0 stamp 78102
			State:: CS_NEW
			Flags:: 0
			Cflags::
			Socket:: udp:192.168.32.8:5060
			Methods:: 5919
</code></pre></div></div>

<p>In the next post, I will show how to add a PSTN gateway to this set up so that you can make outgoing calls. Small Steps. I recommend reading up on how SIP works and the structure of a SIP datagram and the various field before proceeding with more advanced topics.</p>]]></content><author><name>Sumit Birla</name></author><category term="OpenSIPS" /><category term="VoIP" /><category term="Coding" /><summary type="html"><![CDATA[Note: updated for OpenSIPS 2.2 (long term support) on May 10th, 2017.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://sumitbirla.me/wp-content/uploads/2015/11/fMjXFg41_400x400.png" /><media:content medium="image" url="https://sumitbirla.me/wp-content/uploads/2015/11/fMjXFg41_400x400.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>