Ubidots offers many off-the-shelf widgets that cover visualization and control needs for your IoT projects. However, in some projects you may want to code your own customized widget. Knowing some of our users have customization needs beyond our white-glove customer service we wanted to better educate users to the capabilities of their data. Using your own HTML/JS/CSS code you can create your own custom widgets.

In this introductory HTML Canvas demo, we will demonstrate a simple development to monitor a non-static variable. For example, temperature on a 0-100 degree scale.

  • For values less than 30 the display will show a Blue LCD Screen
  • For values between 30 and 70 the display will show the normal (green) LCD Screen
  • For values greater than 70, the display will show a Red LCD Screen

To better understand this - check out the final product here. We have made the sliding scale manual for you to understand this application, but the scale can be powered by a sensor's variables or manual control based on your coding and desired application.

 Create a Custom HTML Canvas Widget

Now, let's see how we created this custom widget?

1- Start by logging into your Ubidots application.
For Educational License users click here
For Business/ Industrial License users click here

2- Next, open your Devices tab and click "Add Widget"
The floating action button in the top-right of your dashboard will take you through the creation process.

3- Now in the creation process; there's an option called HTML Canvas to select to begin the creation of your custom widget:

Click on "HTML Canvas" then "Blank"

Then "Blank"

4- After selecting blank, the Editor will appear. This coding box contains 3 tabs: HTML, CSS and JS

The first tab we will insert HTML Code. This code will create the markup for our widget.

HTML CODE: 

<div id="image_background">
  <p>Last value:</p>
  <span id="image_background_text">No data</span>
</div>

5- The second tab is CSS. This code will give style to our HTML markup; HTML by itself is pretty ugly (or maybe we are the only ones who think so).

CSS CODE:

@import url('https://fonts.googleapis.com/css?family=VT323');

#image_background {
  background: url('http://i.imgur.com/uuYygjz.png') 0 / contain no-repeat;
  font-family: "VT323";
  font-size: 25px;
  letter-spacing: 10.5px;
  height: 220px;
  width: 450px;
}

#image_background p, #image_background_text {
  margin: 0;
  left: 75px;
  position: absolute;
}

#image_background p {
  top: 88px;
  font-size: 25px !important;
}

#image_background_text {
  top: 121px;
}

6- The third tab is for Javascript, the business logic code for our widget. This is the only frontend programming language for the web so it is easily designable for your needs.

Javascript CODE:

var $bg = $('#image_background');
var $text = $('#image_background_text');
var lastValue = null;
function changeImage(value) {
  var choose = 'normal';
  var background = {
    blue: 'http://i.imgur.com/ZE0W7Yx.png',
    normal: 'http://i.imgur.com/uuYygjz.png',
    yellow: 'http://i.imgur.com/RHvDkUE.png'
  }
if (value <= 30) {
    choose = 'blue';
    $bg.css('color', 'white');
  } else if (value > 30 && value <= 70) {
    choose = 'yellow';
    $bg.css('color', 'white');
  }
$bg.css('background', 'url(' + background[choose] + ') 0 / contain no-repeat');
}
function getLastValue(variableId, token) {
  var url = 'https://things.ubidots.com/api/v1.6/variables/' + variableId + '/values';
  $.get(url, { token: token, page_size: 1 }, function (res) {
    if (lastValue === null ||res.results[0].value !== lastValue.value) {
      $text.text(res.results[0].value);
      lastValue = res.results[0].value;
      changeImage(lastValue);
    }
  });
}
setInterval(function () {
  getLastValue('590b18547625421b6a04667d', 'wgi6K8TPXTMsHt41tc8jsX2M67hFzH');
}, 2000);


NOTE: The code is pretty simple, in this Javascript we added the display adjustment functions for evaluating range, outlines in red.

7- The section below the canvas window is for importing 3rd party libraries, as you can see, we have an URL added there. This is the Google CDN for jQuery. A CDN is a service given by a third party which hosts this library and lets us use it our applications.

In this demo, we imported our third party library - jQuery - from Google:

