Jump to content
Forum upgrade is live! Read more... ×
Sign in to follow this  
g__day

Simplest way to display local IP JSON data as a spreadsheet / html page on my PC?

Recommended Posts

Folks,

 

Much obliged if anyone can give me some pointers - as I am a rank amateur with what I am trying to do.

 

My local solar system has 15 minute interval consolidated data coming from the local Envoy-S metered device that controls the micro inverters on the back of each of my 31 solar cells on our house.

 

If one queries the unit by calling:

 

http://192.168.0.12/api/v1/production/inverters

 

then it returns some important information including: each inverters serial number, last reported output in Watts and Maximum every achieved output in watts:

[  {    "serialNumber": "121440006252",    "lastReportDate": 1484971459,    "devType": 1,    "lastReportWatts": 172,    "maxReportWatts": 255  },  {    "serialNumber": "121440009848",    "lastReportDate": 1484971423,    "devType": 1,    "lastReportWatts": 220,    "maxReportWatts": 251  },  {    "serialNumber": "121440009469",    "lastReportDate": 1484971461,    "devType": 1,    "lastReportWatts": 216,    "maxReportWatts": 250  },  {    "serialNumber": "121440006298",    "lastReportDate": 1484971424,    "devType": 1,    "lastReportWatts": 222,    "maxReportWatts": 254  },  {    "serialNumber": "121440000591",    "lastReportDate": 1484971428,    "devType": 1,    "lastReportWatts": 220,    "maxReportWatts": 250  },  {    "serialNumber": "121440006299",    "lastReportDate": 1484971427,    "devType": 1,    "lastReportWatts": 217,    "maxReportWatts": 251  },  {    "serialNumber": "121440009439",    "lastReportDate": 1484971435,    "devType": 1,    "lastReportWatts": 222,    "maxReportWatts": 254  },  {    "serialNumber": "121621032153",    "lastReportDate": 1484971438,    "devType": 1,    "lastReportWatts": 161,    "maxReportWatts": 265  },  {    "serialNumber": "121621032758",    "lastReportDate": 1484971447,    "devType": 1,    "lastReportWatts": 161,    "maxReportWatts": 265  },  {    "serialNumber": "121621031898",    "lastReportDate": 1484971448,    "devType": 1,    "lastReportWatts": 238,    "maxReportWatts": 268  },  {    "serialNumber": "121621032709",    "lastReportDate": 1484971453,    "devType": 1,    "lastReportWatts": 235,    "maxReportWatts": 267  },  {    "serialNumber": "121621032560",    "lastReportDate": 1484971441,    "devType": 1,    "lastReportWatts": 160,    "maxReportWatts": 263  },  {    "serialNumber": "121440005870",    "lastReportDate": 1484971427,    "devType": 1,    "lastReportWatts": 177,    "maxReportWatts": 255  },  {    "serialNumber": "121621032935",    "lastReportDate": 1484971455,    "devType": 1,    "lastReportWatts": 236,    "maxReportWatts": 267  },  {    "serialNumber": "121621032703",    "lastReportDate": 1484971448,    "devType": 1,    "lastReportWatts": 237,    "maxReportWatts": 265  },  {    "serialNumber": "121621032713",    "lastReportDate": 1484971452,    "devType": 1,    "lastReportWatts": 237,    "maxReportWatts": 268  },  {    "serialNumber": "121621032469",    "lastReportDate": 1484971450,    "devType": 1,    "lastReportWatts": 236,    "maxReportWatts": 267  },  {    "serialNumber": "121440005872",    "lastReportDate": 1484971457,    "devType": 1,    "lastReportWatts": 174,    "maxReportWatts": 255  },  {    "serialNumber": "121440003726",    "lastReportDate": 1484971462,    "devType": 1,    "lastReportWatts": 172,    "maxReportWatts": 255  },  {    "serialNumber": "121440010087",    "lastReportDate": 1484971424,    "devType": 1,    "lastReportWatts": 168,    "maxReportWatts": 254  },  {    "serialNumber": "121440006244",    "lastReportDate": 1484971433,    "devType": 1,    "lastReportWatts": 175,    "maxReportWatts": 248  },  {    "serialNumber": "121440010065",    "lastReportDate": 1484971431,    "devType": 1,    "lastReportWatts": 216,    "maxReportWatts": 252  },  {    "serialNumber": "121440005652",    "lastReportDate": 1484971435,    "devType": 1,    "lastReportWatts": 217,    "maxReportWatts": 250  },  {    "serialNumber": "121621032648",    "lastReportDate": 1484971444,    "devType": 1,    "lastReportWatts": 157,    "maxReportWatts": 262  },  {    "serialNumber": "121621032643",    "lastReportDate": 1484971443,    "devType": 1,    "lastReportWatts": 159,    "maxReportWatts": 264  },  {    "serialNumber": "121621032476",    "lastReportDate": 1484971438,    "devType": 1,    "lastReportWatts": 159,    "maxReportWatts": 264  },  {    "serialNumber": "121440000313",    "lastReportDate": 1484971437,    "devType": 1,    "lastReportWatts": 217,    "maxReportWatts": 253  },  {    "serialNumber": "121440006254",    "lastReportDate": 1484971430,    "devType": 1,    "lastReportWatts": 221,    "maxReportWatts": 253  },  {    "serialNumber": "121440010058",    "lastReportDate": 1484971459,    "devType": 1,    "lastReportWatts": 173,    "maxReportWatts": 251  },  {    "serialNumber": "121440009443",    "lastReportDate": 1484971421,    "devType": 1,    "lastReportWatts": 223,    "maxReportWatts": 253  },  {    "serialNumber": "121440006266",    "lastReportDate": 1484971432,    "devType": 1,    "lastReportWatts": 221,    "maxReportWatts": 253  }]

