• On the Client side HTML and script is used to construct and edit the following object:

    /* LogObj1 on client sent via POST JSON*/
    var LogObj1={
      Fname:"xxx.csv",
      Interval:1000, //milliseconds between samples
      items:[
        // header is text at top of column in csv file
        // cmd source for data in each column
        // can be in a different order
        // and have more or fewer items
        {header:"N",cmd:"return(x.LL.count)"},
        {header:"Date",cmd:"return(x.Day+\" \"+x.Month+\" \"+x.Year)"},
        {header:"Time",cmd:"return(x.Hour+\":\"+x.Minute+\":\"+x.Second)"},
        {header:"A0",cmd:"return(analogRead(A0).toFixed(2))"},
        {header:"A1",cmd:"return((analogRead(A1)*x.LL.items[4].slope+x.LL.items[4].offset).toFixed(2))",slope:100,offset:-50
        },
        {header:"A2",cmd:"return((analogRead(A2)*100-50).toFixed(2))"},
        {header:"A3",cmd:"return(SanalogRead(A3).toFixed(2))"},
        {header:"Board Temp C",cmd:"return(E.getTemperature().toFixed(2))"},
        {header:"Board Temp F",
         cmd:"return((E.getTemperature()*9/5+32).toFixed(2))"
        }
      ],
      count:0, // Number of lines logged
      N:10, // stop logging after count>N
    }; //end LogObj1
    
    

    Notice several methods are used to scale the analog inputs using a slope/offset (intercept).
    The Client script stringifies the object and sends it after the HTTP POST header.
    On the Server side the HTTP header is used to determine that the client request is a post and that the Filename in the HTTP header matches “LOG”.
    The stringified object is buffered using the Length in the HTTP header.
    At this point I’m testing the code to process the request. It writes to console.log instead of a file.

    //An object constructor
    function LogObj(){
      this.Month=1,
      this.Day=1,
      this.Year=0,
      this.Hour=0,
      this.Minute=0,
      this.Second=0,
      this.LL={},     //LL is where the Posted object fits
      this.channels=[], // the cmds in LL are converted to functions in channels
    
    //Methods for this object
    this.doHeaders=function(){
        var str="";
        for(var j=0;j in this.LL.items;j++)str+=this.LL.items[j].header+",";
        console.log(str+"\n\r");
       },//end OutputHeaders
    
    this.doData=function(id){
      //openfile append
     //setup date and time
        var t = new Date();
        this.Month=t.getMonth();
        this.Day=t.getDate();
        this.Year=t.getFullYear();
        this.Hour =t.getHours(); 
        this.Minute=("0"+t.getMinutes()).substr(-2);
        this.Second= ("0"+t.getSeconds()).substr(-2);
    //use the channels to get readings
       var readings=[];
       this.LL.count++;
       if(this.LL.count <= this.LL.N){
        for(i=0;i in this.channels;i++)readings[i]= this.channels[i](this);
        console.log(readings.join(", ")+"\n\r");
       }else{
        clearInterval(id);
       }//endif
       //close file 
      };//end doData
    }//end LogObj
    
    

    The JSON.stringify() doesn’t work with embedded methods. The transmitted LogObj1 object is JSON.parsed into the LL field of the LogObj object.
    The code that executes the LogObj follows:

    // Test the LogObj methods using data in LogObj1
    function Test(){
    // The client stringifies and JSON POSTs LogObj1
    var W=JSON.stringify(LogObj1);//the client does this and sends it over
      console.log(W);
    // The server  creates an instance of LogObj
    var Y=new LogObj();
    //The server then embeds the JSON data in the object
    Y.LL=JSON.parse(W);
    //how the  cmd strings convert to functions
    for(var j=0;j in Y.LL.items;j++)
      Y.channels.push(Function("x",Y.LL.items[j].cmd));
      console.log("Y= ",Y);
      console.log("channels\n\r",Y.channels);
    var ID;
      //check to see if file exists
      //open file overwrite here
    Y.doHeaders();
      //close file
    ID=setInterval(function(ID){Y.doData();},Y.LL.Interval,ID);
      console.log("Test End");
    }//end Test
    
    //Pretend the client has POSTed LogObj1
    //Use the info to create a csv file, write headers and collect data
    Test();
    
    

    The “eval()” command is not used and each Client request creates a new LogObj.

    The left side screen using WebIDE:

    N,Date,Time,A0,A1,A2,A3,Board Temp C,Board Temp F,
    Test End
    =undefined
    1, 28 3 2016, 20:57:13, 0.79, 25.54, 21.68, 21.34, 35.74, 95.95
    2, 28 3 2016, 20:57:14, 0.76, 22.49, 20.70, 20.92, 36.11, 96.33
    3, 28 3 2016, 20:57:15, 0.76, 23.24, 20.87, 20.92, 35.96, 95.95
    4, 28 3 2016, 20:57:16, 0.77, 24.07, 21.05, 20.89, 35.93, 96.28
    5, 28 3 2016, 20:57:17, 0.77, 23.49, 20.80, 20.85, 35.74, 95.95
    6, 28 3 2016, 20:57:18, 0.77, 23.97, 21.24, 21.05, 35.96, 95.95
    7, 28 3 2016, 20:57:19, 0.77, 23.54, 20.80, 20.95, 35.93, 95.95
    8, 28 3 2016, 20:57:20, 0.77, 23.83, 21.24, 21.19, 35.96, 96.28
    9, 28 3 2016, 20:57:21, 0.77, 23.90, 21.22, 21.05, 35.96, 95.95
    10, 28 3 2016, 20:57:22, 0.77, 23.78, 21.05, 21.02, 35.98, 96.67
    >
    
    

    Notice that the Test function ends after the CSV headers are printed but before the data are printed.


    1 Attachment

  • Updated Version 2 May 2016
    allObjects gave me some pointers about object constructors, making the object methods exist only once for the object and not in each instance and the use of the keyword “bind” when starting intervals.
    http://forum.espruino.com/conversations/286055/
    These lessons are applied to this project.
    It has been pointed out that using eval() is a security problem. Having commands in the object being shipped over an open channel is also a security problem. I hope to further rework this code to address this issue.
    The output:

    >echo(0);
    N,Date,Time,A0,A1,A2,A3,Board Temp C,Board Temp F,
    Test End
    =undefined
    1, 2 4 2016, 14:51:40, 0.81, 31.39, 0.73, 0.71, 35.39, 95.33
    2, 2 4 2016, 14:51:41, 0.80, 32.57, 0.74, 0.72, 35.37, 95.33
    3, 2 4 2016, 14:51:42, 0.82, 33.57, 0.75, 0.72, 35.37, 95.33
    4, 2 4 2016, 14:51:43, 0.85, 34.69, 0.75, 0.72, 35.39, 94.88
    5, 2 4 2016, 14:51:44, 0.87, 35.77, 0.76, 0.73, 35.18, 95.27
    6, 2 4 2016, 14:51:45, 0.87, 35.79, 0.76, 0.73, 35.18, 95.33
    7, 2 4 2016, 14:51:46, 0.88, 36.50, 0.76, 0.73, 35.18, 95.27
    8, 2 4 2016, 14:51:47, 0.88, 36.94, 0.76, 0.73, 35.39, 96.10
    9, 2 4 2016, 14:51:48, 0.88, 37.35, 0.77, 0.73, 35.18, 95.27
    10, 2 4 2016, 14:51:49, 0.89, 37.26, 0.77, 0.73, 35.58, 95.66
    >
    
    

    Testlog8.js is attached.


    1 Attachment

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Using JSON POST to Start Logging a CSV File on an Espruino Server

Posted by Avatar for ClearMemory041063 @ClearMemory041063

Actions