Help with php for a scoreboard

I have built a scoreboard using the html from https://buildyourownscoreboard.wordpress.com/
But I have added several variables myself, one of which is RunsReq
RunsReq is calculated by subtracting Score from Target, so if the target is 150 & the score is 95, RunsReq is 55
In the first Innings of the game the target & RunsReq are obviously zero, so there’s a line of code that converts RunsReq 0 in to a dash. There’s then some code that tells the scoreboard not to display a dash so the RunsReq on the board is blank. Perfect.

So as the score increases the RunsReq decreases. My problem is that once the RunsReq reached 0, the digit on the board goes blank. But I want it to display a 0.

There’s also a line that strips out leading zeroes so that it displays 65 rather than 065

I will paste the entire php script below but the relevant lines ( I think) are these:

if($target==0) { $runsreq="—"; } else { $runsreq = ltrim($runsreq, ‘-’); $runsreq = str_pad($runsreq, 3, ‘-’, STR_PAD_LEFT); }

if($target==0) { $target="—"; } else { $target = ltrim($target, ‘0’); $target = str_pad($target, 3, ‘-’, STR_PAD_LEFT); }

if($runsreq==0) { $runsreq="—"; } else { $runsreq = ltrim($runsreq, ‘0’); $runsreq = str_pad($runsreq, 3, ‘-’, STR_PAD_LEFT); }

So I think I need to add an extra line that says (in Excel language)
IF target >0 AND runsreq<1 THEN runsreq = “–0”

I’ve tried every combination I can think of & can’t make it work so any help would be greatly appreciated.

Full code of PHP script:

<?php
	//
	// 20.04.2016
	//
	// Overs and wickets output swapped from orginal scoreboard.php to account for Bradford on Avon CC scoreboard design to show 
	// overs - wickets - target along the bottom
	//
	// 20.04.2016
	// Form method changed from POST to GET  and data simplified to send one string - 
	// total[3] wickets[1] overs[2] batsa[3] batsb[3] target[3]
	//
	// e.g. 126807042084453 = Total 126, Wickets 8, Overs 07, Batsman A 042, Batsman B 084, Target 453.
	//
	// 18.06.2016
	// Added back in line for original westbury on server scoreboard layout for second line
	// see lines 50 and 51 
	// 
	// 28.12.2018
	// Modified version for whitchurch CC which includes batsman numbers.
	//
	// Changed string order & contents Tot/Wkts/Overs/Tatget/RunsReq 123456123456
	
	file_put_contents('save.txt', $_GET['data']); // Save the scores! They will be automatically loaded when the scoreboard is turned on. Make sure save.txt is writable by the web server user!
	
	include "php_serial.class.php";

	$total=substr($_GET['data'], 0, 3); //Get first 3 digits
	$wicketsOnes=substr($_GET['data'], 3, 1); //Get next 1 digit
	$overs=substr($_GET['data'], 4, 2); //Get next 2 digits
	$runsreq=$runsreq=substr($_GET['data'], 6, 3); //Get next 3 digits
	$target=$target=substr($_GET['data'], 9, 3); //Get next 3 digits
	$batsmana=$batsmana=substr($_GET['data'], 12, 3); //Get next 3 digits
	$batsmanb=$batsmanb=substr($_GET['data'], 15, 3); //Get next 3 digits
	$batsmananum=$batsmananum=substr($_GET['data'], 18, 2); //Get next 2 digits
	$batsmanbnum=$batsmanbnum=substr($_GET['data'], 20, 2); //Get next 2 digits
		$lastwkt=$lastwkt=substr($_GET['data'], 22, 3); //Get next 3 digits
			$pship=$pship=substr($_GET['data'], 25, 3); //Get next 3 digits
			$dltarget=$dltarget=substr($_GET['data'], 28, 3); //Get next 3 digits
			$lastman=$lastman=substr($_GET['data'], 31, 3); //Get next 3 digits
			
