WebCoRE reading from Google Sheets with multiple tabs


#3

So, I updated the script so now if no column name is specified, the entire tab is returned. See updated script, test piston and logs below.

I plan to use this to record important log data from both my houses in one place and then I can ask Alexa to read the logs back when I am home using a sim switch and Echo speaks. Another implementation of this thread but will support messages from multiple locations.

// version 1.1 - Guxdude
//   1.1: added capability to request full sheet vs single column
function doGet(request) {
  if(request != null) {

    var spreadSheet = SpreadsheetApp.openById("INSERT SHEET ID HERE");
    // default tab name
    var sheet = spreadSheet.getSheetByName("Logs");
    // No default column name. If none provided, entire sheet will be returned
    var columnName = "";
    var columnNumber = -1;
    
    var tt=request.queryString;
    // Look for tab parameter
    if(tt.search("XtabX")>=0) {
        // If tab parameter is found, update all variables to this spreadsheet
        sheet = spreadSheet.getSheetByName(request.parameter["XtabX"]);
    }
    var firstRowRange = sheet.getRange(1, 1, 1, sheet.getLastColumn());
    var sheetHeaders=firstRowRange.getValues();
    
    // if no column provided, return all data including headers
    var range = sheet.getRange(1,1,sheet.getLastRow(),sheet.getLastColumn());
    
    // Look for Column name
    if(tt.search("colName")>=0) {
        // If tab parameter is found, update all variables to this spreadsheet
        columnName = request.parameter["colName"];
        for(var x=0;x<sheetHeaders[0].length;x++) {
          if(columnName.toString().toLowerCase()==sheetHeaders[0][x].toString().toLowerCase()) {
            columnNumber=x+1;
            break;
          }
        }
        // return requested column without the header
        range = sheet.getRange(2,columnNumber,sheet.getLastRow()-1,1);
    }
    
    var data = range.getValues();
    return ContentService.createTextOutput(JSON.stringify(data)).setMimeType(ContentService.MimeType.JSON);
  }
}

4/14/2020, 8:58:45 AM +957ms
+3748ms	║[8]: [[2020-04-13T10:32:05.000Z], [2020-05-01T07:00:00.000Z], [2020-05-02T07:00:00.000Z], [2020-05-03T07:00:00.000Z], [2020-05-04T07:00:00.000Z], [2020-05-05T07:00:00.000Z], [2020-05-06T07:00:00.000Z], [2020-05-07T07:00:00.000Z]]
+5956ms	║[8]: [[Las Vegas], [Las Vegas], [Las Vegas], [Las Vegas], [Las Vegas], [Las Vegas], [Las Vegas], [Las Vegas]]
+8493ms	║[8]: [[All is good], [Message 1], [Message 2], [Message 3], [Message 4], [Message 5], [Message 6], [Message 7]]
+10144ms	║[8]: [[Las Vegas], [Las Vegas], [Las Vegas], [Las Vegas], [Las Vegas], [Las Vegas], [Las Vegas], [Las Vegas]]
+12016ms	║[7]: [[LV Can Lights (Q1)], [More device 1], [More device 2], [More device 3], [More device 4], [More device 5], [More device 6]]
+13797ms	║[7]: [[10], [90], [50], [70], [0], [100], [25]]
+15426ms	║[[Date, Device, Value], [2020-04-13T22:32:12.128Z, LV Can Lights (Q1), 10], [2020-04-14T07:00:00.000Z, More device 1, 90], [2020-04-15T07:00:00.000Z, More device 2, 50], [2020-04-16T07:00:00.000Z, More device 3, 70], [2020-04-17T07:00:00.000Z, More device 4, 0], [2020-04-18T07:00:00.000Z, More device 5, 100], [2020-04-19T07:00:00.000Z, More device 6, 25]]
+15466ms	║this sheet has 3 Columns and 8 rows. value at C5 is 70

#4

I am seeing a lot of potential here, @guxdude. Keep it up!!

One thing that comes to mind is the spreadsheet is auto-populating, so after a week, there may be dozens (or hundreds) of dataPoints in a column.

To keep our code (and response) streamlined here in webCoRE, I think it would be very important to be able to grab only the last ‘X’ dataPoints in a column.


#5

Would be easy enough to add firstRow and lastRow parameters. Will play with it later tonight and post an update when I have it working.


#6

I love what you are doing here @guxdude, but I believe I owe you an apology. It was not my intention to take focus away from your original post. (which is awesome, BTW)

My mind just took your idea to the next level. It took me a few hours to realize that I probably should have started a new thread for this topic.


#7

It’s OK. I enjoy the challenge! I have some of it working but am trying to figure out if I can set a date range which seems like it would also be useful. Not sure if it should go to a different thread. It’s all about writing and reading google sheets.


#8

To be honest, I think we should keep the focus in the other thread to your original “Example Piston”, and keep this new project separate in the “Piston Design Help” category…


#9

@guxdude, new topic is all yours, edit away on that first post.


#10

Thanks, @ipaterson!!


#11

Really nicely done!


#12

@guxdude - Thanks for you work on this. I’m trying to read from a sheet with your code, but each time I get the following error:

TypeError: Cannot read property &#39;getRange&#39; of null (line 13, file &quot;Code&quot;)

What am I missing?


#13

What is the get URL you are using? Seems like the URL is not formatted correctly. Are you trying to read a specific row or column?


#14

@guxdude
I cannot not get my script correct. I have several questions.

I’m not sure what this means…


Do I add the word “Time” in cell A1 and freeze that row? Why would I do this?

I attempted to test…not sure what “test data” I need to delete from my spreadsheet.

When I tested, I got this…
image

My script.


#15

Yes, A1 should be the string “Time”.

The first row is the header row. A1 is the timestamp, and A_n_ is the label of the value being logged. When a new value comes in, the JS looks for an existing column for that label before adding one.


#16

When I click the “Debug” button I get this…

image


#17

(not sure why are clicking “Debug” - you don’t want to use that)

Your script is truncated. It’s about 50 lines.


#18

Yes, add the word ‘Time’. Then the script will automatically add the actual time of each log to that column. Additional columns will be added automatically to the right of this column for any column name that does not already exist.

Did you test by pasting the URL into browser window? Did you make sure you have the correct URL? Did you publish your function as a web app after creating it?


#19

yes, I think so, and yes.


#20

How do you know that? I only see 4.


#21

Are you using my script in post 1 of this thread or the script on the GitHub I referenced? My script modifies the functionality a bit as described in the first post.


#22

No. That may be my problem. Let me work on that…Thanks.