Recently I bought a Fitbit Sense watch, it has tons of sensors to measure your health and fitness, I really enjoy its features.

One extra thing that I like is that Fitbit provides an SDK to create new apps and clock faces for your watch, you can use it for the Ionic, Versa and Sense devices and customize your watch, adding the features you want. This SDK is Javascript based, so you must use Javascript to create your apps. But you are not completely tied to Javascript, you can use Typescript and have all the features the language provides to create your apps. In this article, we’ll see how to use Typescript to create a simple clock face.

Setting up your workspace

The Fitbit SDK is mostly web based. You must have a user account, have the Fitbit mobile app installed in your phone and have a device associated with your account (this is needed in order to upload the app to the store). Once you have this set up, you can open Fitbit Studio and start developing your app. To show the result of your app, you must download and install the Fitbit Simulator from here (this is the Windows version, but you can download the Mac version from here).

When you use Fitbit Studio, you must use JavaScript to develop. This is not what we want. We will use what Fitbit calls the CLI (Command Line Interface), to create an app in your local machine. For that, you must have Visual Studio Code installed (you can use another editor that supports JavaScript/TypeScript, if you want) and Node.js.

With this setup, you can start developing your app. In the command line, type:

npx create-fitbit-app fitbit-first

You will have to select if the application is an app or a clockface, its name,  if it has a companion component and the device it will run:

Once it runs, you can change to the folder created by the creator and start code with

code .

You will have something like this:

This is the basic structure of the Fitbit app:

  • In the app folder, you have the index.js file, the entry point for the app
  • In the resources folder, you have the index.view, with an svg file with the main display. You have also the styles.css with the css styles for the view
  • If you take a look at the main folder, you will see a tsconfig.json file. This is a good indication that TypeScript is already installed for the app.

So, as you can see, you can start to use TypeScript immediately, but you won’t have intellisense. For that, you will have to install the types for the SDK. you can do that by opening a terminal in VS Code and running this command:

npx fitbit-sdk-types

With that, you are ready to go. You can rename the main file to index.ts and start running the project. You must start the simulator and run the application. In the terminal, open the Fitbit shell with

npx fitbit

You will see the Fitbit prompt, fitbit$, where you can type commands. You can use the build command to build the app and the install command to install the app on the simulator. Alternatively, you can use the build-install or bi to build and install the app on the simulator. When you do that, you will see Hello World!  in the console and a white face in the simulator.

Let’s start with our clock face. We will create a simple digital clock, that will display the time and date. The first step is to create the UI, in the index.view file. We will add two text elements for the time and the date:

<svg>
  <text id="time" fill="fb-blue" x="50%" y="50%" 
    font-size="80" font-family="System-Regular" 
    text-anchor="middle" >XX:XXx</text>
  <text id="date" fill="fb-light-gray" x="50%" y="80%" 
    font-size="50" font-family="System-Regular" 
    text-anchor="middle" >xxx 99</text>
</svg>
Running this code you will see a black background with two pieces of text:

Now we can start adding the code. Add a new class and name it Clock.ts:

import clock from "clock";

export class Clock {
    public clockCallback: (text: string) => void;

    constructor() {
        clock.granularity = "minutes";
        // Update the clock every tick event
        clock.addEventListener("tick", this.updateClock);
    }

    private updateClock = () => {
        if (!this.clockCallback)
            return;
        const date = new Date();
        const hours = date.getHours();
        const minutes = date.getMinutes();
        const zeroPad = ((n: number) => (n < 10) ? "0" + n : n);
        const time = `${zeroPad(hours)}:${zeroPad(minutes)}`;
        this.clockCallback(time);
    }
}

export default Clock;

In this class, we will set the granularity of the clock to minutes, and add a listener to update the clock on every tick. It will create a string with the current time and pass it to the callback. The callback is set in the main file, after creating a new instance of the clock:

import Clock from "./Clock";
import document from "document";

const timeElement = document.getElementById("time") as TextElement;
const clock = new Clock();
clock.clockCallback = (t) => timeElement.text = t;

With this code, when you run the program, you will see the current time in the simulator:

This is only a 24 hours clock and doesn’t respect the user preferences. We must use the user preferences to set a 12 hour clock:

import clock from "clock";
import {preferences } from "user-settings";

