3

Entity Alias

Required Something like this[![][2]]3

enter image description here

I have created an Entity Alias on Device Type (Suppose having 4 Devices of type Light Sensors), Is it possible to Copy the Thingsboard's Digital Gauge Widget and make a new widget and modify it in such a way that it can display data from 4 devices or n number of devices (Dynamically create the gauges depending on the length of datasources Array).?

lupz
  • 3,620
  • 2
  • 27
  • 43
Raj Sharma
  • 91
  • 1
  • 10

1 Answers1

3

Yes we can :)

For gauge widgets, thingsboard uses a helper object called TbCanvasDigitalGauge. This thing draws a gauge for widgetContext.data[0] onto an existing canvas element.

Based on one of the existing gauge widgets and the code of TbCanvasDigitalGauge I figured out to setup a fake context for each of the gauges to reflect each resolved entity. Hence, the data for each resolved entity is mapped to fakeCtx.data[0] for every gauge.

This is the javascript part of my multi gauge widget:

self.createGauge = function(data, idx) {
    let elementId, canvas, fakeCtx;

    elementId = ['gauge', self.ctx.$scope.$id, idx].join('_');

    // Canvas for the gauge.
    canvas    = document.createElement('CANVAS');
    canvas.id = elementId;
    self.ctx.$container.append(canvas);

    // Fake context for the gauge helper object.
    fakeCtx = {
        $container: self.ctx.$container,
          settings: self.ctx.settings,
              data: [data],
          decimals: self.ctx.decimals,
             units: self.ctx.units,
          isMobile: self.ctx.isMobile,
            $scope: self.ctx.$scope,
             width: self.ctx.width,
            height: self.ctx.height
    };

    return new TbCanvasDigitalGauge(fakeCtx, elementId);
};

self.onInit = function() {
    // Create a gauge for each resolved entity.
    self.ctx.$scope.gauges = self.ctx.defaultSubscription.data.map(self.createGauge);
};

self.onDataUpdated = function() {
    self.ctx.$scope.gauges.forEach(gauge => gauge.update());
};

self.onResize = function() {
    self.ctx.$scope.gauges.forEach(gauge => gauge.resize());
};

self.getSettingsSchema = function() {
    return TbCanvasDigitalGauge.settingsSchema;
};

self.typeParameters = function() {
    return {
        maxDatasources: 1,
        maxDataKeys: 1
    };
};

self.onMobileModeChanged = function() {
    self.ctx.$scope.gauges.forEach(gauge => gauge.mobileModeChanged());
};

The html for the widget is empty, since the script creates the canvas elements dynamically.

lupz
  • 3,620
  • 2
  • 27
  • 43
  • 2
    Works great :) the only things, I had to edit the `maxDatasources` to enable it to be able to receive data from more than one entity. One can also edit the `maxDataKeys` if you want to display several keys from each datasource – DarkCygnus Oct 17 '19 at 19:17