// creatre new variable & pad it out to 3 digits, also make it blank if target = 0 (as done below for other fields)
//	$runsreq = $target - $total;
	if($target==0) { $runsreq="---"; } else { $runsreq = ltrim($runsreq, '-'); $runsreq = str_pad($runsreq, 3, '-', STR_PAD_LEFT); }
//	if($runsreq<0) { $runsreq="---"; } else { $runsreq = ltrim($runsreq, '0'); $runsreq = str_pad($runsreq, 3, '-', STR_PAD_LEFT); }	



	// Now we want to check if the mutiple digit displays are under 10 or over 10 and turn off the LED's instead of showing 0
	// But if they are 0, show 0
	//
	// First strip the leading zeros, then "pad" the number to the required length by adding dashes to turn off
	// LEDs that would be showing 0 before the actual score
	
	if($total==0) { $total="--0"; } else { $total = ltrim($total, '0'); $total = str_pad($total, 3, '-', STR_PAD_LEFT); }
	if($overs==0) { $overs="-0"; } else { $overs = ltrim($overs, '0'); $overs = str_pad($overs, 2, '-', STR_PAD_LEFT); }
	if($batsmana==0) { $batsmana="--0"; } else { $batsmana = ltrim($batsmana, '0'); $batsmana = str_pad($batsmana, 3, '-', STR_PAD_LEFT); }
	if($batsmanb==0) { $batsmanb="--0"; } else { $batsmanb = ltrim($batsmanb, '0'); $batsmanb = str_pad($batsmanb, 3, '-', STR_PAD_LEFT); }
	if($target==0) { $target="---"; } else { $target = ltrim($target, '0'); $target = str_pad($target, 3, '-', STR_PAD_LEFT); }
	if($runsreq==0) { $runsreq="---"; } else { $runsreq = ltrim($runsreq, '0'); $runsreq = str_pad($runsreq, 3, '-', STR_PAD_LEFT); }

// THIS IS WHERE I THINK I NEED TO PUT MY NEW LINE

		if($lastwkt==0) { $lastwkt="---"; } else { $lastwkt = ltrim($lastwkt, '0'); $lastwkt = str_pad($lastwkt, 3, '-', STR_PAD_LEFT); }
			if($pship==0) { $pship="---"; } else { $pship = ltrim($pship, '0'); $pship = str_pad($pship, 3, '-', STR_PAD_LEFT); }
				if($lastman==0) { $lastman="---"; } else { $lastman = ltrim($lastman, '0'); $lastman = str_pad($lastman, 3, '-', STR_PAD_LEFT); }
	$batsmananum = ltrim($batsmananum, '0'); $batsmananum = str_pad($batsmananum, 2, '-', STR_PAD_LEFT);
	$batsmanbnum = ltrim($batsmanbnum, '0'); $batsmanbnum = str_pad($batsmanbnum, 2, '-', STR_PAD_LEFT);

	include 'updateSpectator.php';

	$serial = new phpSerial;
	$serial->deviceSet("/dev/ttyACM0");
	#$serial->deviceSet("/dev/ttyAMA0");
	#$serial->confBaudRate(115200);
	$serial->confParity("none");
	$serial->confCharacterLength(8);
	$serial->confStopBits(1);

	

//original string
// $tempString="4,".$total.",".$overs.",".$wicketsOnes.",".$target.",".$batsmana.",".$batsmanb."".$batsmananum.",".$batsmanbnum."#";
// use ONE OR THE OTHER of these depending on whether you want Target or Runs Required displayed
//  $tempString="4,".$total.",".$overs.",".$wicketsOnes.",".$target.",".$batsmana.",".$batsmanb."".$batsmananum.",".$batsmanbnum."#";
	$tempString="4,".$total.",".$wicketsOnes.",".$overs.",".$runsreq.",".$batsmana.",".$batsmanb.",".$batsmananum.",".$batsmanbnum.",".$dltarget."#";
//or it might be this one that makes it work
//	$tempString="4,".$total.",".$wicketsOnes.",".$overs.",".$runsreq.",".$target.",".$batsmana.",".$batsmanb."".$batsmananum.",".$batsmanbnum."#";
	




	echo $tempString;
	#echo($tempString."<br>");
	$serial->deviceOpen();
	$serial->sendMessage($tempString);


	$serial->deviceClose();

	#print_r($_POST);
