CSV to PHP, works but is butt ugly.

Hi. I have built the following project. Its to test my wifes garden bed to see if it needs watering during our Cali restricted water consumption period.

Everything works, thats the good news. The bad news is the display. It’s just butt ugly. The new data is at the bottom of the growing stack of data.

I have an Arduino testing the soil. It reports its result to its serial port. I have a RasPi connected via USB and it is reading its serial port connection with the Arduino. The RasPi records what it gets on its port, and saves the info to a CSV file.

I have a piece of code in PHP that displays the CSV file. The issue is that as it grows, the new info is at the bottom of a long list of results. How do i invert the CSV display, so its latest info is at the top of the page, and not at the bottom.

info is live displayed at www.bammo.info (spare url of mine) be kind to the poor raspi server.

The php code parsing the CSV file and serving the page is as follows.
[php]<?PHP

$file_handle = fopen(“widgets.csv”, “r”);

while (!feof($file_handle) ) {

$line_of_text = fgetcsv($file_handle, 1024);

print $line_of_text[0] . $line_of_text[1]. $line_of_text[2] . “
”;

}

fclose($file_handle);

?>[/php]

Disclosure, I am a noob at PHP and have no clue how I got all of this to work. The code is found off the net, and only changed to fix my default settings. Otherwise its as the write posted it.

I know its easy for real nerds to get an arduino posting to the net live data, for me it was exciting until I realized just how fugly it was being displayed. Any help would be appreciated on improving the display of the data would be appreciated.

Thank you to anyone who ponders how to invert a CSV file for display.

[php]$file = file(“widgets.csv”);
$file = array_reverse($file);
foreach($file as $f){
echo $f."
";
}[/php]

Your welcome. Feel free to click the Karma link for me next to my name.

Benanamen,

Thank you for the code. I tried to implement it as following

[php]<?PHP

$file = file(“widget.csv”);
$file = array_reverse($file);
foreach($file as $f){
echo $f."
";
}

fclose($file_handle);

?>[/php]

However nothing displays at www.bammo.info/test.php what did I miss?

Jack

Where is the csv file? As is, the code is looking for it here: http://www.bammo.info/widget.csv

It is not there.

Benanamen,

That was the problem, I had managed to save the new CSV file as “widgets”.

I have changed the code to catch the right file now, and changed it to index at www.bammo.info and it works perfectly.

Thank You, Thank You, Thank You.

Best,

Jack

Here’s another solution, if the file grows big then using file_get_contents() or file() will waste memory as they read the entire file into memory

this solution only read the data you actually want, starting from the last line.

[php]<?php

function readLog($fileName, $rows) {
if (!file_exists($fileName)) {
return false;
}
$fl = fopen($fileName, ‘r’);
for ($x_pos = 0, $ln = 0, $output = array(); fseek($fl, $x_pos, SEEK_END) !== -1; $x_pos–) {
$char = fgetc($fl);
if ($char === “\n”) {
if (++$ln === $rows) {
break;
}
continue;
}
$output[$ln] = $char . ((array_key_exists($ln, $output)) ? $output[$ln] : ‘’);
}
fclose($fl);

return $output;
}

$rows = !empty($_GET[‘rows’]) ? (int) $_GET[‘rows’] : 10;
$data = readLog(‘widgets.csv’, $rows);

$i = 1;
foreach ($data as $line) {
echo $i . ': ’ . $line . ‘
’;
$i++;
}[/php]

Here you can use yourfile.php?rows=the number of rows you want. ex: yourfile.php?rows=5
If you don’t set rows then it will default to 10

Feel free to click karma next to my name. I have no idea what it does though (Yet). JimL is right, if your file is large and you only want to see the last X amount of rows use what he posted. You didnt mention how big your file is or will be and only asked how to invert it so I gave you the simplest code to do that.

Jim,

Thank you for this version, I placed the code at www.bammo.info/new.php but like my first attempt with the first solution, this one doesnt seem to parse for me correctly at first go.

I posted the code exactly as you sent it.

Do you have any ideas by it didnt work? I love the idea of controlling the total data returned, its a real enhancement to the project when I add additional fields of data to the sequence. ie next is temp and humidity.

I would love to get your code working.

Thanks,

Jack

Jims code is good as is. What result are you getting?

To get other than the default ten rows you would do like:

[php]yourscript.php?rows=3[/php]

Benanamen,

I am not getting anything to show up as a result of running the page. www.bammo.info/new.php doesn’t parse anything to the screen.

The idea behind this project is to get an Arduino controller to out its results analog and digital sensors to an RasPi, that posts the info to the web for monitoring.

The file grows until I change it, so yes, this code is really a massive upgrade to the idea. It would allow the data file to grow for days to weeks at a time, with out being required for each display. I am going to turn down the number of times it records a result, to cut down on the size of the log file displayed.

