User avatar
mark3112
Posts: 46
Joined: Mon Apr 09, 2018 10:39 am

Javascript – copy file – possible?

Sun Dec 29, 2019 4:16 pm

I have a data logger program on my Pi monitoring my central heating. Every minute it updates a .csv file with the temperatures. I want to be able to access the data via a webpage using Dygraphs. Dygraphs can only access the file if it is in the www folder but I don’t want to store the data on the SD Card as I suspect it will kill the card with all the writes so I save the .csv file on a USB drive. I am trying to use Javascript to copy the file from the USB drive to the www folder when the page loads but so far I haven’t been able to get it to work and am starting to think that the sandboxed nature of Javascript means it can’t work. Am I correct? Could someone point me to an alternative method of achieving what I am trying to do? Thanks.
temp.html works if execute.js removed and csv file present
sudo node copyfile works from command line

Code: Select all

--------------------------------------------------------------
Temp.html
 
<html>
<head>
<script type="text/javascript"
  src="dygraph.js"></script>
<link rel="stylesheet" src="dygraph.css" />
</head>
<body>
<div id="graphdiv2"
  style="width:1200px; height:700px;"></div>

<script src="require.js"></script>
<script src="execute.js"></script>

<script type="text/javascript">

  g2 = new Dygraph(
    document.getElementById("graphdiv2"),
    "tempdata2.csv", // path to CSV file
    {

 //     customBars: true,
//      title: 'Central Heating Data - xx/xx/xx',
      ylabel: 'Temperature (C)',
      legend: 'always',
      showRangeSelector: true,

      rollPeriod: 1
//      showRoller: true
    }          // options
  );
</script>
</body>
</html>


--------------------------------------------------------------
Execute.js (run copyfile with sudo)

//define(function (require) {
//    var namedModule = require('child_process');
//});

function execute(command) {
  const exec = require(['child_process']).exec

  exec(command, (err, stdout, stderr) => {
    process.stdout.write(stdout)
  })
}

execute('sudo node copyfile')


--------------------------------------------------------------
copyfile.js 

//copyfile.js
const fs = require('fs');

// destination will be created or overwritten by default.
fs.copyFile('/media/usb/tempdata2.csv', '/var/www/html/tempdata2.csv', (err) =>$
  if (err) throw err;
  console.log('File was copied to destination');
});
--------------------------------------------------------------
You can make a real CPU in a FPGA, but you can’t make a real FPGA in a CPU.

Heater
Posts: 17416
Joined: Tue Jul 17, 2012 3:02 pm

Re: Javascript – copy file – possible?

Sun Dec 29, 2019 4:52 pm

Javascript running in the browser as part of your web page cannot copy files around on the machine it is running on. Javascript is "sand boxed" in the browser for security.

Javascript running in the browser as part of your web page does not even know that it may be running on the same machine as the server it came from. Typically it is not. So it has no means to move files around on the web server machine. Even if they are the same.

You are running that execute.js in the page in the browser with '<script src="execute.js"></script>' so no. It cannot do what you want.

What are you using as a web server?

If I were doing this I would likely use node.js as the web server. Using the express.js module. That node.js code could do all the reading of your sensors, serving web pages and serving data to the js that is running in your browser drawing graphs.
Memory in C++ is a leaky abstraction .

User avatar
mark3112
Posts: 46
Joined: Mon Apr 09, 2018 10:39 am

Re: Javascript – copy file – possible?

Sun Dec 29, 2019 7:27 pm

It’s been a long time since I did anything with HTML and Javascript is entirely new to me so please excuse me if I get things mixed up. I am using Apache2 on the Pi as the web server and accessing it with Firefox on my phone.
The program running on the Pi that creates the data, controls my (solid fuel based) central heating system and interacts with my Home Automation system which controls the pumps and valves via it’s CAN network. At bedtime the HA system shuts everything off which allows the heat to flow into the water tank. When that gets up to temp a valve shuts that off and the HA only turns things back on in the morning or if the Pi sees that central heating water is getting too hot so I don’t have to waste heat if I don’t need to.
My background is writing embedded code and I am comfortable leaving the heating to that rather than my very limited Javascript knowledge.
The graph and override options via a web page would be a nice to have, otherwise I will just have to leave the Putty session running on my media centre for control and copy the graphical data over to the PC and import it into Excel to get the graph. All of this is on a private network with no external access so compromising the Javascript security isn’t an issue except that it seems to be stopping me doing what I want and that wouldn’t be an issue if the SD Cards didn’t wear out.
You can make a real CPU in a FPGA, but you can’t make a real FPGA in a CPU.

Heater
Posts: 17416
Joined: Tue Jul 17, 2012 3:02 pm

Re: Javascript – copy file – possible?

Sun Dec 29, 2019 7:55 pm

I feel your pain. I too dd a lot of embedded work and all kind of things before I had to pick up some Web technology a couple of years back.

Luckily it was just the time when one could forget about all that old Apache and PHP stuff and do everything with node.js. It was great to be able to use only one language for the server and in the browser. Today I have node.js running on remote embedded Pi systems!

Anyway, perhaps the quickest route for you to get a result is to configure Apache to serve everything from a web root on your other media rather than the usual www directory on the SD card.
Last edited by Heater on Mon Dec 30, 2019 4:20 am, edited 1 time in total.
Memory in C++ is a leaky abstraction .

User avatar
mark3112
Posts: 46
Joined: Mon Apr 09, 2018 10:39 am

Re: Javascript – copy file – possible?

Mon Dec 30, 2019 12:44 am

“configure Apache to serve everything from a web root on your other media” That I like, will look into it. Thanks.
I was going for a more primitive approach. When the page loads create a flag file, let the C code find the file and move the temperature data. Once it’s displayed, delete the files. The C code reads the thermocouples every 100ms so it can check for the file at the same time. Not fast but it doesn’t need to be. Here’s what I have sketched out so far.

Code: Select all

// >>>CREATE FLAG FILE<<<

const fs = require('fs');

fs.writeFile("/tmp/flag", "X", function(err) {
    if(err) {
        return console.log(err);
    }
    console.log("The file was saved!");
}); 

// >>>WAIT FOR tempdata FILE<<<

var fs = require('fs');
var working = false;
const watcher = fs.watch('tempdata.csv', function (event, filename) => {
  if (filename && event == 'change' && active == false) {
    active = true;
    // >>>SHOW GRAPH<<<
    active = false;
});
watcher.close()

You can make a real CPU in a FPGA, but you can’t make a real FPGA in a CPU.

Return to “General programming discussion”