?>

I have some questions. Is RunsReq always calculated using $target - $total (score), and if so why is there a substr() statement getting it’s value out of the submitted data? Is target a fixed value or does it change during a game? You have a statement that - ‘In the first Innings of the game the target & RunsReq are obviously zero’. Did you mean that the score and RunsReq are obviously zero?

Note: you should perform any calculations or comparisons on the raw data values, and only format the data right before you output it, and in fact, you may want to use different variables for the formatted values and leave the raw values as is. At the point where your comment is, both $target and $runsreq have been formatted and any comparison would need to take into account that formatting.

Let me introduce you to a programming practice called a data-driven design, where you have a data structure (array, database table) that defines the expected data and their dynamic characteristics. You then loop over this defining data structure to control what general-purpose code does. This eliminates the repetitive coding for each value. This also lets you create new systems just by editing/creating new defining data.

Based on my understanding of what you are doing, see the following example code, that should (untested) work -

<?php
//
// 20.04.2016
//
// Overs and wickets output swapped from orginal scoreboard.php to account for Bradford on Avon CC scoreboard design to show
// overs - wickets - target along the bottom
//
// 20.04.2016
// Form method changed from POST to GET  and data simplified to send one string -
// total[3] wickets[1] overs[2] batsa[3] batsb[3] target[3]
//
// e.g. 126807042084453 = Total 126, Wickets 8, Overs 07, Batsman A 042, Batsman B 084, Target 453.
//
// 18.06.2016
// Added back in line for original westbury on server scoreboard layout for second line
// see lines 50 and 51
//
// 28.12.2018
// Modified version for whitchurch CC which includes batsman numbers.
//
// Changed string order & contents Tot/Wkts/Overs/Tatget/RunsReq 123456123456

file_put_contents('save.txt', $_GET['data']); // Save the scores! They will be automatically loaded when the scoreboard is turned on. Make sure save.txt is writable by the web server user!

include "php_serial.class.php";

// define the expected fields and their dynamic characteristics
$fields = [];
// the 'default' element is what to use when the value is zero (logic for special handling of runsreq is in the later code)
// the 'display_order' element is both when to include the formatted value in the display output (any true value) and in what order it is in the data being sent to the display
$fields['total'] = 			['offset'=>0, 'len'=>3,'default'=>'--0','display_order'=>1];
$fields['wicketsOnes'] = 	['offset'=>3, 'len'=>1,'default'=>'0','display_order'=>2]; // this is output as is, with no formatting
$fields['overs'] = 			['offset'=>4, 'len'=>2,'default'=>'-0','display_order'=>3];
$fields['runsreq'] = 		['offset'=>6, 'len'=>3,'default'=>'---','display_order'=>4]; // --- blank, --0 zero
$fields['target'] = 		['offset'=>9, 'len'=>3,'default'=>'---','display_order'=>false];
$fields['batsmana'] = 		['offset'=>12,'len'=>3,'default'=>'--0','display_order'=>5];
$fields['batsmanb'] = 		['offset'=>15,'len'=>3,'default'=>'--0','display_order'=>6];
$fields['batsmananum'] = 	['offset'=>18,'len'=>2,'default'=>'-0','display_order'=>7]; // never expected to be a 0 value, default doesn't matter
$fields['batsmanbnum'] = 	['offset'=>20,'len'=>2,'default'=>'-0','display_order'=>8]; // never expected to be a 0 value, default doesn't matter
$fields['lastwkt'] = 		['offset'=>22,'len'=>3,'default'=>'---','display_order'=>false];
$fields['pship'] = 			['offset'=>25,'len'=>3,'default'=>'---','display_order'=>false];
$fields['dltarget'] = 		['offset'=>28,'len'=>3,'default'=>'--0','display_order'=>9]; // this is output as is, with no formatting
$fields['lastman'] = 		['offset'=>31,'len'=>3,'default'=>'---','display_order'=>false];

