<?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: TAMIL MANI B</title>
    <description>The latest articles on DEV Community by TAMIL MANI B (@tamilmanib2007).</description>
    <link>https://dev.to/tamilmanib2007</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3776093%2Fb4446119-98ce-490a-8241-41c609e456c9.jpeg</url>
      <title>DEV Community: TAMIL MANI B</title>
      <link>https://dev.to/tamilmanib2007</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tamilmanib2007"/>
    <language>en</language>
    <item>
      <title>Building NalamMesh DPI: A Disaster-Ready Healthcare App with 2G SMS Fallback (Node.js)</title>
      <dc:creator>TAMIL MANI B</dc:creator>
      <pubDate>Tue, 17 Feb 2026 14:41:41 +0000</pubDate>
      <link>https://dev.to/tamilmanib2007/building-nalammesh-dpi-a-disaster-ready-healthcare-app-with-2g-sms-fallback-nodejs-c59</link>
      <guid>https://dev.to/tamilmanib2007/building-nalammesh-dpi-a-disaster-ready-healthcare-app-with-2g-sms-fallback-nodejs-c59</guid>
      <description>&lt;p&gt;Handling real-time data is easy when you have 5G. But what happens when a natural disaster hits and cellular networks go dark?&lt;/p&gt;

&lt;p&gt;During a recent hackathon, my team and I built &lt;strong&gt;NalamMesh&lt;/strong&gt;, a Digital Public Infrastructure (DPI) aimed at hospital readiness. When asked how our system would survive a total internet blackout, we had to rethink our architecture.&lt;/p&gt;

&lt;p&gt;Here is how we implemented a 2G SMS fallback system using Node.js to keep critical patient vitals transmitting even when the internet is dead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The Problem: When the Internet Fails&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In cities like Chennai, we are no strangers to severe monsoons and floods. During these critical times, the first thing to collapse is the 4G/5G data infrastructure. Imagine an ambulance carrying a critical patient navigating through waterlogged streets. The hospital needs to prepare the ICU triage with the patient's vitals (Heart Rate, SpO2, BP) before they arrive. But with zero internet connectivity, modern React or Flutter dashboards become completely useless. We needed a solution that works when the internet dies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Why 2G SMS is the Ultimate Fallback&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While data networks require high-bandwidth infrastructure, SMS operates differently. It uses the cellular network's control channels (the signaling path used by towers to track your phone). Even if the internet cables are cut, as long as there is a faint 2G cellular signal to make a voice call, a 160-character text message can go through. By compressing a patient's vitals into a tiny string payload, we realized we could bypass the need for an internet connection entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The Architecture of NalamMesh&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our goal with NalamMesh was to build a resilient Digital Public Infrastructure (DPI). The architecture is incredibly lightweight:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Client (Ambulance/CHW): A simple mobile-responsive UI where paramedics input vitals.&lt;/li&gt;
&lt;li&gt;The Offline Trigger: If the app detects navigator.onLine is false, it intercepts the API call and triggers the phone's native SMS intent.&lt;/li&gt;
&lt;li&gt;The Gateway: The SMS is sent to a central Twilio/Vonage virtual number.&lt;/li&gt;
&lt;li&gt;The Backend (Node.js): A webhook receives the SMS, parses the compressed string (e.g., ID:123|HR:95|O2:92), and updates our MongoDB database, instantly reflecting on the hospital's React dashboard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. The Code: Sending Vitals Offline&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of sending heavy JSON objects, we format the data into a strict string structure. Here is a simplified version of our Node.js webhook controller that handles the incoming SMS data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Express route handling incoming SMS from the cellular gateway&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/sms-webhook&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&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;incomingText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Example: "ID:101|HR:110|BP:120/80|O2:94"&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;senderPhone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;From&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Parse the compressed SMS string&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;vitalsData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;incomingText&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;patientData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;patientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;vitalsData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="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="na"&gt;heartRate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;vitalsData&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="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="na"&gt;bloodPressure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;vitalsData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&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="na"&gt;spO2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;vitalsData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&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="na"&gt;timestamp&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;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;// Save to MongoDB&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;PatientVitals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;patientData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Alert the React Dashboard via WebSockets&lt;/span&gt;
        &lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;emergency_vital_update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;patientData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;Response&amp;gt;&amp;lt;/Response&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Acknowledge receipt&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to parse fallback SMS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Future Scope: Hardware Mesh Networks
&lt;/h2&gt;

&lt;p&gt;While the 2G SMS fallback is a solid software approach, what happens if the cellular towers completely fall? During our hackathon presentation, the judges asked us this exact question. Our next evolution for NalamMesh is integrating LoRa (Long Range) modules (like the ESP32 LoRa). This will allow ambulances to transmit vitals using pure radio frequencies to a localized hospital receiver, creating a true, 100% zero-connectivity hardware mesh network.&lt;/p&gt;

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

&lt;p&gt;Building tech for disaster management forces you to unlearn modern conveniences. It teaches you that sometimes, a 30-year-old technology like SMS is more reliable than a cutting-edge 5G WebRTC stream. As developers, we need to build for the worst-case scenario, because in healthcare, a loading spinner can cost lives.&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>hackathon</category>
    </item>
  </channel>
</rss>
