<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>d0wn</title>
	<atom:link href="http://www.d0wn.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.d0wn.com</link>
	<description>Linux , SBC&#039;s , Bash scripting</description>
	<lastBuildDate>Wed, 24 Dec 2025 22:00:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.2.2</generator>
	<item>
		<title>Fetching and Parsing JSON with Vue 3</title>
		<link>http://www.d0wn.com/fetching-and-parsing-json-with-vue-3/</link>
					<comments>http://www.d0wn.com/fetching-and-parsing-json-with-vue-3/#respond</comments>
		
		<dc:creator><![CDATA[Fabien]]></dc:creator>
		<pubDate>Wed, 24 Dec 2025 21:37:31 +0000</pubDate>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[dashboard]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[simple]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[vue]]></category>
		<guid isPermaLink="false">https://www.d0wn.com/?p=1809</guid>

					<description><![CDATA[Let&#8217;s say you have a JSON endpoint (like a MikroTik switch status that you get from a script ). You want to see it graphically in your webbrowser . You don&#8217;t want to ear about npm or configure Webpack.Here is the single-file solution. It uses Vue 3 from a CDN to fetch, parse, and render [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Let&#8217;s say you have a JSON endpoint (like a MikroTik switch status that you get from a script ). You want to see it graphically in your webbrowser . You don&#8217;t want to ear about npm or configure Webpack.<br>Here is the single-file solution. It uses Vue 3 from a CDN to fetch, parse, and render your JSON in real-time.<br></p>



<pre class="wp-block-code" style="font-size:9px"><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;title&gt;Switch Stats&lt;/title&gt;
    &lt;script src="https://unpkg.com/vue@3/dist/vue.global.js"&gt;&lt;/script&gt;
    &lt;style&gt;
        body { background: #111; color: #ddd; font-family: monospace; padding: 20px; }
        /* Simple responsive grid for the ports */
        .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
        .card { border: 1px solid #444; padding: 10px; background: #222; }
        .green { color: #0f0; } .red { color: #f00; } .gold { color: #fd0; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id="app"&gt;
        &lt;div v-if="!device"&gt;Loading...&lt;/div&gt;
        &lt;div v-else&gt;
            &lt;h1&gt;{{ device.general.identity }}&lt;/h1&gt;
            &lt;p&gt;IP: {{ device.general.ip }} | CPU: {{ device.general.cpu }}%&lt;/p&gt;
            &lt;div class="grid"&gt;
                &lt;div v-for="p in device.ethernet" :key="p.name" class="card"&gt;
                    &lt;strong :class="p.up ? 'green' : 'red'"&gt;{{ p.name }}&lt;/strong&gt;
                    &lt;div v-if="p.up"&gt;
                        {{ p.speed }}
                        &lt;div v-if="p.poe.power" class="gold"&gt;{{ p.poe.power }}W&lt;/div&gt;
                        &lt;div v-if="p.sfp.temperature"&gt;Temp: {{ p.sfp.temperature }}°C&lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;script&gt;
        Vue.createApp({
            setup() {
                // Define a reactive container for our data
                const device = Vue.ref(null);
                const load = async () =&gt; {
                    // Fetch the local JSON file
                    // Note: This requires a local server (CORS) if not on the same domain
                    const res = await fetch('switch.json');                     
                    // Assigning the JSON to .value triggers the HTML update automatically
                    device.value = await res.json();
                };
                Vue.onMounted(() =&gt; {
                    load();
                    setInterval(load, 30000); // Auto-Refresh every 30s
                });
                return { device };
            }
        }).mount('#app');
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>



<p>The Logic : </p>



<p>We use </p>



<pre class="wp-block-code" style="font-size:9px"><code>const device = Vue.ref(null);

const load = async () =&gt; {
    const res = await fetch('data.json'); 
    device.value = await res.json(); // Reactivity triggers here
};</code></pre>



<p>to load the json and put it in <code>device</code> then after this we <code>return</code> it to be used in the html part <br>then we can map the data we just got in device </p>



<ul>
<li>Use <code>v-for</code> to iterate over arrays (like our Ethernet ports).</li>



<li>Use <code>v-if</code> to filter out empty data (like ports without PoE).</li>
</ul>



<p>the demo is here <a href="https://www.d0wn.com/vue/">https://www.d0wn.com/vue/</a><br>and the demo json file is here : <a href="https://www.d0wn.com/vue/switch.json">https://www.d0wn.com/vue/switch.json</a></p>



<p>Because browsers block fetch requests to local files for security (CORS), you cannot just double-click index.html.</p>



<p>Run a temporary server in the folder containing your file</p>



<pre class="wp-block-code has-small-font-size"><code>python3 -m http.server 8000</code></pre>



<p>Then visit <code>http://localhost:8000.</code></p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.d0wn.com/fetching-and-parsing-json-with-vue-3/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CWNA-109 Practice Exam Tool</title>
		<link>http://www.d0wn.com/cwna-109-practice-exam-tool/</link>
					<comments>http://www.d0wn.com/cwna-109-practice-exam-tool/#respond</comments>
		
		<dc:creator><![CDATA[Fabien]]></dc:creator>
		<pubDate>Mon, 08 Dec 2025 15:38:40 +0000</pubDate>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[certification]]></category>
		<category><![CDATA[cwna]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[wifi]]></category>
		<guid isPermaLink="false">https://www.d0wn.com/?p=1807</guid>

					<description><![CDATA[Hey! Recently, for my job, I was required to pass the CWNA-109 (Certified Wireless Network Administrator) certification. As I was studying, I realized I needed a better way to test my knowledge and get ready for the actual exam conditions. So, naturally, I decided to build a little tool to help with the preparation! I’ve [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Hey!</p>



<p>Recently, for my job, I was required to pass the CWNA-109 (Certified Wireless Network Administrator) certification.</p>



<p>As I was studying, I realized I needed a better way to test my knowledge and get ready for the actual exam conditions. So, naturally, I decided to build a little tool to help with the preparation!</p>



<p>I’ve put together a complete CWNA-109 Practice Exam simulator.</p>



<p>The tool randomly selects 60 questions from a database to simulate the real exam experience. It tracks your score as you go and even provides explanations for the answers, so you can learn from any mistakes.</p>



<p>If you are preparing for the certification or just want to test your wireless networking skills, give it a try.</p>



<p>Head over to <a href="https://www.d0wn.com/cwna/ ">https://www.d0wn.com/cwna/ </a>and check it out!</p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.d0wn.com/cwna-109-practice-exam-tool/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Ruckus &#038; UniFi DHCP Option 43 Tool!</title>
		<link>http://www.d0wn.com/check-out-my-cool-ruckus-dhcp-option-43-tool/</link>
					<comments>http://www.d0wn.com/check-out-my-cool-ruckus-dhcp-option-43-tool/#respond</comments>
		
		<dc:creator><![CDATA[Fabien]]></dc:creator>
		<pubDate>Wed, 23 Apr 2025 20:35:52 +0000</pubDate>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[calculator]]></category>
		<category><![CDATA[dhcp]]></category>
		<category><![CDATA[dhcp43]]></category>
		<category><![CDATA[ruckus]]></category>
		<category><![CDATA[unifi]]></category>
		<guid isPermaLink="false">https://www.d0wn.com/?p=1802</guid>

					<description><![CDATA[Hey! I&#8217;ve made a little tool that makes creation DHCP Option 43 for Ruckus and UniFi Access Points way more easy. With the tool you can encode an IP address for your RUCKUS SmartZone or ZoneDirector controller and UniFi, or decode an existing Option 43 string to figure out what ip address is behind the [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img decoding="async" src="http://www.d0wn.com/wp-content/uploads/opt43.png" alt="" class="wp-image-1805" width="150" height="191"/></figure></div>


<p>Hey! I&#8217;ve made a little tool that makes creation DHCP Option 43 for Ruckus and UniFi Access  Points  way more easy.<br> With the tool you can encode an IP address for your RUCKUS SmartZone or ZoneDirector controller and UniFi, or decode an existing Option 43  string to figure out what ip address is behind the string.<br>And it even give in some  examples for setting it up on Cisco IOS, MikroTik, or dnsmasq. Want to try it ? Head over to <a rel="noreferrer noopener" href="https://www.d0wn.com/option_43.php" target="_blank">https://www.d0wn.com/option_43.php</a> and check it out!</p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.d0wn.com/check-out-my-cool-ruckus-dhcp-option-43-tool/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MikroTik Script to Resolve Bridge Host IPs and Hostnames</title>
		<link>http://www.d0wn.com/mikrotik-script-to-resolve-bridge-host-ips-and-hostnames/</link>
					<comments>http://www.d0wn.com/mikrotik-script-to-resolve-bridge-host-ips-and-hostnames/#respond</comments>
		
		<dc:creator><![CDATA[Fabien]]></dc:creator>
		<pubDate>Fri, 21 Mar 2025 09:40:26 +0000</pubDate>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[mikrotik]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[script]]></category>
		<guid isPermaLink="false">https://www.d0wn.com/?p=1800</guid>

					<description><![CDATA[This script for MikroTik RouterOS maps bridge-connected devices by linking their MAC addresses to IP addresses and hostnames. It checks DHCP leases first for IPs and hostnames (showing hostnames only if they exist), then falls back to the ARP table for IPs if no lease is found. Devices without matches in either DHCP or ARP [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>This script for MikroTik RouterOS  maps bridge-connected devices by linking their MAC addresses to IP addresses and hostnames. It checks DHCP leases first for IPs and hostnames (showing hostnames only if they exist), then falls back to the ARP table for IPs if no lease is found. Devices without matches in either DHCP or ARP are skipped, displaying results like &#8220;interface=ether1 mac=00:11:22:33:44:55 ip=192.168.1.10&#8221; or adding &#8220;hostname=pc1&#8221; when available.</p>



<pre class="wp-block-code has-small-font-size"><code>{
    :local ip
    :local hostname
    :foreach ID in=&#91;/interface bridge host find] do={
        :local inf &#91;/interface bridge host get $ID interface]
        :local mac &#91;/interface bridge host get $ID mac-address]
        
        # DHCP
        :local lease &#91;/ip dhcp-server lease find mac-address="$mac"]
        :if (&#91;:len $lease] &gt; 0) do={
            :set ip &#91;/ip dhcp-server lease get &#91;:pick $lease 0] address]
            :set hostname &#91;/ip dhcp-server lease get &#91;:pick $lease 0] host-name]
            :if (&#91;:len $hostname] &gt; 0) do={
                :put "interface=$inf mac=$mac ip=$ip hostname=$hostname"
            } else={
                :put "interface=$inf mac=$mac ip=$ip"
            }
        } else={
            # ARP
            :local idmac &#91;/ip arp find mac-address="$mac"]
            :if (&#91;:len $idmac] &gt; 0) do={
                :set ip &#91;/ip arp get &#91;:pick $idmac 0] address]
                :put "interface=$inf mac=$mac ip=$ip"
            }
            # no dhcp and no arp. 
        }
    }
}
</code></pre>



<p class="has-small-font-size">the output will look someting like that<br><br>/tool fetch url=&#8221;http://d0wn.com/host.rsc&#8221; mode=http ; /import host.rsc<br>      status: finished<br>  downloaded: 1KiB    <br>       total: 1KiB    <br>    duration: 1s      <br>interface=ether05-CAM-PLACE mac=00:12:31:11:XX:XX ip=192.168.1.102 hostname=LocalHost<br>interface=ether03-SALON mac=00:90:27:E8:XX:XX ip=192.168.1.90 hostname=proxmox<br>interface=ether03-SALON mac=02:B9:B5:D3:XX:XX ip=192.168.1.13 hostname=homeassistant<br>interface=ether06-PC mac=30:9C:23:0E:XX:XX ip=192.168.1.25 hostname=PC1<br>interface=ether02-CUISINE mac=3C:61:05:30:XX:XX ip=192.168.1.22 hostname=bedroom<br>interface=ether02-CUISINE mac=3C:61:05:32:XX:XX ip=192.168.1.17 hostname=kitchen<br>interface=ether03-SALON mac=48:8F:5A:22:XX:XX ip=192.168.1.3 hostname=AP-Livingroom<br>interface=ether02-CUISINE mac=48:8F:5A:71:XX:XX ip=192.168.1.4 hostname=AP-Kitchen<br>interface=ether03-SALON mac=64:90:C1:01:XX:XX ip=192.168.1.18<br>interface=ether01-GW mac=6C:61:F4:33:XX:XX ip=192.168.1.1<br>interface=ether01-GW mac=8C:AA:B5:05:XX:XX ip=192.168.1.12 hostname=shellyem-05D60F<br>interface=ether03-SALON mac=9C:9D:7E:3F:XX:XX ip=192.168.1.10 hostname=Xiaomi<br>interface=ether03-SALON mac=A0:B7:65:56:XX:XX ip=192.168.1.11 hostname=salon<br>interface=ether03-SALON mac=BC:DF:58:57:XX:XX ip=192.168.1.87 hostname=Tele<br>interface=ether01-GW mac=C4:AC:59:4C:XX:XX ip=192.168.1.21 hostname=Client<br>interface=ether02-CUISINE mac=C4:AC:59:50:XX:XX ip=192.168.1.20 hostname=Client<br>interface=ether03-SALON mac=D4:53:83:5D:XX:XX ip=192.168.1.19 hostname=Client<br>interface=ether03-SALON mac=E4:5F:01:E8:XX:XX ip=192.168.1.100 hostname=nvr<br>Script file loaded and executed successfully</p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.d0wn.com/mikrotik-script-to-resolve-bridge-host-ips-and-hostnames/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Passing argument to a curl downloaded script</title>
		<link>http://www.d0wn.com/passing-argument-to-a-curl-downloaded-script/</link>
					<comments>http://www.d0wn.com/passing-argument-to-a-curl-downloaded-script/#respond</comments>
		
		<dc:creator><![CDATA[Fabien]]></dc:creator>
		<pubDate>Tue, 09 Jul 2024 09:29:22 +0000</pubDate>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[linux]]></category>
		<guid isPermaLink="false">https://www.d0wn.com/?p=1798</guid>

					<description><![CDATA[To add an argument to the execution of the script you&#8217;re downloading and running via curl, you can modify the command like this: You can add other arguments by separating them with spaces after &#8220;scan&#8221; if needed. This method allows you to execute the downloaded script with arguments, just as if you were running it [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>To add an argument to the execution of the script you&#8217;re downloading and running via curl, you can modify the command like this:</p>



<pre class="wp-block-code"><code>curl http://aaa.com/script.sh | sh -s -- scan
</code></pre>



<ul>
<li><strong>sh -s </strong>: This tells sh to accept input from stdin (which comes from curl via the pipe |).</li>



<li><strong>&#8212; </strong>: This marks the end of options for sh. Everything that follows will be considered arguments for the script.</li>



<li><strong>scan</strong> : This is the argument you want to pass to the script</li>
</ul>



<p>You can add other arguments by separating them with spaces after &#8220;scan&#8221; if needed.</p>



<p>This method allows you to execute the downloaded script with arguments, just as if you were running it directly on your system.</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.d0wn.com/passing-argument-to-a-curl-downloaded-script/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>BASH &#124; Hex to Decimal Conversion</title>
		<link>http://www.d0wn.com/bash-hex-to-decimal-conversion/</link>
					<comments>http://www.d0wn.com/bash-hex-to-decimal-conversion/#respond</comments>
		
		<dc:creator><![CDATA[Fabien]]></dc:creator>
		<pubDate>Fri, 24 May 2024 09:00:33 +0000</pubDate>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[hexadecimal]]></category>
		<category><![CDATA[printf]]></category>
		<guid isPermaLink="false">https://www.d0wn.com/?p=1796</guid>

					<description><![CDATA[To convert a hexadecimal value to decimal using Bash, you can use either the printf command or bc. Here&#8217;s how to do it with printf: printf "%d\n" 0x3000 This will output the decimal value corresponding to 0x3000. Alternatively, using bc: This interprets 3000 as a hexadecimal value (base 16) and converts it to decimal. In [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>To convert a hexadecimal value to decimal using Bash, you can use either the <code>printf</code> command or <code>bc</code>. Here&#8217;s how to do it with <code>printf</code>:</p>



<pre class="wp-block-preformatted"><code>printf "%d\n" 0x3000
</code></pre>



<p>This will output the decimal value corresponding to <code>0x3000</code>.</p>



<p>Alternatively, using <code>bc</code>:</p>



<pre class="wp-block-code"><code><code>echo "ibase=16; 3000" | bc
</code></code></pre>



<p>This interprets <code>3000</code> as a hexadecimal value (base 16) and converts it to decimal.</p>



<p>In both cases, the result will be <code>12288</code>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.d0wn.com/bash-hex-to-decimal-conversion/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Using VI to insert spaces at the begining of every line</title>
		<link>http://www.d0wn.com/using-vi-to-insert-spaces-at-the-begining-of-every-line/</link>
					<comments>http://www.d0wn.com/using-vi-to-insert-spaces-at-the-begining-of-every-line/#respond</comments>
		
		<dc:creator><![CDATA[Fabien]]></dc:creator>
		<pubDate>Fri, 26 May 2023 12:34:47 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[substitution]]></category>
		<category><![CDATA[VI]]></category>
		<guid isPermaLink="false">http://www.d0wn.com/?p=1793</guid>

					<description><![CDATA[In the Vi text editor, you can insert two spaces at the beginning of each line using a command called &#8220;substitution.&#8221; Here&#8217;s how you can do it: when in vi with your text displayed : Press the Esc key to ensure you&#8217;re in command mode. Enter the following command to perform the substitution: Press the [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>In the Vi text editor, you can insert two spaces at the beginning of each line using a command called &#8220;substitution.&#8221; Here&#8217;s how you can do it:</p>



<p>when in vi with your text displayed :</p>



<p>Press the Esc key to ensure you&#8217;re in command mode.</p>



<p>Enter the following command to perform the substitution:</p>



<pre class="wp-block-code"><code>:%s/^/  /
</code></pre>



<p>Press the Enter key to execute the substitution command.</p>



<p>Explanation of the command:</p>



<p>%s indicates that the substitution should be done throughout the entire file.<br>^ represents the beginning of each line.<br>/ is the space you want to insert at the beginning of each line. Make sure to type two spaces.</p>



<p><br>Now, each line in the file should start with two spaces. You can verify this by scrolling through the file or using other search and navigation commands in Vi.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.d0wn.com/using-vi-to-insert-spaces-at-the-begining-of-every-line/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>JSON text filtering with jq</title>
		<link>http://www.d0wn.com/json-text-filtering-with-jq/</link>
					<comments>http://www.d0wn.com/json-text-filtering-with-jq/#respond</comments>
		
		<dc:creator><![CDATA[Fabien]]></dc:creator>
		<pubDate>Tue, 14 Mar 2023 15:38:39 +0000</pubDate>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">http://www.d0wn.com/?p=1790</guid>

					<description><![CDATA[I frequently have to intereact with some json files , since bash is the main tool i use day to day i must master the usage of jq, but i noticed that the vast majority of totorials on jq usage just sucks.I&#8217;m going to write some kind of memo to remember the main command that [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>I frequently have to intereact with some json files , since bash is the main tool i use day to day i must master the usage of jq, but i noticed that the vast majority of totorials on jq usage just sucks.<br>I&#8217;m going to write some kind of memo to remember the main command that i use most of the time <br>lets take this dummy contact.json file</p>



<pre class="wp-block-code"><code>{
  "contacts": &#91;
    {
      "name": "John Smith",
      "phone": "(123) 456-7890",
      "email": "john.smith@example.com",
      "sex": "male",
      "position": "Manager",
      "birthday": "1985-06-23",
      "devices": &#91;
        {
          "type": "laptop",
          "model": "MacBook Pro",
          "serial_number": "ABCD1234",
          "issued_date": "2022-01-15"
        },
        {
          "type": "phone",
          "model": "iPhone 12",
          "serial_number": "EFGH5678",
          "issued_date": "2022-01-15"
        }
      ]
    },
    {
      "name": "Jane Doe",
      "phone": "(234) 567-8901",
      "email": "jane.doe@example.com",
      "sex": "female",
      "position": "Sales Representative",
      "birthday": "1990-02-14",
      "devices": &#91;
        {
          "type": "laptop",
          "model": "Dell XPS 13",
          "serial_number": "IJKL9012",
          "issued_date": "2022-03-01"
        }
      ]
    },
    {
      "name": "Bob Johnson",
      "phone": "(345) 678-9012",
      "email": "bob.johnson@example.com",
      "sex": "male",
      "position": "IT Specialist",
      "birthday": "1982-11-30",
      "devices": &#91;
        {
          "type": "laptop",
          "model": "ThinkPad X1 Carbon",
          "serial_number": "MNOP3456",
          "issued_date": "2022-02-10"
        },
        {
          "type": "phone",
          "model": "Samsung Galaxy S21",
          "serial_number": "QRST7890",
          "issued_date": "2022-02-10"
        }
      ]
    }
  ]
}
</code></pre>



<p>to list the name of all the male employes in the json file<br><code>cat contact.json | jq '.contacts[] | select(.sex=="male") | .name'</code></p>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow">
<p>this one is truly awesome , display the name of all employes that are more than 35 years old using their birthday.<br><code>cat contact.json | jq '.contacts[] | select((.birthday | strptime("%Y-%m-%d") | mktime) &lt;= (now - 35*<em>365</em>*24*<em>60</em>*60)) | .name'<br></code></p>
</div></div>



<p>this one is going to list all the phone and their issued date<br><code>cat contact.json | jq '.contacts[].devices[] | select(.type=="phone") | {model: .model, issued_date: .issued_date}'</code></p>



<p>To display the devices issued after 2022-02-12 and their owner&#8217;s name, you can use the following jq command:<br><code>cat contact.json | jq '.contacts[] | {owner: .name, devices: [.devices[] | select(.issued_date &gt; "2022-02-12") ] } | select(.devices != [])'</code></p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.d0wn.com/json-text-filtering-with-jq/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ffmpeg : Only keep one language audio track</title>
		<link>http://www.d0wn.com/ffmpeg-only-keep-one-language-audio-track/</link>
					<comments>http://www.d0wn.com/ffmpeg-only-keep-one-language-audio-track/#respond</comments>
		
		<dc:creator><![CDATA[Fabien]]></dc:creator>
		<pubDate>Sat, 04 Mar 2023 10:23:19 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">http://www.d0wn.com/?p=1788</guid>

					<description><![CDATA[When downloading movies from the internet, you may notice that some titles include the word &#8220;MULTI.&#8221; This indicates that the file contains multiple language options. However, despite the relatively low cost of disk space nowadays, I prefer not to store unnecessary audio tracks that I will never listen to. That is when the invaluable program [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>When downloading movies from the internet, you may notice that some titles include the word &#8220;MULTI.&#8221; This indicates that the file contains multiple language options. <br>However, despite the relatively low cost of disk space nowadays, I prefer not to store unnecessary audio tracks that I will never listen to.</p>



<p>That is when the invaluable program named ffmpeg come to the rescue to eliminate these useless tracks.</p>



<p>You can use the following FFmpeg command to keep only the English audio track and copy the rest of the tracks into an MKV file:</p>



<blockquote class="wp-block-quote"><p><strong>ffmpeg -i &#8220;in.mkv&#8221; -max_muxing_queue_size 1024 -map 0:v -c:v copy  -map 0<code>:a:m:language:en -c:a copy -map 0:s? -c:s copy "out.mkv"</code></strong></p></blockquote>



<p>Here&#8217;s a breakdown of what each part of the command does:<br><br><strong>ffmpeg</strong>: This is the command that starts the FFmpeg program.<br><strong>-i &#8220;in.mkv&#8221;:</strong> This specifies the input file, &#8220;in.mkv&#8221;, that FFmpeg will be working with.<br><strong>-max_muxing_queue_size 1024</strong>: usefull because sometime ffmpeg crash when this is not present.<br><strong>-map 0:v:</strong> This selects the video stream from the input file (stream 0) to include in the output file.<br><strong>-c:v copy</strong>: This copies the video stream from the input file to the output file without any encoding or re-encoding.<br><strong>-map 0:a:m:language:en:</strong> This selects the audio stream from the input file (stream 0), but only if it has the &#8220;en&#8221; language code. This is useful if there are multiple audio tracks in the input file and you only want to include the English track in the output file.<br><strong>-c:a copy: </strong>This copies the selected audio stream from the input file to the output file without any encoding or re-encoding.<br><strong>-map 0:s?:</strong> This selects any subtitle streams from the input file (stream 0), if they exist. The ? makes the subtitle stream optional, so if there are no subtitles in the input file, this won&#8217;t cause an error.<br><strong>-c:s copy: </strong>This copies any selected subtitle streams from the input file to the output file without any encoding or re-encoding.<br><strong>&#8220;out.mkv&#8221;:</strong> This specifies the output file that FFmpeg will create, &#8220;out.mkv&#8221;.</p>



<p>There are many language codes available in FFmpeg for selecting audio and subtitle streams based on language. Here are some examples:</p>



<p>English: <strong>en</strong><br>Spanish: <strong>es</strong><br>French: <strong>fr</strong><br>German: <strong>de</strong><br>Italian: <strong>it</strong><br>Portuguese: <strong>pt</strong><br>Russian: <strong>ru</strong><br>Arabic: <strong>ar</strong><br>Chinese: <strong>zh</strong><br>Japanese: <strong>ja</strong><br>Korean: <strong>ko</strong><br>Hindi: <strong>hi</strong><br>Urdu: <strong>ur</strong></p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.d0wn.com/ffmpeg-only-keep-one-language-audio-track/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Using the REST api to read sensors on Home assistant</title>
		<link>http://www.d0wn.com/using-the-rest-api-to-read-senson-on-home-assistant/</link>
					<comments>http://www.d0wn.com/using-the-rest-api-to-read-senson-on-home-assistant/#respond</comments>
		
		<dc:creator><![CDATA[Fabien]]></dc:creator>
		<pubDate>Tue, 09 Nov 2021 13:42:57 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[Home Assistant]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[script]]></category>
		<guid isPermaLink="false">http://www.d0wn.com/?p=1783</guid>

					<description><![CDATA[During one of my little project of making timelapses videos with some IP cameras, I had the following problem : How do you stop capturing new images at night when the camera see nothing, After all , the sun rise and sun set time are changing everyday ! and i didn&#8217;t see a simple way [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>During one of my little project of making  timelapses videos with some IP cameras, I had the following problem : How do you stop capturing new images at night when the camera see nothing, <br>After all , the sun rise and sun set time are changing everyday ! and i didn&#8217;t see a simple way to calculate this.<br>then i remembered the <a rel="noreferrer noopener" href="https://www.home-assistant.io/integrations/sun/" data-type="URL" data-id="https://www.home-assistant.io/integrations/sun/" target="_blank">sun.sun integration</a> in Home assistant.</p>



<p>If i had a simple way to query this integration in my script , i could very simply stop my script when the sun was no longer present in the sky !</p>



<p class="has-medium-font-size">The Home assistant <a href="https://developers.home-assistant.io/docs/api/rest/" target="_blank" rel="noreferrer noopener">REST API </a></p>



<p>In any home assistant installation there is access to a REST API that lets you do a lot a things , but in my case, I don&#8217;t want much , I just want to know if the sun is above or below the horizon.</p>



<ol><li>Get a Authorization: Bearer token <br>you first have to generate a token to authenticate your request . You have to go to your user section , this is the circle a the bottom of the toolbar, then at the bottom of the page , you can create a long term token , <br>Please take note of this token because Home assitant can only display it one time , if you loose it , you must recreate an other one.</li><li>Then in my script i can use this <br><div class="my-syntax-highlighter"><pre><textarea id="mshighlighter" class="mshighlighter" language="shell" name="mshighlighter" >curl -s -X GET -H "Authorization: Bearer eyJ0eX....G9QCqY" -H "Content-Type: application/json" http://192.168.1.13:8123/api/states/sun.sun |jq -r .state</textarea></pre></div></li><li>it will return either <strong>above_horizon</strong> or <strong>below_horizon</strong>, I can then use this in my script to stop the capture when it&#8217;s below_horizon</li></ol>



<p>I used jq filter the json result , but , if you can&#8217;t or don&#8217;t want to install it , you can replace it with this simple awk <div class="my-syntax-highlighter"><pre><textarea id="mshighlighter" class="mshighlighter" language="shell" name="mshighlighter" > awk -F "\"" {'print $8'}</textarea></pre></div></p>
]]></content:encoded>
					
					<wfw:commentRss>http://www.d0wn.com/using-the-rest-api-to-read-senson-on-home-assistant/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
