Advertisement
cetax

fronius.js

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