I am adding Temp & Humidity sensors to the output, so I can monitor my wifes garden bed during the summer and water it when the dirt gets dry about 4 inches below soil top. The server will send me an SMS and a Tweet shaming me for allowing the garden to dry out during the drought in Cali.

The project looks like this. (hopes attached files works)


Attach your widgets.csv so I can test your actual file

Benanamen,

Thank you again for helping. I have clicked Karma for you until it told me to stop :o

This picture shows the Ardu with LCD with RasPi Cam setup for testing.

This site doesnt allow .csv so here is a dropbox link to the file.

The CSV file is really just a putty.log file of a serial connection on the RasPi being saved to the www folder.


It is working properly on my server. What version of PHP are you running? What server are you on?

What exactly is the code in new.php?

http://galaxyinternet.us/jackbarnes/

http://galaxyinternet.us/jackbarnes/read_csv_reverse_advanced.php?rows=30

http://galaxyinternet.us/jackbarnes/read_csv_reverse_advanced.php?rows=13

http://galaxyinternet.us/jackbarnes/read_csv_reverse_advanced.php

I am using a Rasberry Pi as the Linux box. It has http://bammo.info/phpinfo.php diagnostic available.

the quick answer is PHP Version 5.4.4-14+deb7u7

System Linux raspberrypi 3.10.25+ #622 PREEMPT Fri Jan 3 18:41:00 GMT 2014 armv6l

your working example of Jims code is exactly what I was hoping for.

Let me see your new.php exactly as you have it.

Here is a C&P of it. [php]<?php

function readLog($fileName, $rows) {
if (!file_exists($fileName)) {
return false;
}
$fl = fopen($fileName, ‘r’);
for ($x_pos = 0, $ln = 0, $output = array(); fseek($fl, $x_pos, SEEK_END) !== -1; $x_pos–) {
$char = fgetc($fl);
if ($char === “\n”) {
if (++$ln === $rows) {
break;
}
continue;
}
$output[$ln] = $char . ((array_key_exists($ln, $output)) ? $output[$ln] : ‘’);
}
fclose($fl);

return $output;
}

$rows = !empty($_GET[‘rows’]) ? (int) $_GET[‘rows’] : 10;
$data = readLog(‘widgets.csv’, $rows);

$i = 1;
foreach ($data as $line) {
echo $i . ': ’ . $line . ‘
’;
$i++;
}

?>[/php]

Nothing wrong with what you posted. Problem is on your server. Set permissions on the csv file to 777 and see if that changes anything.

Thank you for the efforts. I have no clue why this isnt displaying. I have changed the settings for CSV and for the new.php too. Both read -rwxrwxrwx 1 root root

No luck tonight. I guess its time to sit back and ponder why. I am logged in as root so its not a permission issues from the admin point of view. Your code parses the CSV.

Thank you for getting the original upgrade to work, and for the continued effort tonight. I may try a different linux arm chip / flavor install down the road if I dont get around this issue with this install. This code enhancement is what I need to work. The next question is what solution to take.

I want to thank Jim and Benanamen for their help. The code was correct, it was throwing an error for a hidden \xc2 issue. Once I sterilized the C&P and reloaded the new file, it worked perfectly.

Its results are as follow:

1:
2: Soil; 814
3: Soil; 814
4: Soil; 815
5: Soil; 815
6: Soil; 815
7: Soil; 815
8: Soil; 814
9: Soil; 814
10: Soil; 813

Any thoughts on how to snip the first one from showing up blank? ie start with #2 for the display?

Thank you again guys for a major upgrade to the project, in how it displays its results.

I have moved the new.php to the index page now for the RasPi. www.bammo.info with it displaying 2 lines. 1st blank, and 2 with latest reported result.

Well, you could do this

[php]<?php

function readLog($fileName, $rows) {
if (!file_exists($fileName)) {
return false;
}
$fl = fopen($fileName, ‘r’);
for ($x_pos = 0, $ln = 0, $output = array(); fseek($fl, $x_pos, SEEK_END) !== -1; $x_pos–) {
$char = fgetc($fl);
if ($char === “\n”) {
if (++$ln === $rows+1) { // ugly hack to remove first empty row
break;
}
continue;
}
$output[$ln] = $char . ((array_key_exists($ln, $output)) ? $output[$ln] : ‘’);
}
fclose($fl);
array_shift($output); // ugly hack to remove first empty row

return $output;
}

$rows = !empty($_GET[‘rows’]) ? (int) $_GET[‘rows’] : 10;
$data = readLog(‘widgets.csv’, $rows);

$i = 1;
foreach ($data as $line) {
echo $i . ': ’ . $line . ‘
’;
$i++;
}[/php]

But as said in the comments it’s an ugly hack. It will always remove the first entry no matter what it containts.

WIll the empty line always be there? Is it possible to have multiple empty lines?

oh and a ps: the csv data you have isn’t really csv… :stuck_out_tongue:

Sponsor our Newsletter | Privacy Policy | Terms of Service