// display order -
// $total, $wicketsOnes, $overs, $runsreq, $batsmana, $batsmanb, $batsmananum, $batsmanbnum, $dltarget
// target, lastwkt, pship, and lastman are not sent to the display

// parse the input data
$data = [];
foreach($fields as $field=>$arr)
{
	$data[$field] = substr($_GET['data'],$arr['offset'],$arr['len']);
}

// format the data
$display = [];
foreach($fields as $field=>$arr)
{
	// for a true display_order, include the formatted value in the output using the display_order as the array key
	if($arr['display_order'])
	{
		// special handling for runsreq
		if($field == 'runsreq' && $data['target'] > 0)
		{
			// display a zero instead of the default --- blanks
			$display[$arr['display_order']] = format($data[$field], '--0', $arr['len']);
		}
		else
		{
			// normal processing
			$display[$arr['display_order']] = format($data[$field], $arr['default'], $arr['len']);
		}
	}
}

// function to format the output
function format($value, $default, $len)
{
	if($value==0)
	{
		$value=$default;
	} else {
		$value = ltrim($value, '0'); // remove leading zeros
		$value = str_pad($value, $len, '-', STR_PAD_LEFT);
	}
	return $value;
}

// produce the output for the display
$tempString="4,".implode(',',$display)."#";

// if updateSpectator.php does something with the raw data or the formatted data, it will need to be modified to use either the $data or $display array
include 'updateSpectator.php';

$serial = new phpSerial;
$serial->deviceSet("/dev/ttyACM0");
#$serial->deviceSet("/dev/ttyAMA0");
#$serial->confBaudRate(115200);
$serial->confParity("none");
$serial->confCharacterLength(8);
$serial->confStopBits(1);

echo $tempString;
#echo($tempString."<br>");
$serial->deviceOpen();
$serial->sendMessage($tempString);

$serial->deviceClose();

#print_r($_POST);
?>

Many thanks for taking the time to reply.
I haven’t tried your code yet but to clarify what does what & what I’m trying to do…
(BTW although I do IT for a living I’m no programmer but I suspect you worked that out already! This is someone else’s code which I have modified)

There is a Raspberry Pi which runs as a web server & then, from a phone via a HTML interface, the Pi sends a string of data to an Arduino which then controls some shift registers which operated the LEDs on the board

The data string is sent from the html to the scoreboard.php file, it separates the string so it knows which digits relate to which variables, tidies it up (explained below) & then sends it to the Arduino via a .js file.

There are 3 variables in my problem, TOTAL, TARGET & RUNSREQ
Total is the current score, target is how many runs are needed to win & runsreq is how many are left to get. Target & runsreq are only required in the second Innings.

So, in Innings 1, the score might be 175. The target will be 0 & the runsreq will be 0

So,based on my understanding of the php file, the php substitutes the 000 of both target & runsreq & changes them in to —, & somewhere in the code the — doesn’t get displayed. So in the first Innings, target & runsreq are blank on the board.

At the end of the first Innings, the target is set by thye html page.

So, in the second Innings, the target would be 176, and initially the total would be 0 & the runsreq would be 176.
As the score increases, the runsreq reduces, so we might have Target 176, total 70, runsreq 106.

My problem is a simple one - once the total reaches the target, the runsreq is 0. But because of the code that stops 0 being displayed in the first Innings, it doesn’t display a 0, it is blank. I want it to display 0 but only in the second innings (i.e. when there’s a target)

So my logic is something like this… In the first innings, target is 0, but in the second innings it’s a number. So what I’m trying to do is something like
if target=0 & runsreq=0 then runsreq="—"
if target>0 & runsreq=0 then runsreq-"–0"
otherwise do what you do now with runsreq & display the runsreq

I hope that makes sense. I’ll try your code as soon as I get home. Thank you so much for trying to help.

You Sir are a genius.

I have no idea how your code works, but it does. Perfectly. (my old version (CS5) of Dreamweaver complains about some of it but based on the fact that it’s working it’s my old software that’s wrong!)

