loading...

Writing a KDE Plasmoid to display JioFi Stats

anandubajith profile image Anandu B Ajith ・2 min read

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

Originally written on my blog here: https://anandu.net/blog/making-a-kde-plasmoid/
Source Code: https://github.com/anandubajith/jiofi-plasmoid

Discussion

pic
Editor guide
 

This is awesome! I wish I had this when I still used JioFi :P

That aside, this is a really interesting project and I would love to use this as a reference and make something like this on my on (I was a Manjaro + KDE user, now switched to Arch + KDE)

 

I also tried making this using electron couldn't find a way to reduce the bundle size of the final app,
You can find the source for for that here, I'd be happy if someone could help me in reducing that

 

electrino seemed promissory when talking about bundle size. Not sure if it'd fit your needs, but it is only for macOS and Windows 10 anyway.

I randomly read a few articles, among them How to Reduce the Size of an Electron App Installer. Looks like it is unlikely to strip its size down to something similar to your project.