Category Archives: Computer

Need a bigger screenshot of a map

Some websites use ajax and dynamic viewing of larger images.
For a colleage i grabbed a screenshot using below to get him a full sized campsite map.

Firefox example: Open the page, google maps for example.
Press CTRL+SHIFT+M or Responsive Design View from the Developers Tools.

Change the size you want your virtual browser ( and doing so, your screenshot size here 2800 ) And click on the ‘take screenshot from viewport’ icon on the right.

HS 500 APC Ups to domoticz

A friend of mine wanted to monitor his UPS using domoticz.
This UPS only had a simple web interface with information.

So we needed to scrape this information and push this into domoticz.

First create a dummy device in domoticz and note its IDX.

Then we can scrape needed information using below script.

#!/bin/bash
#set -x
# Domoticz server
SERVER="127.0.0.1:8080"

# APC Back-UPS HS 500 status URL
UPS="http://IP-OF-UPS/status.cgi"

# The number of the IDX in the list of peripherals
IDX="362"

# Path for temporary file (RAM drive)
TMPFILE="/tmp/apc-hs500-status.txt"

# Get APC Back-UPS HS 500 status and write to temporary file
wget $UPS -O $TMPFILE 2>/dev/null
if [ $? = 0 ]
then
PWR=$(cat $TMPFILE| tr -dc '[[:print:]]' |awk -F"Watts" '{print $1}' |rev |cut -f1 -d\> |rev |cut -f1 -d\&)
fi

if [ $PWR ]
then
echo "Load on Battery in Watts: $PWR"
# Send data to Domoticz
curl -s -i -H "Accept: application/json" "http://$SERVER/json.htm?type=command&param=udevice&idx=$IDX&nvalue=0&svalue=$PWR"
PWR=""
fi
rm $TMPFILE

Nikon Lenses

Created a graph for my Nikon lenses. It shows me what lens i can use at what Aperture / Range.

