-
Notifications
You must be signed in to change notification settings - Fork 72
/
Copy pathpv_system_1.json
22 lines (22 loc) · 31.9 KB
/
pv_system_1.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"alias": "pv_system",
"name": "pv_system_1",
"image": null,
"description": null,
"descriptor": {
"type": "latest",
"sizeX": 42,
"sizeY": 37.5,
"resources": [],
"templateHtml": "\r\n\r\n<svg viewBox=\"0 0 345 345\" xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\">\r\n\r\n <defs>\r\n <g id=\"bat_symbol\">\r\n <rect id=\"batE4\" class=\"batElement\" x=\"0\" y=\"0\" width=\"20\" height=\"10\" fill=\"#c3c3c3\"/>\r\n <polyline class=\"batElement\" points=\"0,0 6,-6 26,-6 20,0\" fill=\"#e6e6e6\"/>\r\n <polyline class=\"batElement\" points=\"26,-6 26,4 20,10 20,0\" fill=\"#e6e6e6\"/>\r\n <polyline class=\"batElement\" points=\"26,4 26,12 20,18\" fill=\"#e6e6e6\"/>\r\n <polyline class=\"batElement\" points=\"26,12 26,20 20,26 \" fill=\"#e6e6e6\"/>\r\n <polyline class=\"batElement\" points=\"26,20 26,28 20,34 \" fill=\"#e6e6e6\"/>\r\n <polyline class=\"batElement\" points=\"26,28 26,32 20,38 \" fill=\"#e6e6e6\"/>\r\n\r\n <rect id=\"batE3\" class=\"batElement\" x=\"0\" y=\"10\" width=\"20\" height=\"8\" fill=\"#F3F3F3\"/>\r\n <rect id=\"batE2\" class=\"batElement\" x=\"0\" y=\"18\" width=\"20\" height=\"8\" fill=\"#F3F3F3\"/>\r\n <rect id=\"batE1\" class=\"batElement\" x=\"0\" y=\"26\" width=\"20\" height=\"8\" fill=\"#F3F3F3\"/>\r\n <rect id=\"batE0\" class=\"batElement\" x=\"0\" y=\"34\" width=\"20\" height=\"4\" fill=\"#F3F3F3\"/>\r\n <circle id=\"batOnOff\" cx=\"4\" cy=\"4\" r=\"3\" stroke=\"#c3c3c3\" fill=\"#00cc00\"/>\r\n </g>\r\n \r\n <g id=\"g_inverter\">\r\n <circle id=\"cInv\" r=\"30\" stroke=\"#c3c3c3\" fill=\"#FFFFFF\"></circle>\r\n <image href=\"https://github.com/derHaubi/solarwidget/blob/main/used%20pictures/wechselrichter.png?raw=true\" \r\n x=\"-19\" \r\n y=\"-20\" \r\n height=\"40\" \r\n width=\"40\"\r\n preserveAspectRatio=\"xMinYMin meet\"\r\n /> \r\n </g>\r\n \r\n <g id=\"g_production\">\r\n <circle id=\"cSolar\" r=\"40\" stroke=\"#E0BA34\" fill=\"#FFFDF4\"></circle>\r\n <image href=\"https://github.com/derHaubi/solarwidget/blob/main/used%20pictures/solar.png?raw=true\" \r\n x=\"-20\" \r\n y=\"-33\" \r\n height=\"40\" \r\n width=\"40\"\r\n opacity=\"20%\"\r\n preserveAspectRatio=\"xMinYMin meet\"\r\n />\r\n </g>\r\n \r\n <g id=\"g_grid\">\r\n <circle id=\"cGrid\" r=\"40\" stroke=\"#474747\" fill=\"#F3F3F3\"></circle>\r\n <image href=\"https://github.com/derHaubi/solarwidget/blob/main/used%20pictures/grid.png?raw=true\" \r\n x=\"-25\" \r\n y=\"-25\" \r\n height=\"50\" \r\n width=\"50\"\r\n opacity=\"75%\"\r\n preserveAspectRatio=\"xMinYMin meet\"\r\n />\r\n </g>\r\n \r\n <g id=\"g_battery\">\r\n <circle id=\"cBattery\" r=\"40\" stroke=\"#6CBE58\" fill=\"#EFFAEC\"></circle>\r\n <use xlink:href=\"#bat_symbol\" x=\"-13\" y=\"-25\"/>\r\n <text id=\"percBat\" x=\"0\" y=\"30\" text-anchor=\"middle\" font-size=\"small\" fill=\"#03152C\">100%</text>\r\n </g> \r\n \r\n <g id=\"g_house\">\r\n <circle id=\"cHouse\" r=\"40\" stroke=\"#70AFCD\" fill=\"#F4F9FB\"></circle>\r\n <image href=\"https://github.com/derHaubi/solarwidget/blob/main/used%20pictures/haus.png?raw=true\" \r\n x=\"-25\" \r\n y=\"-25\" \r\n height=\"50\" \r\n width=\"50\"\r\n opacity=\"50%\"\r\n preserveAspectRatio=\"xMinYMin meet\"\r\n />\r\n </g> \r\n \r\n <g id=\"g_car\">\r\n <circle id=\"cCar\" r=\"40\" stroke=\"#78828C\" fill=\"#ffffff\"></circle>\r\n <image href=\"https://raw.githubusercontent.com/derHaubi/solarwidget/main/used%20pictures/enyaq.png\" \r\n x=\"-40\" \r\n y=\"-30\" \r\n height=\"80\" \r\n width=\"80\"\r\n preserveAspectRatio=\"xMinYMin meet\"\r\n />\r\n </g>\r\n </defs>\r\n \r\n <line id=\"prod_line\" class=\"lineElement\" x1=\"10\" y1=\"10\" x2=\"150\" y2=\"150\" visibility=\"hidden\"></line>\r\n <line id=\"grid_line\" class=\"lineElement\" x1=\"10\" y1=\"10\" x2=\"150\" y2=\"150\" visibility=\"hidden\"></line> \r\n <line id=\"bat_line\" class=\"lineElement\" x1=\"10\" y1=\"10\" x2=\"150\" y2=\"150\" visibility=\"hidden\"></line>\r\n <line id=\"house_line\" class=\"lineElement\" x1=\"10\" y1=\"10\" x2=\"150\" y2=\"150\" visibility=\"hidden\"></line>\r\n <line id=\"car_line\" class=\"lineElement\" x1=\"10\" y1=\"10\" x2=\"150\" y2=\"150\" visibility=\"hidden\"></line>\r\n \r\n <circle id=\"prod_circle1\" r=\"7\" cx=\"180\" cy=\"45\" fill=\"#E0BA34\" visibility=\"hidden\">\r\n <animateMotion path=\"M0,0 0 135\" dur=\"1.5s\" repeatCount=\"indefinite\" />\r\n </circle>\r\n\r\n <circle id=\"grid_circle1\" r=\"7\" cx=\"45\" cy=\"125\" fill=\"#474747\" visibility=\"hidden\">\r\n <animateMotion path=\"M0,0 135 75\" dur=\"1.5s\" repeatCount=\"indefinite\" />\r\n </circle>\r\n\r\n <circle id=\"bat_circle1\" r=\"7\" cx=\"45\" cy=\"300\" fill=\"#6CBE58\" visibility=\"hidden\">\r\n <animateMotion path=\"M0,0 135 -100\" dur=\"1.5s\" repeatCount=\"indefinite\" />\r\n </circle>\r\n\r\n <circle id=\"house_circle1\" r=\"7\" cx=\"300\" cy=\"125\" fill=\"#70AFCD\" visibility=\"hidden\">\r\n <animateMotion path=\"M0,0 -120 75\" dur=\"1.5s\" repeatCount=\"indefinite\" />\r\n </circle>\r\n\r\n <circle id=\"car_circle1\" r=\"7\" cx=\"300\" cy=\"300\" fill=\"#78828C\" visibility=\"hidden\">\r\n <animateMotion path=\"M0,0 -120 -100\" dur=\"1.5s\" repeatCount=\"indefinite\" />\r\n </circle>\r\n \r\n\r\n <use xlink:href=\"#g_inverter\" id=\"inv_group\" x=\"180\" y=\"200\" visibility=\"hidden\"/>\r\n <use xlink:href=\"#g_production\" id=\"prod_group\" x=\"180\" y=\"45\" visibility=\"hidden\"/>\r\n <use xlink:href=\"#g_grid\" id=\"grid_group\" x=\"45\" y=\"125\" visibility=\"hidden\"/>\r\n <use xlink:href=\"#g_battery\" id=\"bat_group\" x=\"45\" y=\"300\" visibility=\"hidden\"/>\r\n <use xlink:href=\"#g_house\" id=\"house_group\" x=\"300\" y=\"125\" visibility=\"hidden\"/>\r\n <use xlink:href=\"#g_car\" id=\"car_group\" x=\"300\" y=\"300\" visibility=\"hidden\"/>\r\n\r\n <text id=\"prod_text_watt\" x=\"180\" y=\"65\" visibility=\"hidden\" text-anchor=\"middle\" font-size=\"small\" fill=\"#03152C\">--</text> \r\n <text id=\"grid_text_watt\" x=\"45\" y=\"80\" visibility=\"hidden\" text-anchor=\"middle\" font-size=\"small\" fill=\"#03152C\" >--- W</text>\r\n <text id=\"house_text_watt\" x=\"300\" y=\"80\" visibility=\"hidden\" text-anchor=\"middle\" font-size=\"small\" fill=\"#03152C\" >--- W</text>\r\n <text id=\"bat_text_watt\" x=\"45\" y=\"255\" visibility=\"hidden\" text-anchor=\"middle\" font-size=\"small\" fill=\"#03152C\">-- W</text>\r\n <text id=\"car_text_watt\" x=\"300\" y=\"255\" visibility=\"hidden\" text-anchor=\"middle\" font-size=\"small\" fill=\"#03152C\" >-- W</text>\r\n <text id=\"car_text_perc\" x=\"300\" y=\"330\" visibility=\"hidden\" text-anchor=\"middle\" font-size=\"small\" fill=\"#03152C\">-%</text>\r\n\r\n</svg>\r\n\r\n\r\n \r\n \r\n",
"templateCss": " .batElement {\r\n stroke-width: 1;\r\n stroke:#78828C;\r\n }\r\n\r\n .lineElement {\r\n fill: A#000;\r\n stroke: #bfbfbf;\r\n }",
"controllerScript": "self.onInit = function() {\n \n \n \n \n\n /**\n * \n * Start of Scritp Calls\n * \n */\n initSVG(); //unhide and plave SVG-Objects by given Values in Variable Definition wP\n addAnimCircles(wP.nrAnimCircles); //create copies of circle-SVGs (needed because <use> creates copies in Shadow Dom which is not accessable)\n getServerValues(1, null, 5); //\"start widget\" one time manually\n \n\n \n \n}\n\nself.onDataUpdated = function() {\n var settings = self.ctx.settings;\n for (var i = 0; i < self.ctx.datasources\n .length; i++) {\n\n for (var j = 0; j < self.ctx.data.length; j++) {\n \n if (self.ctx.data[j].data.length > 0) {\n if (self.ctx.data[j].dataKey.label ==\n settings.gridValueTelemetry) {\n\n if (isNumber(self.ctx.data[j].data[\n 0][1])) {\n\n getServerValues(2, null, self.ctx.data[\n j].data[0][1] .toFixed(1)); \n }\n\n }\n if (self.ctx.data[j].dataKey.label ==\n settings.pvValueTelemetry) {\n\n if (isNumber(self.ctx.data[j].data[\n 0][1])) {\n\n getServerValues(0, null, self.ctx.data[\n j].data[0][1] .toFixed(1)); \n }\n\n }\n if (self.ctx.data[j].dataKey.label ==\n settings.ConsumptionValueTelemetry) {\n\n if (isNumber(self.ctx.data[j].data[\n 0][1])) {\n\n getServerValues(3, null, self.ctx.data[\n j].data[0][1] .toFixed(1)); \n }\n\n }\n if (self.ctx.data[j].dataKey.label ==\n settings.CarValueTelemetry) {\n\n if (isNumber(self.ctx.data[j].data[\n 0][1])) {\n\n getServerValues(4, null, self.ctx.data[\n j].data[0][1] .toFixed(1)); \n }\n\n }\n if (self.ctx.data[j].dataKey.label ==\n settings.BatteryValueTelemetry) {\n\n if (isNumber(self.ctx.data[j].data[\n 0][1])) {\n\n getServerValues(1, null, self.ctx.data[\n j].data[0][1] .toFixed(1)); \n }\n\n }\n if (self.ctx.data[j].dataKey.label ==\n settings.CarCarchingStateTelemetry) {\n\n if (isNumber(self.ctx.data[j].data[\n 0][1])) {\n\n getServerValues(5, null, self.ctx.data[\n j].data[0][1] .toFixed(1)); \n }\n\n }\n if (self.ctx.data[j].dataKey.label ==\n settings.BatteryCarchingStateTelemetry) {\n\n if (isNumber(self.ctx.data[j].data[\n 0][1])) {\n\n getServerValues(6, null, self.ctx.data[\n j].data[0][1] .toFixed(1)); \n }\n\n }\n \n }\n }\n }\n \n}\n\nself.onLatestDataUpdated = function() {\n}\n\nself.onResize = function() {\n \n}\n\nself.onDestroy = function() {\n}\n\n\n\n/**\n * Function gets the Values for the Data-Points given in Array objIDs. This is a function which can only be used when the widget\n * is living in ioBroker VIS.\n * It is getting the Values and then recalculating Pathes, Circle Sizes and setting Text-SVGs\n */\n function getServerValues(objID, error, value){\n \n //console.log(states);\n \n //console.log(i + ' - ' + objIDs[i] + ' - ' + states[objIDs[i]].val);\n switch(objID) {\n case 0:\n flowValues.prod = value;\n break;\n case 1:\n flowValues.bat = value;\n break;\n case 2:\n flowValues.grid = value * -1;\n break;\n case 3:\n flowValues.house = value;\n break;\n case 4:\n flowValues.car = value;\n break;\n case 5:\n flowValues.carChSt = value;\n break;\n case 6:\n flowValues.batChSt = value;\n break;\n case 7:\n flowValues.batStatus = value;\n break;\n \n }\n \n if(flowValues.batStatus == 1) {flowValues.bat = 0}; //if Battery Off then force value for bat to be 0\n\n setPathes();\n setCircleSizeAndSpeed('prod', flowValues.prod, wP.pathes.prod.cur);\n setCircleSizeAndSpeed('bat', flowValues.bat, wP.pathes.bat.cur);\n setCircleSizeAndSpeed('house', flowValues.house, wP.pathes.house.cur);\n setCircleSizeAndSpeed('car', flowValues.car, wP.pathes.car.cur);\n setCircleSizeAndSpeed('grid', flowValues.grid, wP.pathes.grid.cur);\n setTextValues();\n setBatterySVG(flowValues.batChSt);\n \n }\n \n /**\n * Function used to clone the Animation-Circle-SVGs directly into DOM. Needed because the SVG copying like <use> write the copies into the \"Shadow-Dom\".\n * The Problem then is, that we are not able to edit for example then AnimationPath via DOM anymore.\n * This Function is called only once, when the Widget is intilaized.\n * \n * @number integer number of circles which should be created per FlowLine (currently set to 3 and not changeable)\n */ \n function addAnimCircles(number){\n for(var i=1;i<allFlowObjects.length;i++){\n var type = allFlowObjects[i];\n var el = document.getElementById(type + '_circle1');\n \n for(z=2;z<=number;z++){\n var elCopy = el.cloneNode(true);\n el.id = type + '_circle' + z.toString();\n el.parentNode.insertBefore(elCopy, el.nextSibling); \n }\n }\n } \n \n /**\n * Helper-Function used to calculate the Size, Speed (duartion) and begin-Time of the circles running on the FlowLine. Currently delivering three different sizes,\n * depending on Flows maximum Value and Flows current Value\n * \n * @type string Type of Flow (prod, bat, grid...)\n * @value number current Value gotten from the server for the sepicific Flow\n * \n * @return Object Object with circle size, duration for animation and begin-Threshold\n */ \n function calcCircleSize(type, value){\n value = Math.abs(value);\n var maxSize = 10;\n var maxVal = wP.maxVals[type];\n var z = 2\n var res = {};\n \n //find thresholds for circle Sizes - currently 3 different sizes\n //also the duration is calculated assuming we have 3 circles running per line\n z = Math.round(value/maxVal*10); //\n if(z<3){\n res.size = 3;\n res.duration = 2;\n res.begin = 0.66; //animation speed 2 Seconds with three Circles means every 0.66 seconds a circle can start\n } else if(z<7){\n res.size = z;\n res.duration = 1.5;\n res.begin = 0.5;\n } else if(z<=10){\n res.size = z;\n res.duration = 1;\n res.begin = 0.33;\n } else if(z>10){ //just save my ass :)\n res.size = 10;\n res.duration = 1;\n res.begin = 0.33;\n } \n \n return res; \n }\n \n /**\n * Function Used to set new CircleSize, Animation-Path and Speed for the Flow-Animation\n * \n * @type string Type of Flow (prod, bat, grid...)\n * @value number current Value gotten from the server for the sepicific Flow\n * @path string recalculated Path (by Value) for the given Flow (Direction or OFF)\n * \n */\n function setCircleSizeAndSpeed(type, value, path){\n var opt = calcCircleSize(type, value);\n var animationElement = opt.aniElement;\n //var circleElement = opt.circleElement;\n var circleElement = type + '_circle';\n var beg = 0;\n for(var i=1;i<=3;i++){\n document.getElementById(circleElement + i.toString()).setAttribute(\"r\", opt.size); \n document.getElementById(circleElement + i.toString()).getElementsByTagName('animateMotion')[0].setAttribute(\"path\", path);\n document.getElementById(circleElement + i.toString()).getElementsByTagName('animateMotion')[0].setAttribute(\"dur\", opt.duration + 's');\n document.getElementById(circleElement + i.toString()).getElementsByTagName('animateMotion')[0].setAttribute(\"begin\", beg + 's');\n \n beg = opt.begin * i;\n }\n }\n \n /**\n * Function used to format the given Watt-Values. If more than 1000W then it is deliver kW\n * \n * @val number Value in Watt\n * \n * @return string Value as String in Watt or kW\n */\n function formatWattNumber(val){\n \n function precisionRound(number, precision) {\n var factor = Math.pow(10, precision);\n return Math.round(number * factor) / factor;\n }\n \n var res = {};\n res.val = 0;\n res.unit = 'W';\n \n if (val > 1000){\n res.val = precisionRound(val/1000, 2);\n res.unit = 'kW';\n } else {\n res.val = val;\n res.unit = 'W';\n }\n \n return res;\n }\n \n /**\n * Function to set the Text-Values into the Text-SVG-Objects (Production Watt, Battery Watt, Grid Watt...)\n * New Values are set directly into the Text-SVG-Object via DOM\n */\n function setTextValues(){\n var objWN = {};\n \n objWN = formatWattNumber(flowValues.prod);\n document.getElementById('prod_text_watt').textContent = objWN.val + ' ' + objWN.unit;\n objWN = formatWattNumber(flowValues.grid);\n document.getElementById('grid_text_watt').textContent = objWN.val + ' ' + objWN.unit;\n objWN = formatWattNumber(flowValues.bat);\n document.getElementById('bat_text_watt').textContent = objWN.val + ' ' + objWN.unit;\n objWN = formatWattNumber(flowValues.house);\n document.getElementById('house_text_watt').textContent = objWN.val + ' ' + objWN.unit;\n objWN = formatWattNumber(flowValues.car);\n document.getElementById('car_text_watt').textContent = objWN.val + ' ' + objWN.unit;\n document.getElementById('car_text_perc').textContent = flowValues.carChSt.toString() + \"%\";\n document.getElementById('percBat').textContent = flowValues.batChSt.toString() + \"%\";\n }\n \n /**\n * Function to calculate and repaint the Battery-Cells in different Colors depeind on Battery Charge-Stae Value\n */\n function setBatterySVG(batVal){\n let colEmpty = '#F3F3F3';\n let colGreen = '#039442';\n let colOrange = '#ffdb78';\n let coldDarkOrange = '#ff5e08';\n let colRed = '#bd1b02';\n \n var col = colEmpty;\n var nrSeg = 1;\n \n if (flowValues.batStatus == 1){\n document.getElementById('batOnOff').setAttribute(\"fill\", colRed); \n } else {\n document.getElementById('batOnOff').setAttribute(\"fill\", '#00cc00');\n }\n \n if(batVal < 10){\n col = colRed;\n nrSeg = 0;\n } else if (batVal < 35) {\n col = coldDarkOrange;\n nrSeg = 1;\n } else if (batVal < 75) {\n col = colOrange;\n nrSeg = 2;\n } else {\n col = colGreen;\n nrSeg = 3; \n }\n \n for(var i=0; i<=nrSeg; i++){\n if(i<=nrSeg){\n document.getElementById('batE' + i).setAttribute(\"fill\", col);\n } else {\n document.getElementById('batE' + i).setAttribute(\"fill\", colEmpty);\n }\n }\n \n }\n \n /**\n * Function to set the recalculated Animation-Pathes. Basically it changes the Direction of how the Circles are running on the FlowLine\n * depending on the Flow-Value.\n * The result is written in the wP-Object and then used within Function/FunctionCall for setCircleSizeAndSpeed() \n */\n function setPathes(){\n for (var i=1;i<allFlowObjects.length;i++){\n var typ = allFlowObjects[i];\n var val = flowValues[typ];\n \n if(typ == 'prod'){ //if it's Value of Production then we need to negotiate to have correct direction\n val = val * -1;\n }\n \n if(val == 0) {\n wP.pathes[typ].cur = \"M0,0\";\n } else if (val < 0) {\n wP.pathes[typ].cur = wP.pathes[typ].pos;\n } else {\n wP.pathes[typ].cur = wP.pathes[typ].neg;\n } \n\n //console.log('Path of ' + typ + ': ' + wP.pathes[typ].pos);\n }\n \n }\n \n //define Array of Objects which values are gotten from server\n let objIDs = [\n 'javascript.0.solar.current_production',\n 'javascript.0.solar.toBattery',\n 'modbus.0.holdingRegisters.200.40087_W',\n 'javascript.0.solar.curConsumptionHouse',\n 'mqtt.0.wattpilot.properties.nrg_ptotal.state',\n 'vw-connect.0.xxxxxxxxxxxxx.status.charging.status.battery.stateOfChargeInPercent',\n 'modbus.0.holdingRegisters.1.40351_ChaState',\n 'modbus.0.holdingRegisters.1.40354_ChaSt'\n ];\n \n var allFlowObjects = ['inv', 'prod', 'grid', 'bat', 'house', 'car'];\n var flowValues = { //initialize values used in the widget\n \"prod\": 0,\n \"bat\": 0,\n \"grid\": 0,\n \"house\": 0,\n \"car\": 0,\n \"carChSt\": 0,\n \"batChSt\": 0,\n \"batStatus\": 0\n } \n\n //define Widget-Parameters - described in GitHub Wiki\n var wP = {};\n wP.nrAnimCircles = 3; //currently NOT changable\n wP.pos = {\n \"invX\": 180,\n \"invY\": 200,\n \"prodX\": 180,\n \"prodY\": 45,\n \"gridX\": 45,\n \"gridY\": 125,\n \"batX\": 45,\n \"batY\": 300,\n \"houseX\": 300,\n \"houseY\": 125,\n \"carX\": 300,\n \"carY\": 300, \n };\n wP.textPosDeltas = {\n \"prod_text_watt\": [0, 20],\n \"grid_text_watt\": [0, -45],\n \"bat_text_watt\": [0, -45],\n \"house_text_watt\": [0, -45],\n \"car_text_watt\": [0, -45],\n \"car_text_perc\": [0, 30],\n };\n wP.maxVals = {\n \"prod\": 17000,\n \"grid\": 12000,\n \"bat\": 8000,\n \"house\": 10000,\n \"car\": 11000\n };\n wP.pathes = {};\n calculatePaths();\n\n /**\n * Calculates the Animation Pathes for the given Flow-relevant Objects\n * Makes use of the Positions ov the Main-SVG-Objects and assumes that each Path ends\n * within the Inverter.\n * Result is for each Object a current path (.cur), a path for positive values (.pos) and one for negative values (.neg) e.g. 'M0,0 45 180'\n */\n function calculatePaths(){\n for(var i=1;i<allFlowObjects.length;i++){\n var type = allFlowObjects[i];\n wP.pathes[type] = {};\n wP.pathes[type].cur = \"M0,0 \" + (wP.pos.invX - wP.pos[type + 'X']).toString() + ' ' + (wP.pos.invY - wP.pos[type + 'Y']).toString();\n wP.pathes[type].pos = \"M0,0 \" + (wP.pos.invX - wP.pos[type + 'X']).toString() + ' ' + (wP.pos.invY - wP.pos[type + 'Y']).toString();\n wP.pathes[type].neg = \"M\" + (wP.pos.invX - wP.pos[type + 'X']).toString() + ',' + (wP.pos.invY - wP.pos[type + 'Y']).toString() + ' 0 0'; \n }\n }\n\n /**\n * Used to initialize the SVG-Objects withing the Widget. This is done by setting x/y Attributes in the Objects by DOM.\n */\n function initSVG(){\n //Position and unhide SVG-Object-Groups\n for(var i=0; i < allFlowObjects.length; i++){ \n var el = allFlowObjects[i];\n document.getElementById(el + '_group').setAttribute(\"x\", wP.pos[el+\"X\"]);\n document.getElementById(el + '_group').setAttribute(\"y\", wP.pos[el+\"Y\"]);\n document.getElementById(el + '_group').setAttribute(\"visibility\", \"visible\");\n } \n\n //run through Loop without Inverter-Object\n for(var i=1; i < allFlowObjects.length; i++){ // i = 1 because no line for Inverter\n var el = allFlowObjects[i];\n //Position and unhide Animation Lines\n document.getElementById(el + '_line').setAttribute(\"x1\", wP.pos[el+\"X\"]);\n document.getElementById(el + '_line').setAttribute(\"y1\", wP.pos[el+\"Y\"]);\n document.getElementById(el + '_line').setAttribute(\"x2\", wP.pos.invX);\n document.getElementById(el + '_line').setAttribute(\"y2\", wP.pos.invY);\n document.getElementById(el + '_line').setAttribute(\"visibility\", \"visible\");\n \n //Position and unhide given Set 1 of AnimationCircles - others will be autogenerated afterwards\n document.getElementById(el + '_circle1').setAttribute(\"cx\", wP.pos[el+\"X\"]);\n document.getElementById(el + '_circle1').setAttribute(\"cy\", wP.pos[el+\"Y\"]);\n document.getElementById(el + '_circle1').setAttribute(\"visibility\", \"visible\");\n\n //Position and unhide SVG-Text-Objects\n document.getElementById(el + '_text_watt').setAttribute(\"x\", wP.pos[el+\"X\"] + wP.textPosDeltas[el + '_text_watt'][0]);\n document.getElementById(el + '_text_watt').setAttribute(\"y\", wP.pos[el+\"Y\"] + wP.textPosDeltas[el + '_text_watt'][1]);\n document.getElementById(el + '_text_watt').setAttribute(\"visibility\", \"visible\");\n if(el == 'car'){\n document.getElementById(el + '_text_perc').setAttribute(\"x\", wP.pos[el+\"X\"] + wP.textPosDeltas[el + '_text_perc'][0]);\n document.getElementById(el + '_text_perc').setAttribute(\"y\", wP.pos[el+\"Y\"] + wP.textPosDeltas[el + '_text_perc'][1]);\n document.getElementById(el + '_text_perc').setAttribute(\"visibility\", \"visible\"); \n }\n }\n \n }\n \n function isNumber(value) {\n return typeof value === 'number';\n}\n",
"settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"gridValueTelemetry\": {\n \"title\": \"Grid Value Telemetry\",\n \"type\": \"string\",\n \"default\": \"Grid\"\n },\n \"pvValueTelemetry\": {\n \"title\": \"PV Value Telemetry\",\n \"type\": \"string\",\n \"default\": \"Pv\"\n },\n \"ConsumptionValueTelemetry\": {\n \"title\": \"Consumption Value Telemetry\",\n \"type\": \"string\",\n \"default\": \"Consumption\"\n },\n \"CarValueTelemetry\": {\n \"title\": \"Car Consumption Telemetry\",\n \"type\": \"string\",\n \"default\": \"CarConsumption\"\n }, \n \"BatteryValueTelemetry\": {\n \"title\": \"Battery Consumption Telemetry\",\n \"type\": \"string\",\n \"default\": \"BatteryConsumption\"\n }, \n \"CarCarchingStateTelemetry\": {\n \"title\": \"Car Charging State Telemetry\",\n \"type\": \"string\",\n \"default\": \"CarChargingState\"\n }, \n \"BatteryCarchingStateTelemetry\": {\n \"title\": \"Battery Charging State Telemetry\",\n \"type\": \"string\",\n \"default\": \"BatteryChargingState\"\n },\n \"BatteryStatusTelemetry\": {\n \"title\": \"Battery Status Telemetry\",\n \"type\": \"string\",\n \"default\": \"BatteryStatus\"\n }\n \n \n }\n },\n \"form\": [\n \"gridValueTelemetry\",\n \"pvValueTelemetry\",\n \"ConsumptionValueTelemetry\",\n \"CarValueTelemetry\",\n \"BatteryValueTelemetry\",\n \"CarCarchingStateTelemetry\",\n \"BatteryCarchingStateTelemetry\"\n ]\n}",
"dataKeySettingsSchema": "",
"latestDataKeySettingsSchema": "{}",
"settingsDirective": "",
"dataKeySettingsDirective": "",
"latestDataKeySettingsDirective": "tb-flot-latest-key-settings",
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"First\",\"color\":\"#2196f3\",\"settings\":{\"showLines\":true,\"fillLines\":true,\"showPoints\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Second\",\"color\":\"#ffc107\",\"settings\":{\"showLines\":true,\"fillLines\":false,\"showPoints\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"gridValueTelemetry\":\"Grid\",\"pvValueTelemetry\":\"Pv\",\"ConsumptionValueTelemetry\":\"Consumption\",\"CarValueTelemetry\":\"CarConsumption\",\"BatteryValueTelemetry\":\"BatteryConsumption\",\"CarCarchingStateTelemetry\":\"CarChargingState\",\"BatteryCarchingStateTelemetry\":\"BatteryChargingState\",\"BatteryStatusTelemetry\":\"BatteryStatus\"},\"title\":\"pv_system_1\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"mobileHeight\":null}"
}
}