I’ll try to have a read through it & try to understand it but I am extremely grateful for your work. Thank you.

@phdr Hi phdr. Your scoreboard.php file works perfectly but as you have noted on the code (I didn’t notice until now) it breaks the ‘updateSpectator.php’ file.

I have no idea how to fix the spectator file, I’d be extremely grateful if you could tell me what I need to change.

I have 10 days before I need to take the board up to the ground for our first game (weather permitting) so really hoping I can get it amended & tested before then.

This is the updateSpectator.php file:

/<?php

    $scoreboardArray = array();

//Updated 25/9/2023 to add new variables, lastwkt, pship & lastman

    if (isset($total)) {
        $scoreboardArray['total'] =$total;
    }
    if (isset($wicketsOnes)) {
        $scoreboardArray['wickets']=$wicketsOnes;
    }
    if (isset($overs)) {
        $scoreboardArray['overs']=$overs;
    }
	if (isset($runsreq)) {
    	$scoreboardArray['runsreq']=$runsreq;
    }
    if (isset($batsmana)) {
        $scoreboardArray['bata']=$batsmana;
    }
    if (isset($batsmanb)) {
        $scoreboardArray['batb']=$batsmanb;
    }
    if (isset($target)) {
        $scoreboardArray['target']=$target;
    }
    if (isset($batsmananum)) {
        $scoreboardArray['batanumber']=$batsmananum;
    }
    if (isset($batsmanbnum)) {
        $scoreboardArray['batbnumber']=$batsmanbnum;
    }
    if (isset($dltarget)) {
        $scoreboardArray['dltarget']=$dltarget;
    }
	if (isset($lastwkt)) {
        $scoreboardArray['lastwkt']=$lastwkt;
    }
	if (isset($pship)) {
        $scoreboardArray['pship']=$pship;
    }
	if (isset($lastman)) {
        $scoreboardArray['lastman']=$lastman;
    }

    
    //update the json output file.
    $jsonData=json_encode($scoreboardArray);
    $jsonFile = fopen("score.json", "w") or die("Unable to open file!");
    fwrite($jsonFile, $jsonData);
    fclose($jsonFile);

?>

What exactly is this used for?

This is why trying to solve a small snippet of a problem at a time wastes a huge amount of time going back to include the rest of the problem. This is where a data-driven design comes in handy. The code for any particular operation only exists once, not 13 times, so that if you need to fix or change anything, you only have to make the change in one place.

This code is setting elements in an array variable with ALL the formatted values, not just those being sent to the display, some with different names than being used in the main code.

At this point, I would rename the $fields array indexes to match the index names being used in the json data. Then, repeat the // format the data ... logic, but for the $scoreboardArray variable, removing the if($arr['display_order']) conditional test (you want all the fields to be included), and use the $field variable when assigning the values to the $scoreboardArray variable.

All the values that were parsed from the original $_GET[‘data’] will be set. Therefore, there’s no need for the isset() statements. All the json output file write code can be handled with a single file_put_contents() statement - file_put_contents("score.json",json_encode($scoreboardArray));

@phdr thank you once again for your help here.
FYI this is a boot for profit project which is constantly evolving, which I got from https://buildyourownscoreboard.wordpress.com/
It is a cricket scoreboard built around a raspberry pi and an arduino and costs around £250 as opposed to thousands!
I know my code is a mess but I’d be really grateful for more help.
I will try to understand what you’ve written above.
Could I possibly send you the whole html folder as zip? I’m sure most of it will make far more sense to you than it does to me!
My email is cartoony (at) live dot co dot uk
Or does the last line just need to be added in place of the current line?

My question about what this is being used for, was specifically about what is the updateSpectator.php code being used for. Why is it writing this data to the “score.json” file? What happens with the data in that file?

What else is this code doing that would be affected by how it is operating internally?

This is the page about the spectator stuff https://buildyourownscoreboard (dot) wordpress (dot) com/spectator-tv-scoreboard-optional/
I think this is the relevant bit

