Friday, February 19, 2021

Linux script to display Some information of MP3 files

 The following bash script utilizes mediainfo command line to retrieve various metadata inside an MP3 (or any media file, in fact):


#!/bin/sh

i=0
for f in "$@"
do
    i=$((i+1))
    printf "%d," $i
    mediainfo --Inform="General;%CompleteName%,%Format%,%OverallBitRate_Mode%,%BitRate%,%FileSize/String4%" "${f}"
done





For example (I put the above into a script named 'bitrate.sh'):

$ bitrate.sh *.mp3
1,01_-_bohemian_rhapsody_-_queen_-_greatest_hits_cd1.mp3,MPEG Audio,CBR,256000,10.94 MiB
2,05_-_bicycle_race_-_queen_-_greatest_hits_cd1.mp3,MPEG Audio,CBR,256000,5.612 MiB
3,07_-_it's_a_hard_life_-_queen_-_greatest_hits_cd2.mp3,MPEG Audio,CBR,256000,7.620 MiB
4,09_-_who_wants_to_live_forever_-_queen_-_greatest_hits_cd2.mp3,MPEG Audio,CBR,256000,9.075 MiB
5,11_-_the_miracle_-_queen_-_greatest_hits_cd2.mp3,MPEG Audio,CBR,256000,9.002 MiB
6,15_-_friends_will_be_friends_-_queen_-_greatest_hits_cd2.mp3,MPEG Audio,CBR,256000,7.599 MiB
7,16_-_the_show_must_go_on_-_queen_-_greatest_hits_cd2.mp3,MPEG Audio,CBR,256000,8.048 MiB
8,16_-_we_will_rock_you_-_queen_-_greatest_hits_cd1.mp3,MPEG Audio,CBR,256000,3.741 MiB
9,17_-_we_are_the_champions_-_queen_-_greatest_hits_cd1.mp3,MPEG Audio,CBR,256000,5.542 MiB


The output is in CSV, suitable to be imported as a table in spreadsheet.

Sunday, December 20, 2020