( https://media.henriaanstoot.nl/websites/lenses/ )

It uses canvas to draw lines and text, but thats only interesting for static stuff. ( https://www.w3schools.com/graphics/canvas_drawing.asp )
My example uses a php script to load information from a csv file. And loops though those entries and draw lens info.

Piece of canvas script to draw 17-70mm lens info.

ctx.fillStyle = 'rgba(0, 200, 100, 0.9)';
ctx.lineWidth=2;
ctx.beginPath();
ctx.moveTo(189.98560128675,163.25813588993);
ctx.lineTo(359.81942904592,202.49237972319);
ctx.lineTo(359.81942904592,250);
ctx.lineTo(189.98560128675,250);
ctx.strokeStyle="rgba(0,0,0,0.9)";
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.fillStyle = 'rgba(0,0,0,0.9';
ctx.save();
ctx.translate( 189.98560128675,153.25813588993);
ctx.rotate(-Math.PI / 4);
ctx.fillText("17-70mm", 0,0);
ctx.restore();

CSV lenses info

80;200;2.8;2.8;FX;80-200mm f/2.8
10;24;3.5;4.5;DX;10-24mm wide
28;100;3.5;5.6;;28-100mm leen
17;70;2.8;4;DX;17-70mm
35;35;1.8;1.8;DX;35mm f/1.8
60;60;2.8;2.8;FX;60mm f/2.8
28;300;3.5;5.6;FX;28-300mm

PHP Code to generate


<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>Lens</title>
  <style type='text/css'>
    body{ background-color: ivory; }
#canvas{border:1px solid white;}

  </style>
<script type='text/javascript'>//<![CDATA[
window.onload=function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
<?PHP
$log=yes;

print "ctx.strokeStyle = 'rgba(200, 0, 0, 0.1)';";
print "ctx.fillStyle = 'rgba(0, 0, 0, 0.9)';";
$apes=array(1.4,2,2.8,4,5.6);
$count=0;
foreach ($apes as &$value) {
$height=log($value)*110;
$count=$count+1;
$height=$height+50;
print "ctx.font = '20px Arial';";
print "ctx.fillText(\"$value\", 20, $height);";
print "ctx.lineWidth=2;";
print "ctx.moveTo(50, $height);";
print "ctx.lineTo(900, $height);";
}
print "ctx.stroke();";
$count=0;
$apes=array(8,16,32,64,128);
foreach ($apes as &$value) {
$width=log($value)*120;
$count=$count+1;
$width=$width-150;
print "ctx.fillText(\"$value\", $width, 270);";
}
print "ctx.font = '15px Arial';";
?>
ctx.beginPath();
ctx.moveTo(50,250);
ctx.lineTo(900,250);
ctx.moveTo(50,50);
ctx.lineTo(50,250);
ctx.lineWidth=1;
ctx.strokeStyle="rgba(0, 0, 0, 0.9)";
ctx.stroke();
<?PHP

$configfile="lenses.csv";

$config=get2DArrayFromCsv($configfile,";");

        foreach ($config as $value) {
$fp1=$value[0];
$fp2=$value[1];
$ap1=$value[2];
$ap2=$value[3];
$x1=(log($fp1)*120)-150;
$x2=(log($fp2)*120)-150;
$y1=(log($ap1)*110)+50;
$y2=(log($ap2)*110)+50;
if ( $x1 == $x2 ) { $color="200,0,0"; } else { $color="0,0,0"; }
if ( $x1 == $x2 ) { $x2 = $x2 + 6; }
$green=200;
$xx1=(log($fp1*2)*120)-150;
$xxx1=(log($fp1*2)*120)-160;
$xx2=(log($fp2*2)*120)-150;
$yy1=$y1-10;
$yyy1=$y1+10;

if ( $xx1 == $xx2 ) { $xx2 = $xx2 + 6; }
if ( $value[4] == "FX" ) { $col="200"; $trans=0.2; } else { $col="0";$trans=0.9;  }
?>

ctx.fillStyle = 'rgba(<?PHP print $col; ?>, <?PHP print $green; ?>, 100, <?PHP print $trans; ?>)';
ctx.lineWidth=2;
ctx.beginPath();
ctx.moveTo(<?PHP print "$x1"; ?>,<?PHP print "$y1"; ?>);
ctx.lineTo(<?PHP print "$x2"; ?>,<?PHP print "$y2"; ?>);
ctx.lineTo(<?PHP print "$x2"; ?>,<?PHP print "250"; ?>);
ctx.lineTo(<?PHP print "$x1"; ?>,<?PHP print "250"; ?>);
ctx.strokeStyle="rgba(<?PHP print "$color"; ?>,<?PHP print $trans;  ?>)";
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.fillStyle = 'rgba(<?PHP print "$color"; ?>,<?PHP print $trans;  ?>';
ctx.save();
ctx.translate( <?PHP print "$x1"; ?>,<?PHP print "$yy1"; ?>);
ctx.rotate(-Math.PI / 4);
ctx.fillText("<?PHP print "$value[5]"; ?>", 0,0);
ctx.restore();
<?PHP

if ( $value[4] == "FX" ) {
?>
ctx.fillStyle = 'rgba(0, <?PHP print "200"; ?>, 0, 0.9)';
ctx.beginPath();
ctx.moveTo(<?PHP print "$xx1"; ?>,<?PHP print "$y1"; ?>);
ctx.lineTo(<?PHP print "$xx2"; ?>,<?PHP print "$y2"; ?>);
ctx.lineTo(<?PHP print "$xx2"; ?>,<?PHP print "250"; ?>);
ctx.lineTo(<?PHP print "$xx1"; ?>,<?PHP print "250"; ?>);
ctx.strokeStyle="rgba(<?PHP print "$color"; ?>,0.9";
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.fillStyle = 'rgba(0, 0, 0, 0.9)';
ctx.save();
ctx.translate( <?PHP print "$xx1"; ?>,<?PHP print "$yy1"; ?>);
ctx.rotate(-Math.PI / 4);
ctx.fillText("<?PHP print "$value[5]"; ?> crop", <?PHP print "0"; ?>, <?PHP print "0"; ?>);
ctx.restore();
<?PHP
}
}
?>

ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
ctx.font = 'bold 10pt Calibri';

}//]]>

</script>

</head>
<body><small>
  <canvas id="canvas" width=700 height=300></canvas>
<P>
<?PHP
$configfile="lenses.csv";

   function get2DArrayFromCsv($file,$delimiter) {
       if (($handle = fopen($file, "r")) !== FALSE) {
           $i = 0;
           while (($lineArray = fgetcsv($handle, 4000, $delimiter)) !== FALSE) {
               for ($j=0; $j<count($lineArray); $j++) {
                   $data2DArray[$i][$j] = $lineArray[$j];
               }
               $i++;
           }
           fclose($handle);
       }
       return $data2DArray;
   }

$config=get2DArrayFromCsv($configfile,";");

        foreach ($config as $value) {
            print "<B>Lens = $value[5] </B><BR>";
            print "Focal min = $value[0] <BR>";
            print "Focal max = $value[1] <BR>";
            print "Arp min = $value[2] <BR>";
            print "Arp max = $value[3] <BR>";
            print "Crop (FX/DX) = $value[4] <P>";
        }


?>

</body>

</html>

Terminals and SSH

I’m using a lot of terminals, spawning a new terminal and running ssh, without knowing if i still have a session running.

Lets see:

This was done using something like:

#!/bin/bash
count=$(ps -ef | grep xterm | grep -v grep | wc -l)
timestamp=$(date +%s)
echo "$timestamp,$count" >> /var/local/terminallog 

Later i made a script to push this information in Grafana

Now for the SSH part.
I’m jumping from machine to machine using ssh, sometime i loop back to a server i was already connected to .. this helps me to keep track

in ssh_config add
SendEnv SSHTRAIL

in sshd_config add
AcceptEnv SSHTRAIL

in /etc/profile
export SSHTRAIL=$SSHTRAIL:$HOSTNAME

restart sshd
when you do this on all your machines you can get a trail of ssh using:
echo $SSHTRAIL
workstation:server1:server66:server1

I could change the prompt when a loop is detected
echo $SSHTRAIL | sed -e 's/:/\n/g' | sort | uniq -c | grep -v 1 | ... | echo "WARNING: loop in ssh"

Kanban effectiveness graph generator

While attending a Kanban workshop, i needed to keep myself awake.
I’d hardly slept that night.

So i wrote something useful using PHP JPgraph and Sqlite, while attending the workshop.
It shows the effectiveness of the team using kanban.

index.php

<html>
<head>
</head>
<body>
<?PHP
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
include ("insert.php");
}
include ("getlast.php");
?>
<img src="graph.php"><P>
<form action="" method="POST">
Tickets from board: <input size="4" name="klaar" value="<?PHP print $klaar; ?>"/> <input type="checkbox" name="useklaar" value="useklaar" checked> Use fromboard <P>
    <table>
        <tr>
            <td>inlane:</td><td><input size="4" name="inlane" value="<?PHP print $inlanelast; ?>"/></td>
            <td>analyse:</td><td><input size="4" name="analyze" value="<?PHP print $analyzelast; ?>" /></td>
            <td>implement:</td><td><input size="4" name="implement" value="<?PHP print $implementlast; ?>" /></td>
            <td>documentation:</td><td><input size="4" name="documentation" value="<?PHP print $documentationlast; ?>"/></td>
            <td>peer:</td><td><input size="4" name="peer" value="<?PHP print $peerlast; ?>"/></td>
            <td>test:</td><td><input size="4" name="test" value="<?PHP print $testlast; ?>"/></td>
            <td>done:</td><td><input size="4"  name="done" value="<?PHP print $donelast; ?>"/></td>
        </tr>
    </table>
            <input type="submit" value="Submit"/>
