<?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: Egonex</title>
    <description>The latest articles on DEV Community by Egonex (@egonex).</description>
    <link>https://dev.to/egonex</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%2F3821895%2F4f83e2bd-f38e-48b3-9f38-9c82d45b123c.jpeg</url>
      <title>DEV Community: Egonex</title>
      <link>https://dev.to/egonex</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/egonex"/>
    <language>en</language>
    <item>
      <title>669 bytes for a fire alert. We compressed it to 8. Here's how.</title>
      <dc:creator>Egonex</dc:creator>
      <pubDate>Thu, 19 Mar 2026 10:08:57 +0000</pubDate>
      <link>https://dev.to/egonex/669-bytes-for-a-fire-alert-we-compressed-it-to-8-heres-how-51fa</link>
      <guid>https://dev.to/egonex/669-bytes-for-a-fire-alert-we-compressed-it-to-8-heres-how-51fa</guid>
      <description>&lt;p&gt;669 bytes.&lt;/p&gt;

&lt;p&gt;That's how much data CAP XML — the industry standard — needs to tell a computer: &lt;em&gt;there's a fire in Building A, evacuate now.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We compressed it to &lt;strong&gt;8 bytes&lt;/strong&gt;. Same core machine-readable alert semantics. Need payload and signatures? Typical Envelope size is still under 100 bytes.&lt;/p&gt;

&lt;p&gt;Here's what that looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Format             Bytes
─────────────────────────────────
CAP XML (OASIS)      669  ████████████████████████████████████
JSON over HTTP        270  ██████████████
ECP Envelope        45-100  █████
ECP Token (UET)         8  █
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's not a typo. &lt;strong&gt;8 bytes&lt;/strong&gt; for a complete minimal machine alert — type, priority, zone, timestamp, and action flags. The 8-byte token (UET) is the minimal format. Need payload and HMAC signatures? That's the Envelope: 45-100 bytes, still 85-93% smaller than CAP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you work with LoRa, BLE, satellite, or any bandwidth-constrained network — this is your problem too.&lt;/strong&gt; Not just emergencies: any structured message that needs to travel light.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why does this matter?
&lt;/h2&gt;

&lt;p&gt;LoRa transmits at 300 bytes/sec. BLE has a 20-byte MTU. Satellite links charge per byte. Industrial SCADA networks have real-time constraints. In those environments, 669 bytes is not just wasteful — it may not arrive at all.&lt;/p&gt;

&lt;p&gt;We built ECP because we ran into this problem ourselves. We operate an emergency management system for airports, railways, and ports. When we measured our real traffic, the numbers were clear: most of the bandwidth was format overhead, not actual emergency data. But the protocol works for any domain where bytes matter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Show me the code
&lt;/h2&gt;