Plex Server inaccessible with LG TV nor Ipone

 I recently had access issue to my Plex server (running on Linux).  It was fine sometime ago, but lately everytime I tried to access it from my LG TV or my phone, they said the server was offline. I'd followed various instructions and troubleshooting I found on the Internet with no luck.  Here is the list of steps I did:

  • Ensure no VPN running on all devices and server
  • Select "Preferred" for secure connection
  • Added my private subnet in the "List of IP addresses and networks that are allowed without auth"
  • Upgrade the Plex server to the latest
  • Restart the server (e.g., "sudo service plexmediaserver restart")
  • Verify I am able to access the server through its IP (e.g, http://192.168.1.103:32400)
  • Enable DLNA server
  • Revert the Plex on TV to last publicly available version
  • Power down TV, wait 2 minutes and turn it back on

Turned out it was due to IPv6 connection was enabled on the Plex server! Once I disabled it, now I could watch my movies or stream my music to other devices.  My LG TV apparently did not support IPv6 yet.

Saturday, November 14, 2020

My Indentation configuration

 The content of $HOME/.indent.pro:


-as

-lp

-bad

-bap

-bbb

-bbo

-bli0

-nbc -c33 -cd33 -ncdb -nce -ci4 -cli0

-c4

-ncdw

-cp33 -cs -d0 -di1 -nfc1 -nfca -hnl -i8 -ip0 -l75 -lp -npcs

-nprs -npsl -saf -sai -saw -nsc -nsob -nss

-v

Sunday, July 5, 2020

Refoss Smart Wi-Fi Garage Door Opener

I bought an "add-on" device that will enable my garage door opener accessible via WiFi, as well as other automated processes as part of my home automation project last year.  I bought it on Amazon: https://www.amazon.com/Refoss-Garage-Control-Compatible-Assistant/dp/B07PM59X4J/ref=cm_cr_arp_d_product_top?ie=UTF8&th=1

It had been working perfectly since I installed it last year, but since the last few days ago it has stopped.  I thought it must be something with the networking, so I followed the procedure instructed on the manual to configure it as a new device added to the eHomeLife on my iPhone, but with no luck.  The manual says, if the WiFi LED blinks rapidly, the device has been correctly set to access our home network.  But, I have not been able to connect my app to the device.

Curious to see what was going on, I logged on to my AP router and could see the device had been assigned a valid IP address (192.168.1.55) and I could even ping it.  That's all. I then did nmap to the device to see what ports were open.  I could only see the following:

nmap -O -sO 192.168.1.55
WARNING: Disabling OS Scan (-O) as it is incompatible with the IPProto Scan (-sO)
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-05 21:44 Pacific Daylight Time
Nmap scan report for 192.168.1.55
Host is up (0.021s latency).
Not shown: 252 closed protocols
PROTOCOL STATE         SERVICE
1        open          icmp
6        open          tcp
17       open          udp
41       open|filtered ipv6
MAC Address: 48:E1:E9:51:07:50 (Chengdu Meross Technology)

Actually, if I press the WiFi button for more than 5 seconds to make it goes to configuration mode and then use the SSID of the device (it becomes an "AP" device temporarily), then open a browser to access it (at IP address 10.10.10.1, because my phone's IP was assigned 10.10.10.2), I could see basic web interface to set WIFI as well as to upgrade firmware.

Googling for "Meross" or "Refoss" firmware couldn't give anything.  The company's website also doesn't give any link or information about any firmware upgrade.  Also, What's the difference between "Meross" and "Refoss"? Is Refoss is a knock-off of Meross?  Both are Chinese companies.

Honestly, I am now tempted to develop a similar by myself, probably using ESP32 (as using Raspberry-Pi for such thing is too much for such thing, not to consider more power-hungry).

Thursday, July 2, 2020

Mac Hash Table


 1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>


static unsigned char PseudoRandomHash[256] = {
     1,   87,   49,  12, 176, 178,  102, 166, 121, 193,   6,  84, 249, 230,  44,  163, 
     14, 197,  213, 181, 161,  85,  218,  80,  64, 239,  24, 226, 236, 142,  38,  200, 
    110, 177,  104, 103, 141, 253,  255,  50,  77, 101,  81,  18,  45,  96,  31,  222, 
     25, 107,  190,  70,  86, 237,  240,  34,  72, 242,  20, 214, 244, 227, 149,  235, 
     97, 234,   57,  22,  60, 250,   82,  175, 208,   5, 127, 199, 111,  62, 135,  248, 
    174, 169,  211,  58,  66, 154,  106, 195, 245, 171,  17, 187, 182, 179,   0,  243, 
    132,  56,  148,  75, 128, 133,  158, 100, 130, 126,  91,  13, 153, 246, 216,  219,
    119,  68,  223,  78,  83,  88,  201,  99, 122,  11,  92,  32, 136, 114,  52,   10, 
    138,  30,   48, 183, 156,  35,   61,  26, 143,  74, 251,  94, 129, 162,  63,  152, 
    170,   7,  115, 167, 241, 206,    3, 150,  55,  59, 151, 220,  90,  53,  23,  131, 
    125, 173,   15, 238,  79,  95,   89,  16, 105, 137, 225, 224, 217, 160,  37,  123, 
    118,  73,    2, 157,  46, 116,    9, 145, 134, 228, 207, 212, 202, 215,  69,  229, 
     27, 188,   67, 124, 168, 252,   42,   4,  29, 108,  21, 247,  19, 205,  39,  203, 
    233,  40,  186, 147, 198, 192,  155,  33, 164, 191,  98, 204, 165, 180, 117,   76, 
    140,  36,  210, 172,  41,  54,  159,   8, 185, 232, 113, 196, 231,  47, 146,  120, 
     51,  65,   28, 144, 254, 221,   93, 189, 194, 139, 112,  43,  71, 109, 184,  209}; 
     
#define N   256
     
     
int PearsonHash(uint64_t macAddr)
{
    int i;
    uint8_t h[sizeof(uint64_t)];
    int result;
    
	bzero(h, sizeof(h));
    for(i=1; i<sizeof(h); i++)
    {
		uint8_t byte = (uint8_t)(macAddr & 0xff);
        h[i] = PseudoRandomHash[(h[i-1] ^ byte) & 0xFF];
		macAddr >>= 8;
        result = h[i];
    }
    return result;
}


typedef struct
{
	uint64_t macAddr;
	int		 aid;
} RecordT;


RecordT* buildHashTable(int sz)
{
	RecordT *p = calloc(sz, sizeof(RecordT));
	return p;
}

void addRecord(RecordT* table, RecordT* rec)
{
	int slot = PearsonHash(rec->macAddr);
	table[slot].macAddr = rec->macAddr;
	table[slot].aid = rec->aid;
}

RecordT* findRecord(RecordT *table, uint64_t mac)
{
	int slot = PearsonHash(mac);
	return &table[slot];
}
     
int main()
{
    int i;
    int n;
    const uint64_t MacBase = 0x000011BABEBEEF00ULL;
    uint64_t macTable[N];
    
    for(i=0; i<N; i++)
    {
        printf(" %03u ", PseudoRandomHash[i]);
        if ((i+1)%16 == 0)
            printf("\n");
    }

	RecordT *hashTable = buildHashTable(N);

    for(i=0; i<N; i++)
    {
		uint64_t mac;
        macTable[i] = mac = MacBase + i;
	}

	for(i=0; i<N; ++i)
	{
		RecordT rec;
		rec.macAddr = macTable[i];
		rec.aid = N-i;
		addRecord(hashTable, &rec);
    }

    for(i=0; i<N; i++)
    {
        printf("%d\t %08lX: \tSlot=%u\n", i, macTable[i], PearsonHash(macTable[i]));
    }

	for(int k=0; k<N; ++k)
	{
		uint64_t mac = macTable[k];
		RecordT *p = findRecord(hashTable, mac);
    	printf("mac[%d]=%08lX \trec(%08lX,%d)\n", k, macTable[k], p->macAddr, p->aid);
	}

	free(hashTable);
}  

Wednesday, June 17, 2020

Raspberry PI 3 Model B Rev 1.2 Power Wattage

My order of USB power meter arrived a few days ago, but only today I could put it into use by plugging it in between the power supply adapter and my RPI.

The way I test the max power consumed is by creating a small C program to do infinite loop such as:

int main()
{
   while (1) {}
}

I executed it in four separate processes (open four terminals, and run the program in each one). This way I could exhaust the whole four cores in the CPU.  I also GUI desktop on the machine (LXDE).

Here what is shown by "top":




My USB power meter shows 1.17 WH, meaning in each hour it consumes 2.37 Watt or 0.00237 KWh.  If the price per kWh charged by Utility company is 12.01 cent ($0.1201/KWH), in a day I'd pay 0.00237 KWh* $0.1201/KWh * 24 hours = $‭0.006831288‬ or about $0.0068 per day.  In a month I'd pay about $0.2 minimum.

After I killed all those four infinite loop processes, the wattage did not drop.  Instead I saw it climbed to almost 2 Watt-hour.  I think over time it probably would drop back to around 2 W (idling time).