</form>

</body>
</html>

graph.php

<?php
include ("jpgraph/jpgraph.php");
include ("jpgraph/jpgraph_line.php");
$db = new SQLite3('mysqlitedb.db');
$index=0;
$results = $db->query('SELECT inlane FROM ENTRIES');
while ($row = $results->fetchArray()) {
$inlane[$index] = $row[0];
     $index++;
}
$index=0;
$results = $db->query('SELECT analyze FROM ENTRIES');
while ($row = $results->fetchArray()) {
$analyze[$index] = $row[0];
     $index++;
}
$index=0;
$results = $db->query('SELECT implement FROM ENTRIES');
while ($row = $results->fetchArray()) {
$implement[$index] = $row[0];
     $index++;
}
$index=0;
$results = $db->query('SELECT documentation FROM ENTRIES');
while ($row = $results->fetchArray()) {
$documentation[$index] = $row[0];
     $index++;
}
$index=0;
$results = $db->query('SELECT peer FROM ENTRIES');
while ($row = $results->fetchArray()) {
$peer[$index] = $row[0];
     $index++;
}
$index=0;
$results = $db->query('SELECT test FROM ENTRIES');
while ($row = $results->fetchArray()) {
$test[$index] = $row[0];
     $index++;
}
$index=0;
$results = $db->query('SELECT done FROM ENTRIES');
while ($row = $results->fetchArray()) {
$done[$index] = $row[0];
     $index++;
}
//$datay = array(1,2,4);
$datay1 = array(2,4,4,6,7,4);
$datay2 = array(2,3,4);
$graph = new Graph(600,600,"auto");
$graph->img->SetMargin(40,40,40,40);	
$graph->img->SetAntiAliasing();
$graph->SetScale("textlin");
$graph->SetShadow();
$graph->title->Set("Kanban grapher - A pruts by FASH");
$graph->title->SetFont(FF_FONT1,FS_BOLD);