export class Clock {
    public clockCallback: (text: string) => void;

    constructor() {
        clock.granularity = "minutes";

        // Update the clock every tick event
        clock.addEventListener("tick", this.updateClock);
    }

    private updateClock = () => {
        if (!this.clockCallback)
            return;
        const date = new Date();
        let hours = date.getHours();
        const minutes = date.getMinutes();
        let amPm = "";
        const zeroPad = ((n: number) => (n < 10) ? "0" + n : n);
        const twelveHour = preferences.clockDisplay === "12h";
        if (twelveHour)  { 
            amPm = hours > 12 ? "."  : "" ;
            hours = hours % 12 || 12;
          } 
        const time = `${zeroPad(hours)}:${zeroPad(minutes)}${amPm}`;
        this.clockCallback(time);
    }
}

export default Clock;

We will user the preferences from the user settings to retrieve the time display settings, if the user selects a 12 hours display, we will add a “.” after the time to indicate PM. The rest of the code remains the same and, when you run the code, you can see the effect of the user settings in the simulator by going to the User tab and selecting 12 or 24 hours:

Now, we just need to add the date to the display. For that, you must create a new class and name it DateDisplay.ts:

import clock from "clock";

export class DateDisplay {
    private months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
   
    public dateCallback: (text: string) => void;

    constructor() {
        clock.addEventListener("tick", this.updateDate);
    }

    private updateDate = () => {
        if (!this.dateCallback)
            return;
        const currDate = new Date();
        const day = currDate.getDate();
        const month = currDate.getMonth();
        const date = `${this.months[month]} ${day}`;
        this.dateCallback(date);
    }
}

export default DateDisplay;

The code is very similar to the clock. It adds a listener to the tick event and generates a string composed of the month and the day of the current date, then it passes it to the callback, that is subscribed in index.ts:

import Clock from "./Clock";
import DateDisplay from "./DateDisplay"
import document from "document";

const timeElement = document.getElementById("time") as TextElement;
const dateElement = document.getElementById("date") as TextElement;

const clock = new Clock();
clock.clockCallback = (t) => timeElement.text = t;
const dateDisplay = new DateDisplay();
dateDisplay.dateCallback = (d) => dateElement.text = d;

When you run the app, you have the time and date in the display:

Our clock face is ready. It’s a very simple one and doesn’t use the sensor data available in the smartwatch, but it’s enough to get the feeling on what does it take to develop a clock face for the Fitbit using Typescript and VS Code. You can use the environment you are used to and have all the benefits of using Typescript, and still be able to use all the features available in the Fitbit SDK.

If you want to know more, you can go to https://dev.fitbit.com/getting-started/. There are a lot of resources, tutorials and samples to learn how to create your customized clock face.

The full source code for this article is at https://github.com/bsonnino/FitbitApp

 

There are times when you need to convert data from one format to the other and you don’t have any tools to do it, or you must do it so many times that it becomes difficult to do it manually. In this case, writing a C# program may be the easiest thing to do.

The program can’t be very difficult to code, at at some point it will be thrown, the procedure will be disposable. So, we’ll devise a simple way to convert the file (or files).

