tl;dr - scripts to gather WiFi and Temp data and show it all on a screen.
Read this blog post for more info: https://blog.plip.com/2019/10/31/happy-hacker-halloween/
tl;dr - scripts to gather WiFi and Temp data and show it all on a screen.
Read this blog post for more info: https://blog.plip.com/2019/10/31/happy-hacker-halloween/
<?php | |
function sortBydBm($a, $b) | |
{ | |
$a = $a['rssi']; | |
$b = $b['rssi']; | |
if ($a == $b) return 0; | |
return ($a > $b) ? -1 : 1; | |
} | |
function getAPsArrray(){ | |
$delimiter = "\t"; | |
$fp = fopen('/var/www/html/access.points.txt', 'r'); | |
$data = array(); | |
$seen = array(); | |
while ( !feof($fp) ) | |
{ | |
$line = fgets($fp, 2048); | |
$itemArray = str_getcsv($line, $delimiter); | |
if (isset($itemArray[1]) && !isset($seen[$itemArray[1]])){ | |
$dbm = $itemArray[0]; | |
$ssid = $itemArray[1]; | |
$dbm = str_replace('_' , ' ', $dbm); | |
$ssid = str_replace('_' , ' ', $ssid); | |
$seen[$ssid] = true; | |
$data[] = array('dbm' => $dbm, 'ssid' => $ssid); | |
} | |
if ($count > 10){ | |
break; | |
} | |
} | |
fclose($fp); | |
return $data; | |
} | |
if (isset($_GET['content'])){ | |
$today = date('Y-m-d', time()); | |
$time = date('g:i:s A', time()); | |
$date = date('D M j', time()); | |
if ($_GET['content'] == 'aps'){ | |
$count = 1; | |
$data = getAPsArrray(); | |
$output = ''; | |
foreach ($data as $item) { | |
$output .= '' | |
. $item['dbm'] . ' ' | |
. $item['ssid'] . ' ' | |
. "</br>"; | |
$count++; | |
if ($count > 10){ | |
break; | |
} | |
} | |
$count++; | |
print $output; | |
} elseif ($_GET['content'] == 'clients'){ | |
$str = file_get_contents('/var/www/html/wifi.clients.json'); | |
$strAry = explode('...', $str); | |
$str = trim($strAry[1]); | |
$json = json_decode($str, true); | |
$data = ''; | |
$count = 1; | |
usort($json, 'sortBydBm'); | |
foreach($json as $item){ | |
if(isset($item['mac'])){ | |
$data .= '' | |
. number_format((float)$item['rssi'], 1, '.', '') . ' dBm ' | |
// . $item['mac'] . ' ' | |
. ' ' . $item['company'] . '<br/>'; | |
$count++; | |
} | |
if ($count > 10){ | |
break; | |
} | |
} | |
print $data; | |
} elseif ($_GET['content'] == 'clientTitle'){ | |
$str = file_get_contents('/var/www/html/wifi.clients.json'); | |
$strAry = explode('...', $str); | |
$str = trim($strAry[1]); | |
$json = json_decode($str, true); | |
if (is_array($json)) { | |
$total = sizeof($json); | |
} else { | |
$total = ' :( '; | |
} | |
print "Phones By Proximity ($total total)<hr/>" ; | |
} elseif ($_GET['content'] == 'apsTitle'){ | |
$aps = getAPsArrray(); | |
$apCount = sizeof($aps); | |
print "APs By Proximity ($apCount total) <hr/>" ; | |
} elseif ($_GET['content'] == 'fullTitle'){ | |
$str = file_get_contents('/var/www/html/temp.json'); | |
$json = json_decode($str, true); | |
$jsontump = print_r($json,1); | |
$temp = $json['temperature_F']; | |
$humid = $json['humidity']; | |
$temp = number_format((float)$temp, 1, '.', '') . '° '; | |
$humid = number_format((float)$humid, 1, '.', '') . '% '; | |
print " $time $temp $humid <hr/> "; | |
} else { | |
//ahhhh! wtf!?! | |
print "No AJAX here"; | |
} | |
} | |
exit; |
*/2 * * * * /var/www/html/list.clients.sh | |
* * * * * ( /usr/bin/python3 /var/www/html/YANPIWS/bme280.py > /var/www/html/temp.json ) | |
* * * * * ( sleep 5; /usr/bin/python3 /var/www/html/YANPIWS/bme280.py > /var/www/html/temp.json ) | |
* * * * * ( sleep 10; /usr/bin/python3 /var/www/html/YANPIWS/bme280.py > /var/www/html/temp.json ) | |
* * * * * ( sleep 15; /usr/bin/python3 /var/www/html/YANPIWS/bme280.py > /var/www/html/temp.json ) | |
* * * * * ( sleep 20; /usr/bin/python3 /var/www/html/YANPIWS/bme280.py > /var/www/html/temp.json ) | |
* * * * * ( sleep 25; /usr/bin/python3 /var/www/html/YANPIWS/bme280.py > /var/www/html/temp.json ) | |
* * * * * ( sleep 30; /usr/bin/python3 /var/www/html/YANPIWS/bme280.py > /var/www/html/temp.json ) | |
* * * * * ( sleep 35; /usr/bin/python3 /var/www/html/YANPIWS/bme280.py > /var/www/html/temp.json ) | |
* * * * * ( sleep 40; /usr/bin/python3 /var/www/html/YANPIWS/bme280.py > /var/www/html/temp.json ) | |
* * * * * ( sleep 45; /usr/bin/python3 /var/www/html/YANPIWS/bme280.py > /var/www/html/temp.json ) | |
* * * * * ( sleep 50; /usr/bin/python3 /var/www/html/YANPIWS/bme280.py > /var/www/html/temp.json ) | |
* * * * * ( sleep 55; /usr/bin/python3 /var/www/html/YANPIWS/bme280.py > /var/www/html/temp.json ) | |
*/2 * * * * /var/www/html/list.access.points.sh |
/** | |
* do a GET and stuff results into an ID, optinally call call back | |
* thanks http://stackoverflow.com/a/8567149 - look ma - no jquery! | |
* | |
* @param URL string URL to fetch contnet from | |
* @param targetId string DOM ID where to innerHTML the result | |
* @param callback function to callback when done, optional | |
*/ | |
function loadXMLDoc(URL, targetId, callback) { | |
var xmlhttp = new XMLHttpRequest(); | |
xmlhttp.onreadystatechange = function() { | |
if (xmlhttp.readyState == XMLHttpRequest.DONE ) { | |
if (xmlhttp.status == 200) { | |
document.getElementById(targetId).innerHTML = xmlhttp.responseText; | |
if (typeof callback === "function") { | |
callback(); | |
} | |
} else { | |
document.getElementById(targetId).innerHTML = "AJAX Failed :("; | |
} | |
} | |
}; | |
xmlhttp.open("GET", URL, true); | |
xmlhttp.send(); | |
} |
<!DOCTYPE html> | |
<html lang="en" xmlns="http://www.w3.org/1999/html"> | |
<head> | |
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' http://127.0.0.1 http://localhost http://192.168.8.249"> | |
<meta charset="utf-8"> | |
</head> | |
<body> | |
<link rel="stylesheet" type="text/css" href="styles.css" /> | |
<div class='title' id='fullTitle'></div> | |
<div class="col"> | |
<div class="row"> | |
<div class='temp ' id='apsTitle'></div> | |
</div> | |
<div class="row"> | |
<div class='aps_clients' id='aps'></div> | |
</div> | |
</div> | |
<div class="col rigthtCol" id=""> | |
<div class="row"> | |
<div class='temp ' id='clientTitle'></div> | |
</div> | |
<div class="row"> | |
<div class='aps_clients' id='clients'></div> | |
</div> | |
</div> | |
<script src="./hacker.js"></script> | |
<script> | |
function refreshAll() { | |
loadXMLDoc('./ajax.php?content=fullTitle', 'fullTitle'); | |
loadXMLDoc('./ajax.php?content=aps', 'aps'); | |
loadXMLDoc('./ajax.php?content=clients', 'clients'); | |
loadXMLDoc('./ajax.php?content=clientTitle', 'clientTitle'); | |
loadXMLDoc('./ajax.php?content=apsTitle', 'apsTitle'); | |
} | |
refreshAll(); | |
setInterval ( refreshAll, 5000 ); | |
</script> | |
</body> | |
</html> |
#!/bin/sh | |
LIST="$(sudo /sbin/iw dev wlan0 scan | egrep "signal:|SSID:" | sed -e "s/\tsignal: //" -e "s/\tSSID: //" | awk '{ORS = (NR % 2 == 0)? "\n" : "\t"; print}' | sort|grep -v 'dBm\t$'|sed -e 's/_dBm//g'|tr ' ' '_')" | |
if [ ! -z "$LIST" ] | |
then | |
echo "$LIST" > /var/www/html/access.points.txt | |
fi | |
#!/bin/sh | |
LIST="$(/home/pi/.local/bin/howmanypeoplearearound -j -o /var/www/html/wifi.clients.json -a wlan1)" | |
if [ ! -z "$LIST" ] | |
then | |
echo '' > /var/www/html/wifi.clients.json | |
echo "$LIST" > /var/www/html/wifi.clients.json | |
fi | |
body { | |
margin: 10px; | |
padding: 10px; | |
background-color: black; | |
color: white; | |
font-size: 22pt; | |
font-family: sans-serif; | |
} | |
a { | |
color: white; | |
} | |
.error { | |
color: red; | |
font-size: 30pt; | |
} | |
.errorImg { | |
width:60px; | |
} | |
.homeLink { | |
font-size:29pt; | |
} | |
.YANPIWS a { | |
color: darkgreen; | |
text-decoration: none; | |
font-size:20pt; | |
} | |
a.yellow { | |
color: yellow; | |
} | |
.YANPIWS { | |
position: fixed; | |
z-index: 10000; | |
left: 42%; | |
} | |
.forecastday { | |
width:20%; | |
float:left; | |
text-align: center; | |
} | |
.temp { | |
padding-bottom:10px; | |
padding-top:20px; | |
font-size: 47pt; | |
float: left; | |
} | |
.title { | |
padding-bottom:10px; | |
padding-top:20px; | |
font-size: 65pt; | |
float: left; | |
} | |
.aps_clients { | |
padding-bottom:10px; | |
font-size: 35pt; | |
float: left; | |
} | |
.temp2 { | |
float:right; | |
} | |
.label { | |
text-transform: uppercase; | |
} | |
.degrees { | |
font-weight: bold; | |
} | |
.col { | |
float:left; | |
width: 100%; | |
} | |
.rigthtCol{ | |
padding-top:20px; | |
} | |
.row { | |
padding-bottom: 5px; | |
clear:both; | |
width: 100%; | |
} | |
.sun { | |
width:33px; | |
} | |
.moon { | |
width:25px; | |
padding-left:20px; | |
} | |
.date, .time, .label, .wind_now { | |
font-size:35pt; | |
} | |
.date, .time{ | |
float: left; | |
} | |
.wind_now { | |
float: right; | |
} | |
.date { | |
padding-left: 20px; | |
} | |
.lowt { | |
color: #476b6b; | |
} | |
.spreadtemp { | |
font-size:18pt; | |
} | |
.wind { | |
font-size:12pt; | |
} | |
.suntimes { | |
padding-top: 20px; | |
} | |
label { | |
clear: both; | |
float: left; | |
width: 25%; | |
text-align: left; | |
} | |
input { | |
width:70%; | |
} | |
@media only screen and (max-width : 480px) { | |
body { | |
font-size: 15pt; | |
} | |
.error { | |
color: red; | |
font-size: 20pt; | |
} | |
.errorImg { | |
width:40px; | |
} | |
.temp { | |
font-size: 25pt; | |
} | |
.rigthtCol{ | |
padding-top:10px; | |
} | |
.date, .time, .label, .wind_now { | |
font-size:15pt; | |
} | |
.spreadtemp { | |
font-size:11pt; | |
} | |
.YANPIWS a{ | |
font-size:15pt; | |
} | |
.suntimes { | |
padding-top: 10px; | |
} | |
canvas { | |
width:50px; | |
height:50px; | |
} | |
} |