// Add 10% grace to top and bottom of plot
$graph->yscale->SetGrace(10,10);

//ID|inlane|implement|documentation|peer|test|done

$p1 = new LinePlot($inlane);
$p1->mark->SetType(MARK_FILLEDCIRCLE);
$p1->mark->SetFillColor("red");
$p1->mark->SetWidth(4);
$p1->SetColor("red");
$p1->SetCenter();
$graph->Add($p1);

$p2 = new LinePlot($analyze);
$p2->mark->SetType(MARK_FILLEDCIRCLE);
$p2->mark->SetFillColor("orange");
$p2->mark->SetWidth(4);
$p2->SetColor("orange");
$p2->SetCenter();
$graph->Add($p2);

$p3 = new LinePlot($implement);
$p3->mark->SetType(MARK_FILLEDCIRCLE);
$p3->mark->SetFillColor("yellow");
$p3->mark->SetWidth(4);
$p3->SetColor("yellow");
$p3->SetCenter();
$graph->Add($p3);

$p4 = new LinePlot($documentation);
$p4->mark->SetType(MARK_FILLEDCIRCLE);
$p4->mark->SetFillColor("green");
$p4->mark->SetWidth(4);
$p4->SetColor("green");
$p4->SetCenter();
$graph->Add($p4);

$p5 = new LinePlot($peer);
$p5->mark->SetType(MARK_FILLEDCIRCLE);
$p5->mark->SetFillColor("blue");
$p5->mark->SetWidth(4);
$p5->SetColor("blue");
$p5->SetCenter();
$graph->Add($p5);

$p6 = new LinePlot($test);
$p6->mark->SetType(MARK_FILLEDCIRCLE);
$p6->mark->SetFillColor("purple");
$p6->mark->SetWidth(4);
$p6->SetColor("purple");
$p6->SetCenter();
$graph->Add($p6);

$p7 = new LinePlot($done);
$p7->mark->SetType(MARK_FILLEDCIRCLE);
$p7->mark->SetFillColor("black");
$p7->mark->SetWidth(4);
$p7->SetColor("black");
$p7->SetCenter();
$graph->Add($p7);

$graph->legend->SetLineSpacing(5);