Let’s say we have a file like this one (obtained here):

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description>
   </book>
   <book id="bk103">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology 
      society in England, the young survivors lay the 
      foundation for a new society.</description>
   </book>
   <book id="bk104">
      <author>Corets, Eva</author>
      <title>Oberon's Legacy</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2001-03-10</publish_date>
      <description>In post-apocalypse England, the mysterious 
      agent known only as Oberon helps to create a new life 
      for the inhabitants of London. Sequel to Maeve 
      Ascendant.</description>
   </book>
   <book id="bk105">
      <author>Corets, Eva</author>
      <title>The Sundered Grail</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2001-09-10</publish_date>
      <description>The two daughters of Maeve, half-sisters, 
      battle one another for control of England. Sequel to 
      Oberon's Legacy.</description>
   </book>
   <book id="bk106">
      <author>Randall, Cynthia</author>
      <title>Lover Birds</title>
      <genre>Romance</genre>
      <price>4.95</price>
      <publish_date>2000-09-02</publish_date>
      <description>When Carla meets Paul at an ornithology 
      conference, tempers fly as feathers get ruffled.</description>
   </book>
   <book id="bk107">
      <author>Thurman, Paula</author>
      <title>Splish Splash</title>
      <genre>Romance</genre>
      <price>4.95</price>
      <publish_date>2000-11-02</publish_date>
      <description>A deep sea diver finds true love twenty 
      thousand leagues beneath the sea.</description>
   </book>
   <book id="bk108">
      <author>Knorr, Stefan</author>
      <title>Creepy Crawlies</title>
      <genre>Horror</genre>
      <price>4.95</price>
      <publish_date>2000-12-06</publish_date>
      <description>An anthology of horror stories about roaches,
      centipedes, scorpions  and other insects.</description>
   </book>
   <book id="bk109">
      <author>Kress, Peter</author>
      <title>Paradox Lost</title>
      <genre>Science Fiction</genre>
      <price>6.95</price>
      <publish_date>2000-11-02</publish_date>
      <description>After an inadvertant trip through a Heisenberg
      Uncertainty Device, James Salway discovers the problems 
      of being quantum.</description>
   </book>
   <book id="bk110">
      <author>O'Brien, Tim</author>
      <title>Microsoft .NET: The Programming Bible</title>
      <genre>Computer</genre>
      <price>36.95</price>
      <publish_date>2000-12-09</publish_date>
      <description>Microsoft's .NET initiative is explored in 
      detail in this deep programmer's reference.</description>
   </book>
   <book id="bk111">
      <author>O'Brien, Tim</author>
      <title>MSXML3: A Comprehensive Guide</title>
      <genre>Computer</genre>
      <price>36.95</price>
      <publish_date>2000-12-01</publish_date>
      <description>The Microsoft MSXML3 parser is covered in 
      detail, with attention to XML DOM interfaces, XSLT processing, 
      SAX and more.</description>
   </book>
   <book id="bk112">
      <author>Galos, Mike</author>
      <title>Visual Studio 7: A Comprehensive Guide</title>
      <genre>Computer</genre>
      <price>49.95</price>
      <publish_date>2001-04-16</publish_date>
      <description>Microsoft Visual Studio 7 is explored in depth,
      looking at how Visual Basic, Visual C++, C#, and ASP+ are 
      integrated into a comprehensive development 
      environment.</description>
   </book>
</catalog>

The first step would be convert the XML structure to a C# class. For this file, doing it manually can be an easy task, but for some files, it’s too much work. Thankfully, we have two easy ways to do it:

  • Using xsd.exe – xsd is a tool that converts xml to C# classes. All you have to do is to open a Visual Studio command prompt (in Visual Studio, go to Tools/Command Prompt) and type:
xsd books.xml
xsd /c books.xsd

The first command will create the Books.xsd file and the second one will create the Books.cs file that can be included in your project.

  • Using Visual Studio – now, Visual Studio has an easy way to convert XML and Json into C# (or VB.NET) classes. Just open the XML file, select the data and copy it to the clipboard. Then, in Visual Studio, create a new class, go to Edit/Paste Special/Paste XML as Classes and voilà- you have the C# class for the XML

With this class, we can read the XML file and deserialize it to an instance of the catalog class:

static void Main(string[] args)
{
    var serializer = new XmlSerializer(typeof(catalog));

    using var reader = new StreamReader("books.xml");
    var catalog = (catalog)serializer.Deserialize(reader);
    reader.Close();
}

Note that we are using the new C# 8 using statement feature to minimize nesting.

Now, we can use the new System.Text.Json namespace, available in .NET Core 3.1 or .NET 5.0, to convert the class to Json:

static void Main(string[] args)
{
    var serializer = new XmlSerializer(typeof(catalog));

    using var reader = new StreamReader("books.xml");
    var catalog = (catalog)serializer.Deserialize(reader);
    reader.Close();

    var options = new JsonSerializerOptions { WriteIndented = true };
    var jsonCatalog = JsonSerializer.Serialize(catalog, options);
    File.WriteAllText("books.json", jsonCatalog);
}

When we execute the code, we have the converter to convert the xml file into json. Yes, it works only with this kind of xml file, but it took us no time to assemble it. As a disposable program, it clearly does its job and you have the tool you need to convert the files.

The full source code for this project is at https://github.com/bsonnino/xmltojson