&lt;p&gt;Install the package (requires &lt;a href="https://dotnet.microsoft.com/download/dotnet/8.0" rel="noopener noreferrer"&gt;.NET 8 SDK&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package ECP.Core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  One line to send a fire alert
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ECP.Core&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ECP.Core.Models&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;alert&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Ecp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EmergencyType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fire&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zoneHash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EcpPriority&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Critical&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// alert.Length == 8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. &lt;code&gt;alert&lt;/code&gt; contains emergency type, priority, zone, timestamp, and action flags. 8 bytes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Need more data? Use an Envelope
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ECP.Core&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ECP.Core.Models&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;hmacKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;32&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// load your key from secure storage&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;envelope&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Ecp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Envelope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EmergencyType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Earthquake&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithPriority&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EcpPriority&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Critical&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Evacuate Building A via Stairway B"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithHmacKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hmacKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// 45-100 bytes, cryptographically signed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Decode anything with one call
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ECP.Core&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ECP.Core.Models&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;incomingBytes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetIncomingBytes&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="n"&gt;Ecp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TryDecode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;incomingBytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsUet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Type: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EmergencyType&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&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="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsEnvelope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Payload: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Envelope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PayloadType&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;GetIncomingBytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three API levels. One for quick alerts, one for signed envelopes, one for full control. You pick what you need.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real numbers, not marketing
&lt;/h2&gt;

&lt;p&gt;We didn't build this in a lab and hope it works. During development and internal testing of our emergency management platform, ECP has processed &lt;strong&gt;263,000+ system events&lt;/strong&gt; — monitoring, operational traffic, and integration tests — with an average &lt;strong&gt;96% data reduction&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;System events (internal testing)&lt;/td&gt;
&lt;td&gt;263,000+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Average data reduction&lt;/td&gt;
&lt;td&gt;96%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CAP XML → ECP savings&lt;/td&gt;
&lt;td&gt;85-93%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON → ECP savings&lt;/td&gt;
&lt;td&gt;63-83%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zero-allocation encode&lt;/td&gt;
&lt;td&gt;Yes (&lt;code&gt;WriteTo(Span&amp;lt;byte&amp;gt;)&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://egonex-code.github.io/ecp-protocol/proof/?ref=da01" rel="noopener noreferrer"&gt;Instant visual proof (no install)&lt;/a&gt;&lt;/strong&gt; — see the comparison in 5 seconds, right in your browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to verify independently?&lt;/strong&gt; Clone the repo and measure on your machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Egonex-Code/ecp-protocol.git
&lt;span class="nb"&gt;cd &lt;/span&gt;ecp-protocol/samples/ProofCard
dotnet run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want to see the raw payloads? Add &lt;code&gt;-- --show-payload&lt;/code&gt; to see CAP XML, JSON, and ECP side by side.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full benchmarks&lt;/strong&gt; are also in the repo (&lt;code&gt;benchmarks/ECP.PublicBenchmarks&lt;/code&gt;) if you want to measure throughput and allocation on your hardware.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's inside
&lt;/h2&gt;

&lt;p&gt;ECP is not a single package — it's a modular SDK. Use only what you need:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;ECP.Core&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Encoder/decoder, UET token, Envelope, HMAC security. &lt;strong&gt;Start here.&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ECP.Registry&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Semantic compression, multilingual templates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ECP.Cascade&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;P2P broadcast with O(log N) fan-out&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ECP.Transport.WebSocket&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;WebSocket delivery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ECP.Transport.SignalR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SignalR delivery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ECP.Compatibility&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;JSON-to-ECP migration bridge&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;ECP.Core&lt;/code&gt; has &lt;strong&gt;zero external dependencies&lt;/strong&gt; — it uses only .NET 8 BCL. No Newtonsoft, no Protobuf, no MessagePack. Just &lt;code&gt;System.Security.Cryptography&lt;/code&gt; and &lt;code&gt;BinaryPrimitives&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why open source?
&lt;/h2&gt;

&lt;p&gt;Multiple patents have been filed (UIBM, Italy) covering the protocol design. The core implementation is released under &lt;strong&gt;Apache 2.0&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Why? Because emergency communication shouldn't have a paywall. If a LoRa sensor in a remote area needs to send a fire alert in 8 bytes, it should be able to — without licensing fees.&lt;/p&gt;

&lt;p&gt;The patents protect the innovation. The open source license lets everyone use it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What ECP does NOT do
&lt;/h2&gt;

&lt;p&gt;Transparency matters, so here's what ECP is &lt;em&gt;not&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Not a complete emergency management system.&lt;/strong&gt; ECP is the wire protocol — the encoding layer. You still need your own dispatch, routing, and UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a CAP replacement for all scenarios.&lt;/strong&gt; If you have reliable broadband and need full CAP interoperability, CAP works fine. ECP targets constrained environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not battle-tested at internet scale.&lt;/strong&gt; 263,000+ system events during internal testing is meaningful, but it's not millions. We're publishing everything so the community can help push those boundaries.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package ECP.Core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Write your first alert. Check the output. Count the bytes.&lt;/p&gt;

&lt;p&gt;If you want the full picture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Egonex-Code/ecp-protocol" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nuget.org/profiles/Egonex" rel="noopener noreferrer"&gt;NuGet packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Egonex-Code/ecp-protocol/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;CONTRIBUTING.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;What would you encode in 8 bytes?&lt;/strong&gt; IoT sensor readings? Satellite telemetry? Fleet tracking? Something we haven't thought of?&lt;/p&gt;

&lt;p&gt;We built this for emergencies — but 8 bytes is 8 bytes. If you have a use case where every byte counts, we'd like to hear about it. Post your ProofCard run ID in the comments.&lt;/p&gt;

&lt;p&gt;Found it useful? A ⭐ &lt;a href="https://github.com/Egonex-Code/ecp-protocol" rel="noopener noreferrer"&gt;on the repo&lt;/a&gt; helps others find it.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>opensource</category>
      <category>iot</category>
    </item>
  </channel>
</rss>