Now we need to edit the scoreboard.php file to tell it to create the score.json file every time the scoreboard is updated. This is loaded by the spectator.htm file every 10 seconds. Open the scoreboard.php file using nano with the following commands:

cd /var/www/html/ sudo nano scoreboard.php

Scroll down the file to just above the lines that start $serial (your’s might look different to the screen shot, but just find the section with lines starting $serial and you will be fine). Add the following line just above that section.**

include ‘updateSpectator.php’;

This was written as an add on to provide a spectator scoreboard such as a TV in the bar. I believe the php file outputs the data to the json file and this is then loaded automatically by the spectator.html file every 10 seconds.

The fundamental process, as I understand it, is the html interface is used to change digits eg score, wickets, overs etc, & combines them i to one long string of numbers. scoreboard.php then does what it does & then sends the revised data string to the Arduino (sendtoarduino.js) which then controls the shift registers which turn LEDs on & off.

The addon for the spectator board saves the string to a json file & this can then be loaded by the spectator webpage viewed by anyone connected to the same network. I hope that makes some sense.

EDIT - the json file is just text like this:
{“total”:"-21",“wickets”:“1”,“overs”:"-4",“runsreq”:"—",“bata”:"–1",“batb”:"–8",“target”:"—",“batanumber”:"-3",“batbnumber”:"-2",“dltarget”:“000”,“lastwkt”:"-20",“pship”:"–1",“lastman”:"-12"}

I’m trying my best to give you as much info as I can & answer your questions but coding really isn’t my forte, I’m just trying to help my local cricket club & I’m exceptionally grateful for the time you’ve spent trying to help me.

The following does what I stated above and should (untested) work -

// change the $fields main index name to match the json data index -
$fields['total'] = 			['offset'=>0, 'len'=>3,'default'=>'--0','display_order'=>1];
$fields['wickets'] = 	['offset'=>3, 'len'=>1,'default'=>'0','display_order'=>2]; // this is output as is, with no formatting
$fields['overs'] = 			['offset'=>4, 'len'=>2,'default'=>'-0','display_order'=>3];
$fields['runsreq'] = 		['offset'=>6, 'len'=>3,'default'=>'---','display_order'=>4]; // --- blank, --0 zero
$fields['target'] = 		['offset'=>9, 'len'=>3,'default'=>'---','display_order'=>false];
$fields['bata'] = 		['offset'=>12,'len'=>3,'default'=>'--0','display_order'=>5];
$fields['batb'] = 		['offset'=>15,'len'=>3,'default'=>'--0','display_order'=>6];
$fields['batanumber'] = 	['offset'=>18,'len'=>2,'default'=>'-0','display_order'=>7]; // never expected to be a 0 value, default doesn't matter
$fields['batbnumber'] = 	['offset'=>20,'len'=>2,'default'=>'-0','display_order'=>8]; // never expected to be a 0 value, default doesn't matter
$fields['lastwkt'] = 		['offset'=>22,'len'=>3,'default'=>'---','display_order'=>false];
$fields['pship'] = 			['offset'=>25,'len'=>3,'default'=>'---','display_order'=>false];
$fields['dltarget'] = 		['offset'=>28,'len'=>3,'default'=>'--0','display_order'=>9]; // this is output as is, with no formatting
$fields['lastman'] = 		['offset'=>31,'len'=>3,'default'=>'---','display_order'=>false];

And -

<?php
// updateSpectator.php
// writes formatted data for all the fields to a json file
$scoreboardArray = [];
foreach($fields as $field=>$arr)
{
	// special handling for runsreq
	if($field == 'runsreq' && $data['target'] > 0)
	{
		// display a zero instead of the default --- blanks
		$scoreboardArray[$field] = format($data[$field], '--0', $arr['len']);
	}
	else
	{
		// normal processing
		$scoreboardArray[$field] = format($data[$field], $arr['default'], $arr['len']);
	}
}

//update the json output file.
file_put_contents("score.json",json_encode($scoreboardArray));

Thank you for your continued efforts.
I take it that the first code swaps in to the scoreboard.php in place of the similar code that’s already there.
May I ask where the second part goes? Do I just add it later in the same scoreboard.php file?

