• Categories
  • Recent
  • Tags
  • Popular
  • Register
  • Login
  • Categories
  • Recent
  • Tags
  • Popular
  • Register
  • Login

Custom widget

Scheduled Pinned Locked Moved Dashboard
custom widgetguagedashboard
43 Posts 5 Posters 33.0k Views 3 Watching
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    jkandasa
    last edited by jkandasa 4 Nov 2020, 23:36 1 Aug 2016, 06:29

    You can create any type of widget with Custom widget support.

    Steps:

    • Add third party js and/or css files on HTML additional headers
    • Add script to get data from MyController
    • Add Template how you want to display your data.

    Example:
    Now I'm going to show, how we can add a Gauge widget with the help of Custom widget

    First add required js and/or css files. In our case we need this js file.
    How to use, we can use either way, with internet or local. If you want to use it from internet get a link from cdn server(https url needed if you are using https protocol for MyController). CDN location. You can use any cnd which supports HTTPS

    NOTE: If you do not want to get every time from internet, download this file and put it on mycontroller/www/mylib/gauge.min.js.

    Put this url in Utilities >> HTML additional headers >> script files and save it. If you have downloaded the file locally, you have to enter https://<mycontrollerip>:8443/mylib/gauge.min.js

    0_1470030993827_upload-7a773b78-c825-47f5-9784-c8a9a830a015

    IMPORTANT: You have to refresh your browser [F5] now

    It is time to create script file(Javascript😞

    //Load sensor variable data with UID-TAG identification
    var temperatureSen = mcApi.uidTag().getByUid("my-sensor-1").getResource(); 
    //Generate UUID, for html widget
    var uuid = mcApi.utils().getUUID();
    

    Steps in script:

    • I want to use UID tags to avoid complications when selecting sensor on script. So I have named my temperature sensor as my-sensor-1 with the help of UID Tags as shown below,
      0_1470031857193_upload-318bd574-76db-4291-95d3-35d098552788
    • Now get the sensor variable with UID api, as show in script var temperatureSen = mcApi.uidTag().getByUid("my-sensor-1"); and store it in bindings temperatureSen.
    • When creating custom widgets, you may use more than one widgets on the same dashboard, in this case always use unique id for widget name in template script. load a unique id(uuid) in script itself with the help of var uuid = mcApi.utils().getUUID().

    You are done! Now we have to create a template to display in dashboard.

    Template file,

    <div id="wrapper" style="text-align: center">    
      <canvas id="my-gauge-${uuid}" style="display: inline-block;"></canvas>
      <div style="font-size:21px" id="textfield--${uuid}"></div>
    </div>
    <script>
      var opts = {
        lines: 12, // The number of lines to draw
        angle: 0, // The length of each line
        lineWidth: 0.24, // The line thickness
        pointer: {
          length: 0.9, // The radius of the inner circle
          strokeWidth: 0.035, // The rotation offset
          color: '#000066' // Fill color
        },
        colorStart: '#6FADCF',   // Colors
        colorStop: '#8FC0DA',    // just experiment with them
        strokeColor: '#E0E0E0',   // to see which ones work best for you
        generateGradient: true
      };
      var target = document.getElementById('my-gauge-${uuid}'); // your canvas element
      var gauge = new Gauge(target).setOptions(opts); // create sexy gauge!
      gauge.animationSpeed = 5; // set animation speed (32 is default value)
      gauge.maxValue = 200; //Maximum value
      gauge.setTextField(document.getElementById("textfield--${uuid}"));
      gauge.set(${temperatureSen.value}); // set actual value
    </script>
    
    • You can call bindings from script with ${} notation, if you want to place uuid call it as ${uuid}, to get sensor value call it as ${temperatureSen.value}. You can use this and replace wherever you want on template.

    All done! Create a custom widget and map both of script and Template that we create on above steps.
    0_1470032468081_upload-e3f3a699-bc6d-4586-ae0e-23b3596086c6

    Extra section

    Script:
    0_1470032598923_upload-7f3daf0a-55a2-4ffd-a363-160fb2263336

    Template:
    0_1470032636889_upload-4e7ff5aa-3d05-450a-9872-1a0d0ce33c0d

    You can test your script/template before adding in to dashboard,
    To test script, select your script and on Actions click on Run now (on the popup click on Run) will get as follows,
    0_1470032799536_upload-deb44409-6db1-4f26-b5d6-cdff769abd3d

    You can test your template, select your template and on Actions click on Run now and on the popup select your script file and click on Run, you will get your widget that you will see on dashboard.
    0_1470032858751_upload-df419d20-6b12-4deb-9e73-86283bcbe1b2

    R 1 Reply Last reply 16 Dec 2016, 16:40 Reply Quote 0
    • T Offline
      Tag MOD
      last edited by 3 Aug 2016, 07:38

      Many thnks for the great explanation!!

      I setup the example and played around with it and it works fine in chrome on my PC, however on my chrome book and phone, the graph stays empty...In both non working browsers, javascript is enabled and the example shown here http://jsfiddle.net/berni/Yb4d7/ works in both browsers.

      any idea what could be the issue here?

      J 1 Reply Last reply 3 Aug 2016, 08:12 Reply Quote 0
      • J Offline
        jkandasa @Tag
        last edited by 3 Aug 2016, 08:12

        @Tag Have you refreshed your browser in your chrome book and on your phone(F5) and clear cache. If it is not working till, can see any error on console?

        1 Reply Last reply Reply Quote 0
        • T Offline
          Tag MOD
          last edited by 3 Aug 2016, 19:44

          YEAY!! victory, clearing all cache and refresh worked on the chrome book

          thanks!

          1 Reply Last reply Reply Quote 1
          • T Offline
            Tag MOD
            last edited by jkandasa 7 Aug 2016, 20:17

            This HTML script will give you a gauge that will change color based on the value of the scale in percentage.
            The script below has a scale range 0-5000. (I use it to measure my KWH usage)....

            Here is the trick i experimented with

            limitMax: 'false', 
              percentColors: [[0.0, "#a9d70b" ], [0.80, "#f9c802"], [1.0, "#ff0000"]], // !!!!
              strokeColor: '#b0b0b0',
                generateGradient: true
            

            From 0% - 80% the scale is green to yellow at the 80%, the from 80%-100% it will rapidly change to red....

            Green: #a9d70b
            Orange #f9c802
            Red #ff0000
            

            I also made the value font, bold by adding this ; font-weight:bold

            And with this line you can set the maximum value of the gauge gauge.maxValue = 5000; lower it to something that comes close to the max value you want to measure.

            Really nice effect!

            -------------- Cut ----------------

            <div id="wrapper" style="text-align: center">    
              <canvas id="my-gauge-${uuid}" style="display: inline-block;"></canvas>
              <div style="font-size:21px ; font-weight:bold" id="textfield--${uuid}"></div>
            </div>
            <script>
              var opts = {
                  lines: 12,
              angle: 0.05,
              lineWidth: 0.44,
              pointer: {
                length: 0.9,
                strokeWidth: 0.035,
                color: '#303030'
                },
            limitMax: 'false', 
              percentColors: [[0.0, "#a9d70b" ], [0.80, "#f9c802"], [1.0, "#ff0000"]], // !!!!
              strokeColor: '#b0b0b0',
                generateGradient: true
              };
              var target = document.getElementById('my-gauge-${uuid}'); // your canvas element
              var gauge = new Gauge(target).setOptions(opts); // create sexy gauge!
              gauge.animationSpeed = 3; // set animation speed (32 is default value)
              gauge.maxValue = 5000; //Maximum value
              gauge.setTextField(document.getElementById("textfield--${uuid}"));
              gauge.set(${temperatureSen.value}); // set actual value
            </script>
            
            <!--see http://jsfiddle.net/berni/Yb4d7/ for example-->
            

            -------------- Cut ----------------

            1 Reply Last reply Reply Quote 1
            • R Offline
              Redferne @jkandasa
              last edited by 16 Dec 2016, 16:40

              @jkandasa

              Thanks for showing this. It makes it very versatile. However for the Temperature example above, how do I get all decimals? I'd like the Temperature to show for example "23.45°C"

              ///Redferne

              J 1 Reply Last reply 16 Dec 2016, 16:46 Reply Quote 0
              • J Offline
                jkandasa @Redferne
                last edited by 16 Dec 2016, 16:46

                @Redferne

                how do I get all decimals? I'd like the Temperature to show for example "23.45°C"

                I guess it is limitation of http://bernii.github.io/gauge.js/dist/gauge.min.js or we may have some option to show decimal points. Kindly refer http://bernii.github.io/gauge.js

                R 1 Reply Last reply 16 Dec 2016, 16:48 Reply Quote 0
                • R Offline
                  Redferne @jkandasa
                  last edited by 16 Dec 2016, 16:48

                  @jkandasa

                  Nope, Gauge handles decimals and negative values just fine. See here:
                  http://jsfiddle.net/berni/smNjl/

                  J 1 Reply Last reply 19 Dec 2016, 02:19 Reply Quote 0
                  • J Offline
                    jkandasa @Redferne
                    last edited by jkandasa 19 Dec 2016, 02:19

                    @Redferne

                    Can you try this line

                      gauge.set(${temperatureSen.value}); // set actual value
                    
                    

                    with this,

                      gauge.set(parseFloat(${temperatureSen.value})); // set actual value
                    
                    1 Reply Last reply Reply Quote 0
                    • R Offline
                      Redferne
                      last edited by jkandasa 20 Dec 2016, 14:30

                      @jkandasa said:

                      gauge.set(parseFloat(${temperatureSen.value}));

                      Solution was little more complicated:

                      <div id="wrapper" style="text-align: center">    
                        <canvas id="my-gauge-${uuid}" style="display: inline-block;"></canvas>
                        <div style="font-size:21px" id="textfield--${uuid}"></div>
                      </div>
                      <script>
                        var CustomTextRenderer = function(el){
                          this.el = el;
                          this.render = function(gauge) {
                            this.el.innerHTML = gauge.displayedValue.toPrecision(3);
                           }
                        }
                        CustomTextRenderer.prototype = new TextRenderer();
                        var cs = new CustomTextRenderer(document.getElementById("textfield--${uuid}"));
                        var opts = {
                          lines: 32,
                          angle: 0,
                          lineWidth: 0.24,
                          pointer: {
                            length: 0.9,
                            strokeWidth: 0.035,
                            color: '#000066'
                          },
                          limitMax: 'false', 
                          percentColors: [[0.0, "#2B31CF" ], [0.60, "#37CF32"], [1.0, "#ff0000"]],
                          strokeColor: '#E0E0E0',
                          generateGradient: true
                        };
                        var target = document.getElementById('my-gauge-${uuid}');
                        var gauge = new Gauge(target).setOptions(opts);
                        gauge.animationSpeed = 3;
                        gauge.maxValue = 40.0;
                        gauge.setMinValue(-30.0);
                        gauge.setTextField(new CustomTextRenderer(document.getElementById("textfield--${uuid}")))
                        gauge.set(${temperatureSen.value});
                      </script>
                      
                      1 Reply Last reply Reply Quote 1
                      • E Offline
                        esawyja
                        last edited by 3 Jan 2017, 10:16

                        Hi all,
                        Brilliant program @jkandasa , I'm having some issues with the gauge display, I don't see the gauge when I test the template. I'm using Firefox, cleared the history and cache. even tried it with Microsoft Edge, but my gauge does not display. Rebooted the RaspBerry PI as well, I don't see any errors in the logs etc, could someone point me in the right direction please, see screenshots below
                        Regards

                        0_1483438450608_image.png

                        0_1483438485395_image.png

                        0_1483438519652_image.png

                        0_1483438562379_image.png

                        0_1483438603778_image.png

                        1 Reply Last reply Reply Quote 0
                        • E Offline
                          esawyja
                          last edited by 3 Jan 2017, 10:19

                          The location of the gauge.min.js
                          0_1483438777925_image.png

                          J 1 Reply Last reply 3 Jan 2017, 10:26 Reply Quote 0
                          • J Offline
                            jkandasa @esawyja
                            last edited by 3 Jan 2017, 10:26

                            @esawyja You have to add gauge.min.js as mentioned here,
                            0_1470030993827_upload-7a773b78-c825-47f5-9784-c8a9a830a015.

                            Once done, reload your browser.

                            1 Reply Last reply Reply Quote 0
                            • E Offline
                              esawyja
                              last edited by 3 Jan 2017, 10:36

                              Hi
                              Sorry yes I did, I just forgot to include the screenshot, still not seeing the gauge, any other suggestions please

                              0_1483439762387_image.png

                              J 1 Reply Last reply 3 Jan 2017, 10:39 Reply Quote 0
                              • J Offline
                                jkandasa @esawyja
                                last edited by 3 Jan 2017, 10:39

                                @esawyja can you post your gauge HTML template and javaScript code?

                                1 Reply Last reply Reply Quote 0
                                • E Offline
                                  esawyja
                                  last edited by jkandasa 3 Jan 2017, 10:42

                                  Sure, see below
                                  0_1483440109921_image.png

                                  Below is the template file

                                  <div id="wrapper" style="text-align: center">    
                                    <canvas id="my-gauge-${uuid}" style="display: inline-block;"></canvas>
                                    <div style="font-size:21px" id="textfield--${uuid}"></div>
                                  </div>
                                  <script>
                                    var CustomTextRenderer = function(el){
                                      this.el = el;
                                      this.render = function(gauge) {
                                        this.el.innerHTML = gauge.displayedValue.toPrecision(3);
                                       }
                                    }
                                    CustomTextRenderer.prototype = new TextRenderer();
                                    var cs = new CustomTextRenderer(document.getElementById("textfield--${uuid}"));
                                    var opts = {
                                      lines: 32,
                                      angle: 0,
                                      lineWidth: 0.24,
                                      pointer: {
                                        length: 0.9,
                                        strokeWidth: 0.035,
                                        color: '#000066'
                                      },
                                      limitMax: 'false', 
                                      percentColors: [[0.0, "#2B31CF" ], [0.60, "#37CF32"], [1.0, "#ff0000"]],
                                      strokeColor: '#E0E0E0',
                                      generateGradient: true
                                    };
                                    var target = document.getElementById('my-gauge-${uuid}');
                                    var gauge = new Gauge(target).setOptions(opts);
                                    gauge.animationSpeed = 3;
                                    gauge.maxValue = 40.0;
                                    gauge.setMinValue(-30.0);
                                    gauge.setTextField(new CustomTextRenderer(document.getElementById("textfield--${uuid}")))
                                    gauge.set(${temperatureSen.value});
                                  </script>
                                  
                                  jkandasaJ 1 Reply Last reply 3 Jan 2017, 10:59 Reply Quote 0
                                  • jkandasaJ Offline
                                    jkandasa @esawyja
                                    last edited by 3 Jan 2017, 10:59

                                    @esawyja I use this lib and works as expected for your script, https://cdnjs.cloudflare.com/ajax/libs/gauge.js/1.2.1/gauge.min.js

                                    0_1483441169722_upload-ea83be23-e0e8-44dd-8622-a64a9d44d960

                                    E 1 Reply Last reply 3 Jan 2017, 11:08 Reply Quote 0
                                    • E Offline
                                      esawyja @jkandasa
                                      last edited by 3 Jan 2017, 11:08

                                      mmmh ok, then it must be something else
                                      0_1483441444970_image.png

                                      Still getting nothing
                                      0_1483441499925_image.png

                                      Even using Microsoft edge after clearing browser cache, history etc
                                      0_1483441642806_image.png

                                      1 Reply Last reply Reply Quote 0
                                      • E Offline
                                        esawyja
                                        last edited by 3 Jan 2017, 11:11

                                        This is how I clear the cache

                                        0_1483441886704_image.png

                                        jkandasaJ 1 Reply Last reply 3 Jan 2017, 11:18 Reply Quote 0
                                        • jkandasaJ Offline
                                          jkandasa @esawyja
                                          last edited by jkandasa 1 Mar 2017, 16:51 3 Jan 2017, 11:18

                                          @esawyja I have updated this script on our demo server too. You can have a look at http://demo.mycontroller.org/#/dashboard, you can see a dashboard named esawyja

                                          Steps:

                                          1. Create UID tag for your temperature sensor
                                          2. Create Javascript to return value to HTML template
                                          3. Create HTML template
                                          4. Add you javaScript on script files, reload MC server page on your browser
                                          5. Create custom widget with template(step#3) and script(step#2), done! 🙂

                                          IMPORTANT: I believe you are with latest SNAPSHOT version.

                                          1 Reply Last reply Reply Quote 0
                                          • First post
                                            Last post

                                          0

                                          Online

                                          628

                                          Users

                                          532

                                          Topics

                                          3.4k

                                          Posts
                                          Copyright © 2015-2025 MyController.org | Contributors | Localization