https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js

jQuery is a library that will let us manipulate the DOM simply. The DOM is literally everything you see in your browser.

With this final step you have completed your custom color adjusting widget based pre-determined triggers of 30 and 70.
Check out the final product for our custom trigger widget adjusting based on:

  • values less than 30 the display will show a Blue LCD Screen
  • values between 30 and 70 the display will show the normal (green) LCD Screen
  • values greater than 70, the display will show a Red LCD Screen

The final Dashboard Display here.

Wait - You Want One More Layer?

To further display the capabilities of this HTML Canvas, let's keep going. Our widget demo was designed to adjust a display based on triggers (30 & 70). But, what if you wanted to go one more layer and overlay an image onto another image? This is possible too with Ubidots HTML Canvas.

Using an LCD display image, we coded HTML to adjust contrast according to a variables value. LCD screens user an analog input. This lets you change the contrast of the screen by varying the current, we will do something similar here with a new variable.


1- Create a new variable.
I'm going to create this new variable called contrast called Ubidots.


2- Use the new assets of the screen.
As we are just modifying the display of the LCD screen, we need to separate the display screen from the boarder. We will work with two images: The LCD screen body and the LCD display.

3- Let's take a look back to our example and edit it to incorporate this new layer

Our adjusted HTML code will be:

<div id="image_background">
 
  <img id="display_background" src="http://i.imgur.com/meoKhMG.png" />
 
  <p>Last value:</p>
  <span id="image_background_text">No data</span>
</div>

The new CSS code will be:

@import url('https://fonts.googleapis.com/css?family=VT323');

#image_background {
  background: url('http://i.imgur.com/ehNdUxY.png') 0 / contain no-repeat;
  font-family: "VT323";
  font-size: 25px;
  letter-spacing: 10.5px;
  height: 220px;
  width: 450px;
}

#image_background p, #image_background_text {
  margin: 0;
  left: 75px;
  position: absolute;
}

#image_background p {
  top: 88px;
  font-size: 25px !important;
}

#image_background_text {
  top: 121px;
}

#display_background {
  height: 94px;
  position: absolute;
  top: 70px;
  left: 52px;
  pointer-events: none;
}

Lastly, the new JS code is:

var $bg = $('#display_background');
var $text = $('#image_background_text');
var lastValue = null;
var lastContrast = null;
var TOKEN = 'YOUR TOKEN';
var scale = d3.scaleLinear().range([0, 4]).domain([0, 1023])

function getLastValue(variableId, token, cb) {
  var url = 'https://things.ubidots.com/api/v1.6/variables/' + variableId + '/values';
  $.get(url, { token: token, page_size: 1 }, function (res) {
    if (typeof cb === 'function') cb(res);
  });
}

setInterval(function () {
  // Get LCD Screen last value
  getLastValue('YOUR LAST VALUE VARIABLE ID', TOKEN, function (res) {
    var value = null;
    try {
    value = res.results[0].value;
    } catch (e) {
      console.log('No data');
    }
  if ((lastContrast === null || value !== lastContrast.value) && value !== null) {
      $text.text(value);
      lastValue = value;
    }
  });
 
  // Get LCD Screen contrast
  getLastValue('YOUR CONTRAST VALUE VARIABLE ID', TOKEN, function (res) {
    var value = null;
    try {
    value = res.results[0].value;
    } catch (e) {
      console.log('No data');
    }
  if ((lastContrast === null || value !== lastContrast.value) && value !== null) {
 $bg.css('filter', 'contrast(' + scale(value) + ')');
      lastContrast = value;
    }
  });
 
}, 2000);


An example can be seen here: https://app.ubidots.com/ubi/public/getdashboard/page/wKyYTxt6bcaM3o-nFMOglR2NrAI/

Thank you for learning a little bit more about Ubidots and our HTML Canvas widget. Now it is your turn to build a custom widget tailored to your specific application needs. 

If you develop something amazing, please share it with us on Facebook, Twitter, or Youtube. 

Did this answer your question?