What is the simplest way to achieve a spreadsheet or local webpage that if I go to it will exectue this call and graphically display a bar / number of how much power each solar cell is producing?

 

Many thanks,

 

Matthew

Share this post


Link to post
Share on other sites

So that's how the data comes down?

 

Not sure if Excel can parse it like that... from memory you can deliniate fields by absolute column # but I suspect that might break when the watts goes under 100.

Might need some pre-parse massaging of the data, like throw away superfluous stuff, pack the whole lot of samples into a single record with only one CR/LF.

Then probably append it to a file that gets input to the graphing.

Then maybe do EOD processing, weekly, monthly etc.

Edited by Rybags

Share this post


Link to post
Share on other sites

I think Excel handles html tables from web calls very nicely, but JSON gives excel a total heart attack.

 

I was expecting someone to say forget excel code a simple local web page which calls this IP and formats its reply using some uber complicated technology...

Edited by g__day

Share this post


Link to post
Share on other sites

I was expecting someone to say forget excel code a simple local web page which calls this IP and formats its reply using some uber complicated technology...

I think most people would say just that. But seeing as I have no idea how to do that i'll give you this option instead.

 

Of course this would depend on how you can get a copy of the file for excel to use. I've got it using a file on the desktop called solar.txt. Ideally if you can have the data saved periodically to a file, then all you need to do is open the spreadsheet.

 

So here's a something that I cobbled together based on a formulas i've used in the past to parse data that's spread out.

 

https://1drv.ms/x/s!Au4ONRNAF_J5vJpVfn1d79R8U90s6g

 

Getting to the endpoint is somewhat convoluted, but all that can be hidden only showing the final table - and you do get a graph out of it in the end. Not sure if that's exactly how you want it laid out though. But you should be able to work on it from there.

 

The data source can be changed and should prompt your for a source when you open the file. From then on it should update automatically when opening the sheet or manually refreshing the data.

 

Happy to tweak if it's heading in the right direction.

 

NOTES:

Columns BC is imported data from the txt file using space, comma, colon as delimiters

Columns EFG is the data parsed for only serial/last/max watts

Columns IJK is the parsed data collated together into a table

Graph is on the 2nd tab

The data will be updated on opening the spreadsheet or using the Refresh option in the Data tab.

Edited by rs727

Share this post


Link to post
Share on other sites

If you're using Excel on Windows, there's a kludge that lets you read text from a HTTP source using an ActiveX object.

 

You could then parse the output using a combination of Split(), Replace(), and Trim().

 

Like this maybe:

 

Option Explicit
Option Base 0

Private Sub Workbook_Open()

populate

End Sub

Public Function GetWebSource(ByRef URL As String) As String
    Dim xml As IXMLHTTPRequest
    On Error Resume Next
    Set xml = CreateObject("Microsoft.XMLHTTP")
    With xml
        .Open "GET", URL, False
        .send
        GetWebSource = .responseText
    End With
    Set xml = Nothing
End Function

Private Sub populate()
    Dim json As String
    json = GetWebSource("http://192.168.0.12/api/v1/production/inverters")

    Dim out() As String
    out = ParseJSON(json)
    
    ' Do stuff here with the array
    ' out(0,x) = serialnumber
    ' out(1,x) = lastreportdate
    ' out(2,x) = devtype
    ' out(3,x) = lastreportwatts
    ' out(4,x) = maxreportwatts
    '
    ' x = 0-based index of inverter
    
    ' e.g.
    
    Dim i As Integer
    
    For i = LBound(out, 2) To UBound(out, 2)
        ' Do stuff here like "Range.FormulaR1C1 = out(0,i)"
    Next i
    

End Sub

