cetax

MMM-fronius.js

Jun 6th, 2020
93
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. "use strict";
  2.  
  3. Module.register("MMM-fronius", {
  4.  
  5.   firstUpdate: true,
  6.   result: {},
  7.   defaults: {
  8.     prettyName: true,
  9.     stripName: true,
  10.     title: "PV Anlage",
  11.     url: "", // Deprecated
  12.     urls: [], // Added as a new parameter to maintain backwards compatibility
  13.     ipaddfr: [],  //Inverter Ip Address from Config
  14.  
  15.  
  16.     updateInterval: 50,
  17.     singleLine: false,
  18.     values: [
  19.         'Body.Data.Inverters.1.P',  //Solar output from Json
  20.         'Body.Data.Site.P_Grid', //Grid Draw from Json
  21.         'Body.Data.Site.P_Load',  //Total load from Json
  22.         'Body.Data.Inverters.1.E_Day', // Tages Ertrag
  23.         'Body.Data.Inverters.1.E_Total' // Gesamt Ertrag
  24.         ],
  25.     //Give everything Pretty names that make sense
  26.     replaceName: [
  27.                 ["P", "Aktuell "],
  28.                 ["P_Grid", "Einspeisen "],
  29.                 ["P_Load", "Verbrauch "],
  30.                 ["E_Day", "Tag "],
  31.                 ["E_Total", "Gesamt "],
  32.     ],
  33.         arrayName: "",
  34.     arraySize: 999
  35.   },
  36.  
  37.   start: function() {
  38.  
  39. var ipaddfr = this.config.ipaddfr;  //Define ip address var and send to console
  40.  console.log("Fronius inverter ip:" + ipaddfr);
  41.  
  42.         this.getStats();
  43.         this.scheduleUpdate();
  44.  
  45.  
  46.          },
  47.  
  48.   isEmpty: function(obj) {
  49.     for(var key in obj) {
  50.       if(obj.hasOwnProperty(key)) {
  51.         return false;
  52.       }
  53.     }
  54.  
  55.     return true;
  56.   },
  57.  
  58.   getDom: function() {
  59.     var wrapper = document.createElement("ticker");
  60.     wrapper.className = "dimmed small";
  61.  
  62.     var data = this.result;
  63.     var statElement =  document.createElement("header");
  64.     var title = this.config.title;
  65.     statElement.innerHTML = title;
  66.     wrapper.appendChild(statElement);
  67.  
  68.     if (data && !this.isEmpty(data)) {
  69.       var tableElement = document.createElement("table");
  70.       var values = this.config.values;
  71.  
  72.       if (this.config.arrayName.length > 0) {
  73.         try {
  74.           data = this.byString(data, this.config.arrayName);
  75.  
  76.         if (data && data.length) {
  77.             for (var i = 0; i < data.length && i < this.config.arraySize; i++) {
  78.               this.addValues(data[i], values, tableElement);
  79.  
  80.                  if (i < data.length - 1) {
  81.                 var hr = document.createElement("hr");
  82.                 hr.style = "border-color: #444;"
  83.                 tableElement.appendChild(hr);
  84.               }
  85.             }
  86.           } else {
  87.             this.addValues(data, values, tableElement);
  88.           }
  89.         } catch (e) {
  90.           console.error(e);
  91.           this.addValues(data, values, tableElement);
  92.         }
  93.       } else {
  94.         this.addValues(data, values, tableElement);
  95.       }
  96.  
  97.       wrapper.appendChild(tableElement);
  98.     } else {
  99.       var error = document.createElement("span");
  100.       error.innerHTML = this.firstUpdate ? "Lade Daten ..." : "Error fetching stats.";
  101.       wrapper.appendChild(error);
  102.     }
  103.  
  104.     return wrapper;
  105.   },
  106.  
  107.   addValues: function(data, values, tableElement) {
  108.  
  109.     if (values.length > 0) {
  110.       for (var i = 0; i < values.length; i++) {
  111.         var val = this.getValue(data, values[i]);
  112.  
  113.         //Items in Json from inverter have too many decimal places,  round them and add the W to the end for display
  114.  
  115.         if (typeof val == 'number'){
  116.           if(i >= 3 && i <= 4) {
  117.             val = Math.round(val/1000).toFixed(1) + ' kW' ;
  118.           } else {
  119.             val = Math.round(val) + ' W &nbsp;' ;
  120.           }
  121.         }
  122.  
  123.         if (val) {
  124.           tableElement.appendChild(this.addValue(values[i], val));
  125.         }
  126.       }
  127.     } else {
  128.       for (var key in data) {
  129.         if (data.hasOwnProperty(key)) {
  130.           tableElement.appendChild(this.addValue(key, data[key]));
  131.         }
  132.       }
  133.     }
  134.   },
  135.  
  136.   getValue: function(data, value) {
  137.     if (data && value) {
  138.       var split = value.split(".");
  139.       var current = data;
  140.       while (split.length > 0) {
  141.        current = current[split.shift()];
  142.       }
  143.  
  144.       return current;
  145.     }
  146.  
  147.     return null;
  148.   },
  149.  
  150.   addValue: function(name, value) {
  151.     // This is a nasty hack, don't do this in prod kids
  152.     var row = this.config.singleLine ? document.createElement("span") : document.createElement("tr");
  153.  
  154.     var split = name.split(".");
  155.     var strippedName = split[split.length - 1];
  156.  
  157.     if (this.config.stripName) {
  158.       name = strippedName;
  159.     }
  160.  
  161.     // Replace overrides not stripping the name
  162.     if (this.matchesReplace(strippedName)) {
  163.       name = this.replaceName(strippedName);
  164.     } else if (this.config.prettyName) {
  165.       name = name.replace(/([A-Z])/g, function($1){return "_"+$1.toLowerCase();});
  166.       name = name.split("_").join(" ");
  167.       name = name.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
  168.     }
  169.  
  170.     row.innerHTML = "";
  171.  
  172.     if (name.length > 0) {
  173.       name = name.replace(/['"]+/g, '');
  174.       row.innerHTML = name; // + "&nbsp; : &nbsp;"; // Hier ist der Doppelpunkt
  175.     }
  176.  
  177.     row.innerHTML += JSON.stringify(value).replace(/['"]+/g, '');
  178.     return row;
  179.   },
  180.  
  181.   matchesReplace: function(name) {
  182.     for (var i = 0; i < this.config.replaceName.length; i++) {
  183.       var n = this.config.replaceName[i];
  184.       if (n[0].toLowerCase() === name.toLowerCase()) {
  185.   //      console.log("matched")
  186.         return true;
  187.       }
  188.     }
  189.  
  190.     return false;
  191.   },
  192.  
  193.   replaceName: function(name) {
  194.     for (var i = 0; i < this.config.replaceName.length; i++) {
  195.       var n = this.config.replaceName[i];
  196.       if (n[0].toLowerCase() === name.toLowerCase()) {
  197.         return n[1];
  198.       }
  199.     }
  200.  
  201.     return name;
  202.   },
  203.  
  204.   scheduleUpdate: function(delay) {
  205.     var nextLoad = this.config.updateInterval;
  206.     if (typeof delay !== "undefined" && delay >= 0) {
  207.       nextLoad = delay;
  208.     }
  209.  
  210.     var self = this;
  211.     setInterval(function() {
  212.       self.getStats();
  213.     }, nextLoad);
  214.   },
  215.  
  216.   getStats: function () {
  217. var ipaddfr = this.config.ipaddfr;
  218. var url = ("http://" + ipaddfr + "/solar_api/v1/GetPowerFlowRealtimeData.fcgi");  //add correct path to ip address so we can find the info on the inverter
  219.  
  220. this.url = (this.config.url.length > 0) ? [this.config.url] : [];
  221.  
  222.  
  223.  var allUrls = this.config.urls.concat(url);
  224.     this.sendSocketNotification("GET_STATS", allUrls);
  225.   },
  226.  
  227.   socketNotificationReceived: function(notification, payload) {
  228.     if (notification === "STATS_RESULT") {
  229.       this.result = payload;
  230.       this.firstUpdate = false;
  231.       this.updateDom(); // 500 is fade
  232.     }
  233.   },
  234.  
  235.   // function from https://stackoverflow.com/questions/6491463
  236.   byString: function(o, s) {
  237.     s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
  238.     s = s.replace(/^\./, '');           // strip a leading dot
  239.     var a = s.split('.');
  240.     for (var i = 0, n = a.length; i < n; ++i) {
  241.         var k = a[i];
  242.         if (k in o) {
  243.             o = o[k];
  244.         } else {
  245.             return;
  246.         }
  247.     }
  248.     return o;
  249.   }
  250. });
RAW Paste Data