Please read what it says -

Thank you yet again.
Sorry for my ignorance, but do these 2 bits of code go in the scoreboard.php file or in the updateSpectator.php file?
And do they replace any of the existing code, or do I just add them in, & if the latter, does it matter where?
I know this is probably all very obvious to you, but I have never played with php before.

I’ve tried to slot your code in where I think it goes but it’s not updating the score.json file

I’m sure your code will be correct & that I’m doing something wrong!

These are my files:

scoreboard.php

<?php
//
// 20.04.2016
//
// Overs and wickets output swapped from orginal scoreboard.php to account for Bradford on Avon CC scoreboard design to show
// overs - wickets - target along the bottom
//
// 20.04.2016
// Form method changed from POST to GET  and data simplified to send one string -
// total[3] wickets[1] overs[2] batsa[3] batsb[3] target[3]
//
// e.g. 126807042084453 = Total 126, Wickets 8, Overs 07, Batsman A 042, Batsman B 084, Target 453.
//
// 18.06.2016
// Added back in line for original westbury on server scoreboard layout for second line
// see lines 50 and 51
//
// 28.12.2018
// Modified version for whitchurch CC which includes batsman numbers.
//
// Changed string order & contents Tot/Wkts/Overs/Tatget/RunsReq 123456123456

file_put_contents('save.txt', $_GET['data']); // Save the scores! They will be automatically loaded when the scoreboard is turned on. Make sure save.txt is writable by the web server user!

include "php_serial.class.php";

// define the expected fields and their dynamic characteristics
$fields = [];
// the 'default' element is what to use when the value is zero (logic for special handling of runsreq is in the later code)
// the 'display_order' element is both when to include the formatted value in the display output (any true value) and in what order it is in the data being sent to the display
// change the $fields main index name to match the json data index -
$fields['total'] = 			['offset'=>0, 'len'=>3,'default'=>'--0','display_order'=>1];
$fields['wickets'] = 	['offset'=>3, 'len'=>1,'default'=>'0','display_order'=>2]; // this is output as is, with no formatting
$fields['overs'] = 			['offset'=>4, 'len'=>2,'default'=>'-0','display_order'=>3];
$fields['runsreq'] = 		['offset'=>6, 'len'=>3,'default'=>'---','display_order'=>4]; // --- blank, --0 zero
$fields['target'] = 		['offset'=>9, 'len'=>3,'default'=>'---','display_order'=>false];
$fields['bata'] = 		['offset'=>12,'len'=>3,'default'=>'--0','display_order'=>5];
$fields['batb'] = 		['offset'=>15,'len'=>3,'default'=>'--0','display_order'=>6];
$fields['batanumber'] = 	['offset'=>18,'len'=>2,'default'=>'-0','display_order'=>7]; // never expected to be a 0 value, default doesn't matter
$fields['batbnumber'] = 	['offset'=>20,'len'=>2,'default'=>'-0','display_order'=>8]; // never expected to be a 0 value, default doesn't matter
$fields['lastwkt'] = 		['offset'=>22,'len'=>3,'default'=>'---','display_order'=>false];
$fields['pship'] = 			['offset'=>25,'len'=>3,'default'=>'---','display_order'=>false];
$fields['dltarget'] = 		['offset'=>28,'len'=>3,'default'=>'--0','display_order'=>9]; // this is output as is, with no formatting
$fields['lastman'] = 		['offset'=>31,'len'=>3,'default'=>'---','display_order'=>false];

// display order -
// $total, $wicketsOnes, $overs, $runsreq, $batsmana, $batsmanb, $batsmananum, $batsmanbnum, $dltarget
// target, lastwkt, pship, and lastman are not sent to the display

// parse the input data
$data = [];
foreach($fields as $field=>$arr)
{
	$data[$field] = substr($_GET['data'],$arr['offset'],$arr['len']);
}