Public Function ParseJSON(ByVal json As String) As String()

    Dim firstsplit() As String
    Dim secondsplit() As String
    Dim outputarray() As String
    Dim thirdsplit() As String
    
    json = Replace(json, "[", "")
    json = Replace(json, "]", "")
    json = Replace(json, """", "")
    
    firstsplit = Split(json, "},")
    
    Dim parsing As String
    Dim i As Integer
    Dim c As Integer
    c = 0

    For i = LBound(firstsplit) To UBound(firstsplit)
        ReDim Preserve outputarray(4, c)
        secondsplit = Split(firstsplit(i), ",")
        
        thirdsplit = Split(secondsplit(0), ":")
        outputarray(0, c) = Trim$(Replace(Replace(thirdsplit(1), "{", ""), "}", ""))
        
        thirdsplit = Split(secondsplit(1), ":")
        outputarray(1, c) = Trim$(Replace(Replace(thirdsplit(1), "{", ""), "}", ""))
        
        thirdsplit = Split(secondsplit(2), ":")
        outputarray(2, c) = Trim$(Replace(Replace(thirdsplit(1), "{", ""), "}", ""))
        
        thirdsplit = Split(secondsplit(3), ":")
        outputarray(3, c) = Trim$(Replace(Replace(thirdsplit(1), "{", ""), "}", ""))
        
        thirdsplit = Split(secondsplit(4), ":")
        outputarray(4, c) = Trim$(Replace(Replace(thirdsplit(1), "{", ""), "}", ""))
        c = c + 1
        
    Next i
    
    ParseJSON = outputarray

End Function
Edited by SquallStrife

Share this post


Link to post
Share on other sites

I think Excel handles html tables from web calls very nicely, but JSON gives excel a total heart attack.

 

I was expecting someone to say forget excel code a simple local web page which calls this IP and formats its reply using some uber complicated technology...

Sorry I'm late haha :)

 

...or local webpage that if I go to it will exectue this call and graphically display a bar / number of how much power each solar cell is producing?

Not sure why people even consider Excel :)

 

HTML page + javascript will read JSON piece of piss, then iterate in JS and create table.

http://192.168.0.12/...ction/inverters = REST API. hit it using jquery with something like

$.getJSON("http://192.168.0.12/api/v1/production/inverters", function(data) {
  // Build a table here using the returned data.
 // This will output to html page.
// piss easy. all dynamic.
});
see http://api.jquery.com/jquery.getjson/

 

I'm balls deep in deadline and shouldn't even be browsing here or taking the time to type this, otherwise I'd type up a complete working example. However, it realy is easy and not at all requiring "uber" technology :) Happy to help out if needed. JSON is built for this - JavaScript Object Notation. i.e. Use JavaScript.

 

Ironically or coincidentally I'm balls deep in finishing a web-api REST end-point that emits JSON

Edited by kikz

Share this post


Link to post
Share on other sites

<html>
    <head>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
        <style>
            table td.box {
                width: 250px;
                border-left: 1px solid #000000;
                border-right: 1px solid #000000;
            }
            table td.box div {
                background-color: #0000FF;
            }
        </style>
    </head>
    <body>
        
        <div id="results"></div>
        
        <script>            
            $(function() {
                $.getJSON("http://www.robertgray.net.au/gday", function(data) {                    
                    var table = $("<table><tr><th>Serial Number</th><th>Last Report Date</th><th>Status</th><th>Last</th><th>Max</th></tr></table>").addClass("table table-striped");
                    $.each(data, function(index, item) {                                                
                        var percent = ((item.lastReportWatts / item.maxReportWatts) * 100);                      
                        var row = $("<tr></tr>").html("<td>" + item.serialNumber + "</td><td>" + new Date(item.lastReportDate) + "</td><td class='box'><div style='width: " + percent + "%'> </div></td><td>" + item.lastReportWatts + "</td><td>" + item.maxReportWatts+ "</td>");
                        table.append(row);                       
                    });                                       
                    $("#results").append(table);
                })
            });
        </script>
    </body>
</html> 

okay. Whipped this up just now. All you need to do is copy it to a HTML file and click on it. oh and change the url from mine to yours :)

that's the url in the getJSON. - which is just the data copied from your OP so i can test and verify.

 

Here's a working example.

http://www.robertgray.net.au/gday-example

 

oh yeah... the dates... I guess it's not reporting year? and Jan 18 was when you were trying this? You can just do .getMonth and .getDay to get rid of the rest.

 

Techologies:

- jquery (hosted on cdn)

- twitter bootstrap for styling the table (hosted on cdn).

The most basic of basic web technologies :)

 

From there you can do an easy sum on the inverters to get unique -rather than the raw data dump I have here.

Edited by kikz
  • Like 2

Share this post


Link to post
Share on other sites

Wow thanks guys - I am overwhelmed! Am trying this now...

 

Also when I enter the url in say Firefox it always prompts me for a user name (envoy) and password (last 6 digits of my envoy-s gateway). I there a way I can pass those variables envoy/123456 in the .JSON call?

 

Also when I entered the data in a html file and execute it in firefox (via go to url file:///I:/Users/Matthew/Documents/Solar/Enphase.html) it just gave me a blank screen - any idea what I did wrong?

 

 

<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
</head>
<body>

<div id="results"></div>

<script>
$(function() {
$.getJSON("http://192.168.0.12/api/v1/production/inverters", function(data) {
var table = $("<table><tr><th>Serial Number</th><th>Last Report Date</th><th>Last Report Watts</th><th>Max Report Watts</th></tr></table>").addClass("table table-striped");
$.each(data, function(index, item) {
var row = $("<tr></tr>").html("<td>" + item.serialNumber + "</td><td>" + new Date(item.lastReportDate) + "</td><td>" + item.lastReportWatts + "</td><td>" + item.maxReportWatts+ "</td>");
table.append(row);
});
$("#results").append(table);
})
});
</script>
</body>
</html>

Edited by g__day

Share this post


Link to post
Share on other sites

Also when I enter the url in say Firefox it always prompts me for a user name (envoy) and password (last 6 digits of my envoy-s gateway). I there a way I can pass those variables envoy/123456 in the .JSON call?

 

Also when I entered the data in a html file and execute it in firefox (via go to url file:///I:/Users/Matthew/Documents/Solar/Enphase.html) it just gave me a blank screen - any idea what I did wrong?

1) Authentication - I guess it's using basic authentication and sending in clear text? You can check it out by hitting F12 and going to the Network tab (assuming chrome here), finding the call to the endpoint and then looking at it's request headers. If it is in fact basic auth you can follow the answer here http://stackoverflow.com/questions/5507234/how-to-use-basic-auth-with-jquery-and-ajax really easy to do and it'll add the header to every request from that page.

 

2) yeah, It's blank because the code that creates the table only executes when the call to the endpoint returns successfully. at the moment you're not getting authorized, so it's not returning successfully :) Fix #1 and #2 should sort itself.

 

 

Oh yeah, if you want it all graphicals and stuff you can just create a column instead of two and create a div with border set to 1px (border: 1px solid #000000 in css) and width to the max value (Set this in js). Then create another div with same starting point on the left hand side and create it with a solid background colour (e.g. background-color: #0000FF) and set the width to the last reported value. Or you could get fancy and use canvas, but meh.

 

If you're trying to work out what's going on where in JS, include "console.debug('stuff')"; in the appropriate place. then pop open your buddy F12 and go to the console tab and see if it's output.

Edited by kikz
  • Like 1

Share this post


Link to post
Share on other sites

Well your link looks really great! I'd be thrilled when I get to that position.

 

I added the user id and password to the Url as I thought $.getJSON("envoy:011842@http://192.168.0.12/api/v1/production/inverters", function(data) {

 

The Chrome feedback - without the above user id and password fails says authentication required, once I added it runs longer and still arrives at a blank screen but Chrome F12 -> network now gives

 

XMLHttpRequest cannot load envoy:011842@http://192.168.0.12/api/v1/production/inverters. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.

 

So getting closer - many thanks - now googling what Cross origin requests vs protocol schemes mean!

 

* * * * * * *

 

So Dr Google says the error seems to be that I am trying to run this as a html file from my web browser by tyring to load ---> file:///I:/Users/Matthew/Documents/Solar/Enphase.html

 

Apparently most prowsers see this is a security risk. Google advice offer two options - run a simple web server browsed to the html files dierctory and execute their or lower your browsers security configuration. Short story - both options dead eneded.

 

Option1 - instal Python 3.6.0 - open a cmd prompt, go to the local director and type python -m http.server --- this should make a local host server at the current directory - so one could then go http://localhost/enphase.html. On re-boot created a local http server on localhost:8000 - that worked!

 

Option 2 - in firefox browse to about:configue, set security.fileuri.strict_origin_policy to false. This progressed the problem to still a blank screen - but now it says The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must be declared in the document or in the transfer protocol. Googling this says to add somewhere in the head of client/live.html add:

<meta charset="utf-8"/>

So I tried all the above in Firefox - ran the server - went to http://localhost:8000/Enphase.html - the error is

 

The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must be declared in the document or in the transfer protocol.

 

under CSS tap the data is:

 

Error in parsing value for '-webkit-text-size-adjust'. Declaration dropped. bootstrap.min.css:5:132
Unknown pseudo-class or pseudo-element '-webkit-inner-spin-button'. Ruleset ignored due to bad selector. bootstrap.min.css:5:1544
Unknown pseudo-class or pseudo-element '-webkit-search-cancel-button'. Ruleset ignored due to bad selector. bootstrap.min.css:5:1778
Unknown property 'orphans'. Declaration dropped. bootstrap.min.css:5:2691
Unknown property 'widows'. Declaration dropped. bootstrap.min.css:5:2700
Unknown property '-moz-osx-font-smoothing'. Declaration dropped. bootstrap.min.css:5:3676
Expected colour but found 'auto'. Expected colour but found '-webkit-focus-ring-color'. Expected end of value but found '-webkit-focus-ring-color'. Error in parsing value for 'outline'. Declaration dropped. bootstrap.min.css:5:15689
Error in parsing value for 'margin-top'. Declaration dropped. bootstrap.min.css:5:35720
Expected colour but found 'auto'. Expected colour but found '-webkit-focus-ring-color'. Expected end of value but found '-webkit-focus-ring-color'. Error in parsing value for 'outline'. Declaration dropped. bootstrap.min.css:5:35947
Unknown pseudo-class or pseudo-element '-ms-input-placeholder'. Ruleset ignored due to bad selector. bootstrap.min.css:5:36878
Unknown pseudo-class or pseudo-element '-webkit-input-placeholder'. Ruleset ignored due to bad selector. bootstrap.min.css:5:36926
Unknown pseudo-class or pseudo-element '-ms-expand'. Ruleset ignored due to bad selector. bootstrap.min.css:5:36978
Expected media feature name but found '-webkit-min-device-pixel-ratio'. bootstrap.min.css:5:37312
Error in parsing value for 'margin-top'. Declaration dropped. bootstrap.min.css:5:38425
Unknown property 'touch-action'. Declaration dropped. bootstrap.min.css:5:45363
Unknown property 'user-select'. Declaration dropped. bootstrap.min.css:5:45471
Expected colour but found 'auto'. Expected colour but found '-webkit-focus-ring-color'. Expected end of value but found '-webkit-focus-ring-color'. Error in parsing value for 'outline'. Declaration dropped. bootstrap.min.css:5:45652
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:45998
Expected colour but found 'solid\9 '. Expected end of value but found 'solid\9 '. Error in parsing value for 'border-top'. Declaration dropped. bootstrap.min.css:5:54924
Expected 'none', URL, or filter function but found 'progid'. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:56291
Expected colour but found 'solid\9 '. Expected end of value but found 'solid\9 '. Error in parsing value for 'border-bottom'. Declaration dropped. bootstrap.min.css:5:56836
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:85213
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:86118
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:86744
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:87376
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:88006
Unknown property 'zoom'. Declaration dropped. bootstrap.min.css:5:88442
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:105685
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:105794
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:107003
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:107056
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:108206
Unknown property 'line-break'. Declaration dropped. bootstrap.min.css:5:108243
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:108268
Unknown property 'line-break'. Declaration dropped. bootstrap.min.css:5:110250
Expected media feature name but found 'transform-3d'. bootstrap.min.css:5:112088
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:113425
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:113581
Expected 'none', URL, or filter function but found 'progid'. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:113840
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:114124
Expected 'none', URL, or filter function but found 'progid'. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:114383
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:114608
Expected colour but found '#\30 00\9 '. Error in parsing value for 'background-color'. Declaration dropped. bootstrap.min.css:5:115557
The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must be declared in the document or in the transfer protocol.

 

One the CMD window running python is states 127.0.0.1 - - [12/Feb/2017 14:20:49] "GET Enphase.html HTTP/1.1" 200 -

 

Which I guess is normal :)

 

PPS

 

One final request - would it be simple in your program to sum and total the last two columns please - that would be amazingly useful!

 

Edited by g__day

Share this post


Link to post
Share on other sites

not sure why you're getting the python problems. cross domain is usually when you try to access resources from another server. usually with posting. cross domain get shouldn't be a problem.

 

here's the new JS code you'll need to total. Totalling is pretty trivial.

<script>            
            $(function() {
                $.getJSON("http://www.robertgray.net.au/gday", function(data) {                    
                    var table = $("<table><tr><th>Serial Number</th><th>Last Report Date</th><th>Status</th><th>Last</th><th>Max</th></tr></table>").addClass("table table-striped");
                    var totalLastReportWatts = 0;
                    var totalMaxReportWatts = 0;
                    $.each(data, function(index, item) {                                                
                        totalLastReportWatts += item.lastReportWatts;
                        totalMaxReportWatts += item.maxReportWatts;

                        var percent = ((item.lastReportWatts / item.maxReportWatts) * 100);                      
                        var row = $("<tr></tr>").html("<td>" + item.serialNumber + "</td><td>" + new Date(item.lastReportDate) + "</td><td class='box'><div style='width: " + percent + "%'> </div></td><td>" + item.lastReportWatts + "</td><td>" + item.maxReportWatts+ "</td>");
                        table.append(row);                       
                    });                                       
                    var totalsRow = $("<tr></tr>").html("<td colspan='3'></td><td>" + totalLastReportWatts + "</td><td>" + totalMaxReportWatts + "</td>");
                    table.append(totalsRow);                       
                    $("#results").append(table);
                })
            });
        </script>
  • Like 1

Share this post


Link to post
Share on other sites

Many thanks for that - slowest debug ever because another week and a half until I get home to try it again - time for me to start reading up on browser based debugging of javascript!

Greatly appreciate you adding the totalling code - so now it's condition that raises the error related to encoding of the html blocking things. So given your code is straightforward and works for you - we can assume its correct and the code it calls is also correct. I can't see it complaining about the formatting of the data - so I presume its the sending of the final result that is causing all the pain when its in my home environment. So am I right to assume that something between your and my home environment is different and something extra must be defined in your code to encounter for my situation. If you wrote a simple "hello world" program using your same scaffolding and it failed to run on my PC would that help isolate the problem? I am pondering why the beginners guide is saying the error points to the script type i.e. setting the character set to UTF-8 so no characters fall outside the US ASCII character set is the only and true error - unless its the fact I have set in Windows 10 use Australian English and possibly an Australian keyboard and by default you have selected US keyboard when you installed Windows on your PC and that is causing the error on my PC but not your?

 

So your experience that it shouldn't be happening and you believe it's a Python error. I don't have the necessary skills to fix it unaided. Do you believe Dr Google saying declare the character set required explicitly somewhere or would you have me follow a different solution approach or run another diagonostic?

I never did ask how you run yours - but Python does allow me to simply to run a web server to allow local html files to be executed from a web browser.

So what do you recommend I do next once I return home and add the totalling code to your script section of the program? It's tantalising being this close! Even with the totals added if the harness around the code won't let the output be displayed on my version of Windows 10 Pro what is the best thing to do next?

Edited by g__day

Share this post


Link to post
Share on other sites

Holy Molly - when I pasted your code I think I missed a key section - when I copied it across to my Html file!

 

Looking at the code above vs my sample it's belatedly obvious my code missed lines 5 - 14 - maximum head slap! Means I probably don't need the Python web server either!

 

I just did a how to code Hello World JavaScript tutorial (with 3 mistake), then two popup buttons that launch a hello world text - then entered your framework's style link and it crashed - tried to debug it and then thought no lift your whole program again - it worked a treat on my laptop. So I re-checked the code and found that clear mistake - mega whoopsie on my part.

 

So will see if I can get my wife to run this from a PC at home this afternoon.

 

Fingers crossed - plus I think I will now start learning JavaScript - first time I have learnt a programming language in 20 years!

 

Many thanks!

Edited by g__day

Share this post


Link to post
Share on other sites

So two more tries narrowing down the issue:

 

  1. modifying the URL in your $get.JSON("envoy:011842@http://192.168.0.12/api/v1/production/inverters", - gave the cross domain error message about http accepted so on reading a bit more about how to pass a userid and password to a url I gleaned the string should possibly be formatted like this so the JSON recognises it as a http address
  2. modifying the URL in your $get.JSON(http://envoy:011842@192.168.0.12/api/v1/production/inverters, - got past the old error but now failed authentication - saying a null id was passed and a null id isn't accepted and returns only a 404 page not found cannot load http://192.168.0.12/api/v1/production/inverters 404 error as No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 404.

So the first method of calling the URL confuses the javascript into thinking its not a http address and the second request hit the right URL - but doesn't pass the user id and password the way the Envoy-s wishes to receive it.

 

This simplifies things back to how to get the user id and password into the call.

 

Any ideas greatly appreciated whilst I search for answers!

 

Cheers,

 

Matthew

Share this post


Link to post
Share on other sites

When you call json on one server from JSON on another you cab get that problem. Normally the easiest way is to set the Access-Control-Allow-Origin header to "*" in the response header. But that has to be done on the server. Unfortunately you can't do that (and I did). You have to call using JSONP

 

https://www.sitepoint.com/jsonp-examples/ is a good introduction

 

basically, the original code won't work as-is (it's using plain old JSON). All you should need to do is append a ? to the end of the url you are calling e.g.

http://192.168.0.12/api/v1/production/inverters?

*I think*. I've always modified the response header.

 

You're auth problem is something else and may be sorted by the right Auth header in the request.

 

see. http://stackoverflow.com/questions/18264601/how-to-send-a-correct-authorization-header-for-basic-authentication (which coincidentally also has an example where he sets Access-Control-Allow headers.

Share this post


Link to post
Share on other sites

Many thanks so it's still a $.getJSON("URL?" Just add the ? At the end.

 

Is there any call you can make to the URLs to get it to tell you what authentication protocol it expects for its user id and password?

 

Otherwise it's try many different protocol modified URLs strings, tokens etc to attempt to see which is the correct method.

 

I have pinged a message to Enphase to see if they will reveal the correct method.

 

I will also try experimenting with the original type in the URL from a browser and try and add the user id and password in the call to see if I can find what structure of call works. Normally from a browser I enter the URL then it brings up a window asking for user id and password - enter the correct details and everything then works fine when you continually press refresh until you close the browser - so I guess it creates a session token or cookie somewhere that expires once the session closes? Wish there was a way is seeing exactly what happens and what it therefore expects!

 

Cheers,

Matt

Edited by g__day

Share this post


Link to post
Share on other sites

Still waiting Enphase's response...

 

Reading up on different means to pass credentials I came across this... what do you think - should this be merged into your code somehow?

 

$,getJSON({ 'url' : 'http://host.com/action' 'othersettings' : 'othervalues ', 'beforesend' : function(xhr) {

// May need to use the string Authorization instead of Authentication

xhr, setRequestHeader("Authentication", "Basic " + encodeBase64(username + ":" + password)},

success: Function(result) { alert('done'); } });

 

Its mind boggling that it is so challenging to pass the user name and password to a URL when it's not all executed in a browser.

 

If I execute the URL from Chrome and press debug - will I see how it invokes and confirms the credentials - or will this be hidden server side code?

 

Cheers,

Matt

Share this post


Link to post
Share on other sites

Been revisiting this code and trying it on latest versions of Chrome, Firefox and Edge and trying to clear the error messages. Most of which related to not specifying the doc type? rather than CORS issues from the browser not allowing localhost on my machine to talk to 192.168.0.12.

 

Now its complaining about not being able to load the style sheet - so no authentication issus reported - under Edge thankfully, but to die on the Stylesheet seems like ignomious defeat!

 

My protocol is to use Admin CMD prompt to start a Python http web server in the directory with the Enphase.html script - so elevated CMD, CD to Solar directory, python -m http.server to startrt a 127.0.0.1:8000 webserver

 

Then under my Broswers in debug mode I try to run 127.0.0.1:8000/enphase.html

 

The error code in Edge is

 

GET http://127.0.0.1:8000/Enphase.html [HTTP/1.0 200 OK 52ms]
GET https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css [HTTP/2.0 304 Not Modified 177ms]
GET https://code.jquery.com/jquery-3.1.1.min.js [HTTP/2.0 304 Not Modified 181ms]
Error in parsing value for '-webkit-text-size-adjust'. Declaration dropped. bootstrap.min.css:5:132
Unknown pseudo-class or pseudo-element '-webkit-inner-spin-button'. Ruleset ignored due to bad selector. bootstrap.min.css:5:1544
Unknown pseudo-class or pseudo-element '-webkit-search-cancel-button'. Ruleset ignored due to bad selector. bootstrap.min.css:5:1778
Unknown property 'orphans'. Declaration dropped. bootstrap.min.css:5:2691
Unknown property 'widows'. Declaration dropped. bootstrap.min.css:5:2700
Unknown property '-moz-osx-font-smoothing'. Declaration dropped. bootstrap.min.css:5:3676
Expected colour but found 'auto'. Expected colour but found '-webkit-focus-ring-color'. Expected end of value but found '-webkit-focus-ring-color'. Error in parsing value for 'outline'. Declaration dropped. bootstrap.min.css:5:15689
Error in parsing value for 'margin-top'. Declaration dropped. bootstrap.min.css:5:35720
Expected colour but found 'auto'. Expected colour but found '-webkit-focus-ring-color'. Expected end of value but found '-webkit-focus-ring-color'. Error in parsing value for 'outline'. Declaration dropped. bootstrap.min.css:5:35947
Unknown pseudo-class or pseudo-element '-ms-input-placeholder'. Ruleset ignored due to bad selector. bootstrap.min.css:5:36878
Unknown pseudo-class or pseudo-element '-webkit-input-placeholder'. Ruleset ignored due to bad selector. bootstrap.min.css:5:36926
Unknown pseudo-class or pseudo-element '-ms-expand'. Ruleset ignored due to bad selector. bootstrap.min.css:5:36978
Expected media feature name but found '-webkit-min-device-pixel-ratio'. bootstrap.min.css:5:37312
Error in parsing value for 'margin-top'. Declaration dropped. bootstrap.min.css:5:38425
Unknown property 'user-select'. Declaration dropped. bootstrap.min.css:5:45471
Expected colour but found 'auto'. Expected colour but found '-webkit-focus-ring-color'. Expected end of value but found '-webkit-focus-ring-color'. Error in parsing value for 'outline'. Declaration dropped. bootstrap.min.css:5:45652
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:45998
Expected colour but found 'solid\9 '. Expected end of value but found 'solid\9 '. Error in parsing value for 'border-top'. Declaration dropped. bootstrap.min.css:5:54924
Expected 'none', URL, or filter function but found 'progid'. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:56291
Expected colour but found 'solid\9 '. Expected end of value but found 'solid\9 '. Error in parsing value for 'border-bottom'. Declaration dropped. bootstrap.min.css:5:56836
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:85213
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:86118
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:86744
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:87376
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:88006
Unknown property 'zoom'. Declaration dropped. bootstrap.min.css:5:88442
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:105685
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:105794
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:107003
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:107056
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:108206
Unknown property 'line-break'. Declaration dropped. bootstrap.min.css:5:108243
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:108268
Unknown property 'line-break'. Declaration dropped. bootstrap.min.css:5:110250
Expected media feature name but found 'transform-3d'. bootstrap.min.css:5:112088
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:113425
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:113581
Expected 'none', URL, or filter function but found 'progid'. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:113840
Error in parsing value for 'background-image'. Declaration dropped. bootstrap.min.css:5:114124
Expected 'none', URL, or filter function but found 'progid'. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:114383
Expected 'none', URL, or filter function but found 'alpha('. Error in parsing value for 'filter'. Declaration dropped. bootstrap.min.css:5:114608
Expected colour but found '#\30 00\9 '. Error in parsing value for 'background-color'. Declaration dropped. bootstrap.min.css:5:115557
GET https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css [HTTP/2.0 200 OK 0ms]
GET https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css.map

 

The latest code is


<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="screen" charset="UTF-8" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
<style>
table td.box {
width: 250px;
border-left: 1px solid #000000;
border-right: 1px solid #000000;
}
table td.box div {
background-color: #0000FF;
}
</style>
</head>
<body>
<div id="results"></div>
<script>
$(function() {
$.getJSON("envoy:011842@http://envoy:011842@192.168.0.12/api/v1/production/inverters", function(data) {
var table = $("<table><tr><th>Serial Number</th><th>Last Report Date</th><th>Status</th><th>Last</th><th>Max</th></tr></table>").addClass("table table-striped");
$.each(data, function(index, item) {
var percent = ((item.lastReportWatts / item.maxReportWatts) * 100);
var row = $("<tr></tr>").html("<td>" + item.serialNumber + "</td><td>" + new Date(item.lastReportDate) + "</td><td class='box'><div style='width: " + percent + "%'> </div></td><td>" + item.lastReportWatts + "</td><td>" + item.maxReportWatts+ "</td>");
table.append(row);
});
$("#results").append(table);
})
});
</script>
</body>
</html>

[\code]

Share this post


Link to post
Share on other sites

Getting closer! Found that the correct structure to pass the command is

 

 

$.getJSON("http://192.168.0.12/api/v1/production/inverters?locale=en&user=envoy&password=011842", function(data) { 

 

So now In edge I am receiving SCRIPT7002: XMLHttpRequest: Network Error 0x2efd, Could not complete the operation due to error 00002efd. Which I believe is Edge won't link to a Localhost domain? At least in one browser I seem to have progressed past the authentication status - so that is a big step forward!

Edited by g__day

Share this post


Link to post
Share on other sites

So tenacity... I recieved more and more arcane issues with this then I tried just running the IP in the browser with debug on - and watched how it sent and recieved the headers. They I googled a simple how to call a web address from JSON and they provided a sample using $.getSCRIPT rather than $.getJSON - and this script worked - in that it returned success and I could see the inverter data in the debug window list returned - so now I just have to understand how to use the formatting code supplied with the $.getJSON to $.getSCRIPT

 

Huge success. I tried simply changing the word JSON to SCRIPT - but on the screen it just handed me the title line and the total power line as 0 0 - so it didn't process any of inverter enteries. But at least now the inverter enteries are being passed!

 

Off now to research how to use $.getSCRIPT to format a list the way it was suggested it should be!

 

Next challenge - I can't find a way to authenticate successfuly using $.get variants other than $.getScript - which launches a window ask for user name and password (which it remembers) then on ok it returns all the results - but doesn't assocaite these results with the Data field!

 

So tantalisingly close - the data is actually there - but hard to reach!

 

In the code below my issue now is console.log( data ); returns undefined - whilst I can see in the debugger call stack the data is actually returned and just waiting for parsing. I have to find some way to connect the return data to my data variable so the $.each (data, function(index, item) { line can process it!

     <script>            
                $(function() {
            var url = "http://192.168.0.12/api/v1/production/inverters?locale=en&user=envoy&password=011842";
            
            $.getScript ( url, function( data, textStatus, jqxhr ) {
            console.log( data );
            console.log( textStatus );
            console.log(jqxhr.status );
            console.log("Load was performed");
                            
                        var table = $("<table><tr><th>Serial Number</th><th>Last Report Date</th><th>Status</th><th>Last</th><th>Max</th></tr></table>").addClass("table table-striped");
                        var totalLastReportWatts = 0;
                        var totalMaxReportWatts = 0;

                     $.each( data, function(index, item) {  
            console.log( index );                                              
                        totalLastReportWatts += item.lastReportWatts;
                        totalMaxReportWatts += item.maxReportWatts;

                        var percent = ((item.lastReportWatts / item.maxReportWatts) * 100);                      
                        var row = $("<tr></tr>").html("<td>" + item.serialNumber + "</td><td>" + new Date(item.lastReportDate) + "</td><td class='box'><div style='width: " + percent + "%'> </div></td><td>" + item.lastReportWatts + "</td><td>" + item.maxReportWatts+ "</td>");
                        table.append(row);                       
                       });
                                   
                    var totalsRow = $("<tr></tr>").html("<td colspan='3'></td><td>" + totalLastReportWatts + "</td><td>" + totalMaxReportWatts + "</td>");
                    table.append(totalsRow);                       
                    $("#results").append(table);
            });
Edited by g__day

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×