Writing a KDE Plasmoid to display JioFi Stats

I've been using Manjaro KDE for a while now, and thought I'd make a KDE Widget to display the information from connected JioFi M2S Router.

Reversing the protocol?

Since we are able to view the details of the router if we visit jiofi.local.html, I visited the site, and checked for networks tab for an API, I was under the assumption that the source code would be obfuscated , and looking at the JavaScript would be tedious. Not being able to gain anything from the Networks tab, I tried viewing the source, and the following snippet caught my eye.

	</head>
<body>
<input type="hidden" id="connectedStatus" value="Attached" />
<input type="hidden" id="imsi" value="XXXX" />
<input type="hidden" id="batterystatus" value="Discharging" />
<input type="hidden" id="batterylevel" value="41%" />
<input type="hidden" id="signalstrength" value="Normal" />
<input type="hidden" id="noOfClient" value="3" />
<input type="hidden" id="devicemodel" value="M2S" />
.
.
.

Not much reversing needed anymore, I could just parse the DOM ( As I'd realize later it's hard to do HTML parsing ) or write a regex to extract these values to display in the widget

Writing the widget

I found this tutorial which saved me a lot of time. A Qt plasmoid is made up of two files the metadata.desktop file which contains the widget metadata, and the main .qml file which renders the widget.

So I can write a widget with two columns of text, to display the details I want, I ended up adding some emoji's to make it prettier

  Column {
Text {
text:"🔋"+ root.chargeIcon+ " : "+ root.batteryPercentage
font.pointSize: 24
}
Text {
text:"📱 : "+ root.noOfClients
font.pointSize: 24
}
Text {
text: "📶 : "+root.signalStrength
font.pointSize: 24
}
}

Then following along the tutorial, I proceeded to add a timer , which will perform an XMLHttpRequest, parse the response body using regex, and update the global variables. I'm trying to match type text between the fixed input tags by using regular expressions htmlBody.match(/<input type="hidden" id="batterystatus" value="(.*)" \/>/)[1]

function parseBody(x){
if (x.responseText) {
// Couldn't parse the HTML , so using regex to extract the values
var htmlBody = x.responseText;
root.batteryPercentage = htmlBody.match(/<input type="hidden" id="batterystatus" value="(.*)" \/>/)[1]
root.noOfClients = htmlBody.match(/<input type="hidden" id="noOfClient" value="(.*)" \/>/)[1]
root.signalStrength = htmlBody.match(/<input type="hidden" id="signalstrength" value="(.*)" \/>/)[1]
var batteryStatus = htmlBody.match(/<input type="hidden" id="batterystatus" value="(.*)" \/>/)[1]
if ( batteryStatus == "Charging" ) {
root.chargeIcon = " ⚡";
}
}
}


function request(url, parseBody) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = (function f() {parseBody(xhr)});
xhr.open('GET', url, true);
xhr.send();
}


Timer {
running: true
triggeredOnStart: true
interval: 60000
onTriggered: request("http://jiofi.local.html", parseBody)
}

And we're done, It finally looks something like this

JioFi Plasmoid

Source Code: https://github.com/anandubajith/jiofi-plasmoid