$p1->SetLegend ("inlane"); 
$p2->SetLegend ("analyse"); 
$p3->SetLegend ("implementation"); 
$p4->SetLegend ("documentation"); 
$p5->SetLegend ("peer"); 
$p6->SetLegend ("test"); 
$p7->SetLegend ("done"); 
$graph ->legend->Pos( 0.09,0.09,"left" ,"top");

$graph->Stroke();
?>

insert.php

<?php
$db = new SQLite3('mysqlitedb.db');
//ID|inlane|implement|documentation|peer|test|done
$klaar=$_POST["klaar"];
$inlane=$_POST["inlane"];
$analyze=$_POST["analyze"];
$implement=$_POST["implement"];
$documentation=$_POST["documentation"];
$peer=$_POST["peer"];
$test=$_POST["test"];
$done=$_POST["done"];

$db->exec("DELETE FROM BOARD");
$db->exec("INSERT INTO BOARD  VALUES ($klaar,$inlane,$analyze,$implement,$documentation,$peer,$test,$done)");

$done=$_POST["done"]+$klaar;
$test=$_POST["test"]+$done;
$peer=$_POST["peer"]+$test;
$documentation=$_POST["documentation"]+$peer;
$implement=$_POST["implement"]+$documentation;
$analyze=$_POST["analyze"]+$implement;
$inlane=$_POST["inlane"]+$analyze;

$db->exec("INSERT INTO ENTRIES  VALUES (NULL,$inlane,$analyze,$implement,$documentation,$peer,$test,$done)");
?>
getlast.php
<?php
$db = new SQLite3('mysqlitedb.db');

$results = $db->query('SELECT inlane FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$inlanelast = $row[0];

$results = $db->query('SELECT implement FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$implementlast = $row[0];

$results = $db->query('SELECT documentation FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$documentationlast = $row[0];

$results = $db->query('SELECT peer FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$peerlast = $row[0];

$results = $db->query('SELECT test FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$testlast = $row[0];

$results = $db->query('SELECT done FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$donelast = $row[0];

$results = $db->query('SELECT vanbord FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$klaar = $row[0];

$results = $db->query('SELECT analyze FROM BOARD LIMIT 1;');
$row = $results->fetchArray();
$analyzelast = $row[0];
?>

Brother printer hack’s

Cartridge not recognised?
Just replace chip! With a original one

UPDATE: Maybe there is a counter in there, had a cartridge which wouldn’t work anymore ?!?

Cartridge saying .. i’m empty, but still visible ink?

Just tape up above part!

Note: there are many solutions found on the web, like opening the lid and pressing two buttons to get into a reset menu. Or Cold start your printer without cartrides 5 times to reset stored ink levels.

These are only the things I found

Jumanji Screen

Vincent showed me a very beautiful “pruts” he made.
It was the Boardgame from Jumanji.
He asked someone from work to write software for the center display.

I really liked the idea, so i made my own version.

I’ve cleaned-up the code and my version is here.
https://media.henriaanstoot.nl/websites/jumanji/index.html

The second page should play a mp3 sound sample, but there is a autoplay issue with some browsers. (I have fixed this on other projects, i will fix this later.

Portable Squeeze Server

Update : https://www.henriaanstoot.nl/2022/05/26/portable-logitech-media-server-again/


Below is a picture of my mobile LMS server i used in my car.
I only had radio and a CD player, i’m not a radio man .. folk, pipes and audiobooks


At the time i was working for Dutch Railways, imagine me walking with this blinky leds thingy, though the railway station …

It consisted of a dual port usb charger, a usb hub to power the drive, the rpi wasn’t strong enough. Thumbdrives where small in capacity, so i had to use a spinning disk harddrive.
It was only a raspberry 1, in a case i had designed and lasercutted at Fablab Utrecht.

Now you can get rid of the Usb hub and harddrive using a small but with large capacity sdcards.

I could charge the thing in my car, and when i got home, it would connect to my home wifi network, sync-ed my MP3’s and turn off.