// format the data
$display = [];
foreach($fields as $field=>$arr)
{
	// for a true display_order, include the formatted value in the output using the display_order as the array key
	if($arr['display_order'])
	{
		// special handling for runsreq
		if($field == 'runsreq' && $data['target'] > 0)
		{
			// display a zero instead of the default --- blanks
			$display[$arr['display_order']] = format($data[$field], '--0', $arr['len']);
		}
		else
		{
			// normal processing
			$display[$arr['display_order']] = format($data[$field], $arr['default'], $arr['len']);
		}
	}
}

// function to format the output
function format($value, $default, $len)
{
	if($value==0)
	{
		$value=$default;
	} else {
		$value = ltrim($value, '0'); // remove leading zeros
		$value = str_pad($value, $len, '-', STR_PAD_LEFT);
	}
	return $value;
}

// produce the output for the display
$tempString="4,".implode(',',$display)."#";

// if updateSpectator.php does something with the raw data or the formatted data, it will need to be modified to use either the $data or $display array
include 'updateSpectator.php';

$serial = new phpSerial;
$serial->deviceSet("/dev/ttyACM0");
#$serial->deviceSet("/dev/ttyAMA0");
#$serial->confBaudRate(115200);
$serial->confParity("none");
$serial->confCharacterLength(8);
$serial->confStopBits(1);

echo $tempString;
#echo($tempString."<br>");
$serial->deviceOpen();
$serial->sendMessage($tempString);

$serial->deviceClose();

#print_r($_POST);
?>```

updateSpectator.php

/<?php

    $scoreboardArray = array();

//Updated 25/9/2023 to add new variables, lastwkt, pship & lastman



    
    //update the json output file.
//    $jsonData=json_encode($scoreboardArray);
//    $jsonFile = fopen("score.json", "w") or die("Unable to open file!");
//    fwrite($jsonFile, $jsonData);
//    fclose($jsonFile);







<?php
// updateSpectator.php
// writes formatted data for all the fields to a json file
$scoreboardArray = [];
foreach($fields as $field=>$arr)
{
	// special handling for runsreq
	if($field == 'runsreq' && $data['target'] > 0)
	{
		// display a zero instead of the default --- blanks
		$scoreboardArray[$field] = format($data[$field], '--0', $arr['len']);
	}
	else
	{
		// normal processing
		$scoreboardArray[$field] = format($data[$field], $arr['default'], $arr['len']);
	}
}

//update the json output file.
file_put_contents("score.json",json_encode($scoreboardArray));

?>

@phdrMorning. Please could you look at my files above & see if I’m doing something wrong.
I massively appreciate you changing the php to a much better way of doing it but as you say it has consequences. I’m probably being massively naive her but couldn’t we just put a line like this in the original (badly written) php file?

if($target<>0 && $runsreq<1) { $runsreq="-0-"; }

The code I posted for updateSpectator.php is all the operational code for that file. By adding it into some of the existing code you now have two opening <?php tags, which should be producing a php syntax error, and none of the updateSpectator.php code gets executed. I’m not sure if the leading / before the first opening <?php tag is just a typo made when the code was posted or if it is actually present in the file, but there’s no technical reason for it to be there. If it is there, it is being literally output back to the html page that is requesting scoreboard.php,

To do that, you would need to put all the conditional logic needed for formatting $runsreq near the top, so that it is testing the raw data values, and it would need to use a temporary variable to hold the formatted value, that gets put back into $runsreq after the conditional logic is done figuring out the formatting.

@phdr I knew it would be something I’d done, thank you.
I have modified the updateSpectator.php file to just include your code & tested it on the Pi that I have in the office & the json file now updates.
I will test it on the board (which is at home) over the weekend (tied up with a MOT this afternoon)
I will let you know how it goes but it seems to be right now.
Thanks again for your help

@phdr tested on my board and works, thank you for all your help and sorry for my mistakes.
Now on to getting the spectator board to work when the scorer is using the Play Cricket Scorer app, which talks to the Pi through a php file the someone else wrote. But that’s a separate post which I’ll do tomorrow.

Sponsor our Newsletter | Privacy Policy | Terms of Service