Skip to content

Commit 047281e

Browse files
authored
Merge pull request #21 from femto-code/setup-page
All new setup page - supposed to simplify the installation and detection of errors in your configuration
2 parents 29173f5 + 00a1975 commit 047281e

File tree

9 files changed

+901
-34
lines changed

9 files changed

+901
-34
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ img/chartjs-logo.svg
44
img/intro.psd
55
raminfo.php
66
img/intro2.psd
7+
test.php

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Open for your feature [requests](https://github.com/femto-code/Rasberry-Pi-Dashb
99

1010
## [0.10] - 2021-03-18
1111
> Last release before a major 1.0.0
12+
1213
### Added
1314
- allow changing password from options modal 💯
1415

README.md

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
## Features
1111

1212
- Live surveillance of RPi hardware (CPU Temperature, frequency, loads etc.) with customizable warning thresholds
13-
- Detailed software/hardware information (web server, PHP, storage / partition workload, core voltage, plugged USB devices, kernel version, model specifications, OS, CPU)
13+
- Detailed software/hardware information (web server, PHP, storage / partition workload, core voltage, plugged USB devices, kernel version, model specifications, OS, CPU, network config)
1414
- Protected access with password login (default: root) ([configure password](https://github.com/femto-code/Rasberry-Pi-Dashboard#configure-password))
1515
- Power (shutdown/reboot) Raspberry Pi with schedule options ([setup instructions](https://github.com/femto-code/Rasberry-Pi-Dashboard#enabling-remote-shutdownreboot-optional))
1616
- Mobile WebApp integration
@@ -35,6 +35,29 @@
3535

3636
- Running Web Server (e.g. Lighttpd or Apache) with PHP installed (>=v5.6)
3737
- Installed Git (comes preinstalled on Raspberry Pi OS / formerly Raspbian as well as other linux distros)
38+
- Valid permissions within /var/www/html
39+
40+
#### Valid permissions
41+
42+
> This setup ensures that your user as well as the `www-data` user are allowed to write files to web directory (the minimum need of permissions)
43+
44+
The following configuration is the commonly recommended set-up for your web server folder:
45+
(Source: https://dev.to/phlash909/comment/ahf6)
46+
47+
1. First, make sure `www-data` group exists and add your current login:
48+
_(if you are using another distro than Raspbian/Raspberry Pi OS the username of web server can differ)_
49+
`sudo groupadd www-data`
50+
`sudo usermod -a -G www-data www-data`
51+
`sudo usermod -a -G www-data <yourlogin>` (replace `<yourlogin>` with your username)
52+
53+
2. Second, give the ownership of web folder to the `www-data` group and user. The following commands ensure that group members (including your own login) are able to write/edit files:
54+
`sudo chgrp -R www-data /var/www/html`
55+
`sudo chown -R www-data /var/www/html`
56+
`sudo chmod -R 775 /var/www/html`
57+
58+
3. Reboot your RPi (for permission changes to take effect)
59+
60+
> An erroneous permission typically results in the situation where the user responsible for web server (e.g. `www-data`) does not have rights to create/modify the local config file for saving your dashboard adjustments (your custom thresholds, password etc.). In this case, the dashboard won't work at all and throwing this error (see #22).
3861
3962
### Setup project
4063

@@ -43,14 +66,14 @@
4366
- **DONE!** Open web browser with URL: `http://IP_OF_YOUR_RPI/{your_subfolder_name}`
4467
> Note: replace {your_subfolder_name} with your choice accordingly. You can also rename the base folder at any time afterwards.
4568
46-
## Configuration
69+
## Configuration / Help
4770

48-
#### Core voltage output is not shown
49-
- If you want to see this information on your dashboard instance:<br>run `sudo usermod -aG video www-data` in a terminal
71+
#### Core voltage (or other hardware info) output is not shown (optional)
72+
- If you want to see advanced hardware information (core voltage, model information) on your dashboard instance:<br>run `sudo usermod -aG video www-data` in a terminal
5073
>If you do not use Raspbian (or any other RasPi distro) like Ubuntu, you do have to install `libraspberrypi-bin` by running `sudo apt install libraspberrypi-bin`.
5174
5275
- background: The `vcgencmd` command (specifically dedicated to RPi firmware) is a system command that requires certain hardware rights. Therefore one has to grant this particular right (to read hardware info) to e.g. `www-data` (under which web server is running). This is achived by adding this user to a system group called video, which the standard user pi is part of by default.
53-
- in case of problems: please comment on #12 (or new issue)
76+
- in case of problems: please comment on [#12](https://github.com/femto-code/Raspberry-Pi-Dashboard/issues/12) (or [new issue](https://github.com/femto-code/Raspberry-Pi-Dashboard/issues/new))
5477

5578
#### Enable shutdown / reboot (optional)
5679

backend/Config.php

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,51 @@
33
class Config{
44

55
protected $data;
6+
public $userconf;
7+
public $defconf;
68

7-
protected $default = null;
89

910
protected $file;
1011

1112
public function load($file, $defaultfile){
1213
if(!(file_exists($file))){
13-
$myfile = fopen($file, "w") or die("Unable to open file!");
14+
$myfile = fopen($file, "w") or die("Unable to open file! This error happens in the situation where the user responsible for web server (e.g. www-data) does not have rights to create/modify the local config file for saving your dashboard adjustments (your custom thresholds, password etc.). Please see installation instructions for setting correct permissions on your dashboard folder.");
1415
fwrite($myfile, "<?php\nreturn array();\n?>");
1516
fclose($myfile);
17+
chmod($file, 0664);
1618
}
1719
$this->file=$file;
1820
$userconf=require $file;
1921
$defaults=require $defaultfile;
20-
$this->data = array_merge($defaults, $userconf);
22+
$this->data = array_replace_recursive($defaults, $userconf); // not array_merge($defaults, $userconf)! Use recursive replace!
23+
$this->userconf = $userconf;
24+
$this->defconf = $defaults;
2125
//echo "<pre>",print_r($this->data),"</pre>";
2226
//$this->save($this->data);
2327
}
2428

25-
public function get($key, $default = null){
26-
$this->default = $default;
29+
public function get($key, $source=false){
2730

2831
$segments = explode(".", $key);
2932

30-
$data = $this->data;
33+
$data = ($source!==false) ? $this->{$source} : $this->data;
3134

3235
foreach ($segments as $segment){
3336
if (isset($data[$segment])){
3437
$data = $data[$segment];
3538
}else{
36-
$data = $this->default;
39+
$data = "";
3740
break;
3841
}
3942
}
4043
return $data;
4144
}
4245

43-
public function exists($key){
44-
return $this->get($key) !== $this->default;
46+
public function modified($key){
47+
return $this->get($key, "userconf");
48+
}
49+
public function defaults($key){
50+
return $this->get($key, "defconf");
4551
}
4652

4753
public function save($dat){

css/darkmode.css

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ body, div.bg-light {
33
background-color: #24292e!important;
44
}
55

6-
footer, .card, .modal-header, .modal-body, .modal-footer, .close, #preload {
6+
footer, .card, .modal-header, .modal-body, .modal-footer, .close, #preload, .multisteps-form__panel {
77
background-color: #2f363d!important;
88
color: #fff!important;
99
}
@@ -16,7 +16,7 @@ hr {
1616
color: #b1afaf!important;
1717
}
1818

19-
label{
19+
label, .headline {
2020
color: #fff;
2121
}
2222

@@ -28,4 +28,4 @@ label{
2828
}
2929
.modal-content{
3030
background-color: #4e4e4e;
31-
}
31+
}

defaults.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
'general' =>
1111
array (
1212
'pass' => '63a9f0ea7bb98050796b649e85481845',
13-
'initsetup' => '0',
13+
'initialsetup' => '0',
1414
),
1515
);
1616
?>

index.php

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,16 @@
88
$config = new Config;
99
$config->load("local.config", "defaults.php");
1010

11+
if(!isset($_SESSION["setup"])){
12+
if($config->get("general.initialsetup")=="0"){
13+
header("Location: setup.php");
14+
}
15+
}
16+
1117
$path=$_SERVER['SCRIPT_FILENAME'];
1218
$fol=substr($path, 0, -9);
1319

14-
$passVal = ($config->get("general.pass")!=='63a9f0ea7bb98050796b649e85481845') ? '***' : '';
20+
$passVal = ($config->get("general.pass")!=='63a9f0ea7bb98050796b649e85481845') ? "***notdefault***" : '';
1521
?>
1622
<!doctype html>
1723
<html lang="en">
@@ -104,8 +110,12 @@
104110
$p = $df / $ds * 100;
105111
//
106112

113+
$permissionerr=false;
107114
$spannung=substr(exec("vcgencmd measure_volts core"),5);
108-
if(strpos($spannung,"failed")!==false) $spannung=$spannung."<div class='alert alert-danger' role='alert'>Reading of core voltage failed. Please run<br><kbd>sudo usermod -aG video www-data</kbd><br>in a terminal to solve this problem.</div>";
115+
if( (strpos($spannung,"failed")!==false) || (strlen($spannung)<2) ){
116+
$spannung=$spannung."<div class='alert alert-danger' role='alert'>Reading of core voltage failed. Please run<br><kbd>sudo usermod -aG video www-data</kbd><br>in a terminal to solve this problem.</div>";
117+
$permissionerr=true;
118+
}
109119
}
110120
?>
111121

@@ -142,6 +152,15 @@
142152
<div class="card-body">
143153
<h5 id="sys1" class="card-title"><span id="overallstate"></span></h5>
144154
<p id="sys11" class="card-text"></p>
155+
<?php
156+
if(isset($_SESSION["setup"])){
157+
?>
158+
<div class="alert alert-info alert-dismissible fade show" role="alert"><i class="bi bi-info-circle"></i>&nbsp;Setup finished! RPi Dashboard is ready.<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>
159+
<?php
160+
unset($_SESSION["setup"]);
161+
}
162+
?>
163+
145164
<p id="sys2" class="card-text"></p>
146165
<hr>
147166
<p><i class="bi bi-clock-history"></i><!--<img src="img/time-icon.png">-->&nbsp;Uptime: <b><span id="uptime"></span></b><?php if($auth){ ?>&nbsp;(started <?=$uptstr;?>)<?php } ?></p>
@@ -255,7 +274,7 @@
255274
<div class="card-header">Model</div>
256275
<div class="card-body">
257276
<samp><?php echo exec("cat /sys/firmware/devicetree/base/model");?></samp>
258-
<samp><?php $ot=shell_exec("vcgencmd version");if(strpos($ot,"failed")!==false){echo "<div class='alert alert-danger' role='alert'>Execution of system command failed. Please run<br><kbd>sudo usermod -aG video www-data</kbd><br>in a terminal to solve this problem.</div>";}else{echo $ot;}?></samp>
277+
<?php $ot=shell_exec("vcgencmd version");if($permissionerr){echo "<div class='alert alert-danger' role='alert'>Execution of system command failed. Please run<br><kbd>sudo usermod -aG video www-data</kbd><br>in a terminal to solve this problem.</div>";}else{echo '<samp>'.$ot.'</samp>';}?>
259278
<p class="card-text"><small class="text-muted">Updated <span><?php echo date("H:i:s");?> (at page load)</span></small></p>
260279
</div>
261280
</div>
@@ -433,24 +452,24 @@
433452
<form id="settingsForm">
434453
<div class="form-row">
435454
<div class="col">
436-
<input type="number" id="warn_cpu_temp" class="form-control" placeholder="default: 60" aria-describedby="critCpuTempHelp" min="20" max="80" value="<?=$config->get("thresholds.warn_cpu_temp")?>">
455+
<input type="number" id="warn_cpu_temp" class="form-control" placeholder="default: 65" aria-describedby="critCpuTempHelp" min="20" max="80" value="<?=$config->modified("thresholds.warn_cpu_temp")?>">
437456
<small id="critCpuTempHelp" class="form-text text-muted">CPU Temperature (°C) - default: 65°C</small>
438457
</div>
439458
<div class="col">
440-
<input type="number" id="warn_ram_space" class="form-control" placeholder="default: 80" aria-describedby="critRamSizeHelp" min="0" max="100" value="<?=$config->get("thresholds.warn_ram_space")?>">
459+
<input type="number" id="warn_ram_space" class="form-control" placeholder="default: 80" aria-describedby="critRamSizeHelp" min="0" max="100" value="<?=$config->modified("thresholds.warn_ram_space")?>">
441460
<small id="critRamSizeHelp" class="form-text text-muted">RAM Load (%) - default: 80%</small>
442461
</div>
443462
</div>
444463
<div class="form-row">
445464
<div class="col-6">
446-
<input type="number" id="warn_loads_size" class="form-control" placeholder="default: 2" aria-describedby="critCpuLoadHelp" min="1" max="4" value="<?=$config->get("thresholds.warn_loads_size")?>">
465+
<input type="number" id="warn_loads_size" class="form-control" placeholder="default: 2" aria-describedby="critCpuLoadHelp" min="1" max="4" value="<?=$config->modified("thresholds.warn_loads_size")?>">
447466
<small id="critCpuLoadHelp" class="form-text text-muted">CPU workload (last min) - default: 2</small>
448467
</div>
449468
</div>
450469
<div class="form-row mb-2">
451470
<label for="upd_time_interval" class="col-sm-6 col-form-label">Refresh rate (sec)</label>
452471
<div class="col-sm-6">
453-
<input type="number" class="form-control" placeholder="default: 15" id="upd_time_interval" aria-describedby="dbRefreshHelp" min="5" max="600" value="<?=$config->get("thresholds.upd_time_interval")?>">
472+
<input type="number" class="form-control" placeholder="default: 15" id="upd_time_interval" aria-describedby="dbRefreshHelp" min="5" max="600" value="<?=$config->modified("thresholds.upd_time_interval")?>">
454473
</div>
455474
<small id="dbRefreshHelp" class="col form-text text-muted">Refresh interval of live data update section (recommended: 10 - 60 sec) - Pay attention: Do not set too low. - default: 15</small>
456475
</div>
@@ -571,7 +590,6 @@
571590
upd_time_interval = <?=$config->get("thresholds.upd_time_interval")?>;
572591
warn_loads_size = <?=$config->get("thresholds.warn_loads_size")?>;
573592
var settingsKeys=["warn_cpu_temp", "warn_ram_space", "warn_loads_size", "upd_time_interval", "pass"];
574-
var defaultSettings=[65, 80, 2, 15, "root"];
575593
console.log("Custom user options: warncputemp="+warn_cpu_temp+" | warn_ram_space="+warn_ram_space+" | upd_time_interval="+upd_time_interval+" | warn_loads_size="+warn_loads_size);
576594
</script>
577595

js/main.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,14 @@ function authorize() {
8686
console.log(data.responseText);
8787
if(data.responseText.indexOf("true") > -1){
8888
document.getElementById("currentState").innerHTML = "<div class='alert alert-success' role='alert'><i class='bi bi-check2-circle'></i>&nbsp;Authorization completed!</font>";
89-
$("#confbtn").html("<i class='bi bi-check2-circle'></i>&nbsp;Saved");
9089
var res=JSON.parse(data.responseText.split("true_")[1]);
9190
if( (res.act=="") || (res.date==null) ){
92-
if (confirm(("There was an error with shutdown. Please check that user www-data has necessary rights to perform this action.\nShow help?"))){
93-
location.href='https://github.com/femto-code/Raspberry-Pi-Dashboard#enabling-remote-shutdownreboot-optional';
91+
$("#confbtn").html("<i class='bi bi-x-circle'></i>&nbsp;Failed");
92+
if (confirm(("There was an error with scheduling the shutdown. This error usually goes back to incorrect permissions.\nPlease check that user www-data has necessary rights to perform this action.\nShow help?"))){
93+
location.href='https://github.com/femto-code/Raspberry-Pi-Dashboard#enable-shutdown--reboot-optional';
9494
}
9595
}else{
96+
$("#confbtn").html("<i class='bi bi-check2-circle'></i>&nbsp;Saved");
9697
outputShutdown(res.date,res.act);
9798
}
9899
setTimeout(function(){
@@ -109,7 +110,7 @@ function authorize() {
109110
$("#inputPassword2").addClass("is-invalid");
110111
$("#confbtn").html("Confirm identity");
111112
}else if(data.responseText.indexOf("false") > -1){
112-
alert('There was an error with shutdown: Parameter error. Please report an issue.');
113+
alert('There was an error with shutdown: Parameter error. Please report this issue on Github!');
113114
}
114115
}, function () {
115116
alert("Connection error");
@@ -157,7 +158,7 @@ function cancelShutdown(force) {
157158
}else{
158159
checkShutdown(function(){
159160
if(shutdownCurrent){
160-
alert('There was an error with shutdown cancel. Please report an issue.');
161+
alert('There was an error with shutdown cancel. Please report this issue on Github!');
161162
}else{
162163
mdtoast('<i class="bi bi-check2-circle"></i>&nbsp;Power event was cancelled!', { type: 'success'});
163164
}
@@ -570,9 +571,9 @@ document.querySelector('#applyBtn').onclick = function (e) {
570571
for (var i = 0; i < settingsKeys.length; i++) {
571572
val=document.getElementById(settingsKeys[i]).value;
572573
if(val==""){
573-
val=defaultSettings[i];
574-
sFormData.append(settingsKeys[i], val);
575-
}else if(val=="***"){
574+
//val=defaultSettings[i];
575+
//sFormData.append(settingsKeys[i], val);
576+
}else if(val=="***notdefault***"){
576577
// NOTE: password is altered (not default) -> leave as is
577578
}else{
578579
if(settingsKeys[i]=="pass") {
@@ -592,6 +593,9 @@ document.querySelector('#applyBtn').onclick = function (e) {
592593
if(data.responseText=="1"){
593594
mdtoast('<i class="bi bi-check2-circle"></i>&nbsp;Settings were updated!', { type: 'success'});
594595
$("#sformFeedback").html('<div class="mt-2 alert alert-success alert-dismissible fade show" role="alert"><i class="bi bi-check2-circle"></i>&nbsp;Saved successfully! <a href="javascript:location.reload()" class="alert-link">Reload</a> the page for changes to take effect.<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>');
596+
}else if(data.responseText=="nothing changed"){
597+
mdtoast('<i class="bi bi-info-circle"></i>&nbsp;Nothing was changed!', { type: 'info'});
598+
$("#sformFeedback").html('<div class="mt-2 alert alert-info alert-dismissible fade show" role="alert"><i class="bi bi-info-circle"></i>&nbsp;All set! You did not change anything.<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>');
595599
}else{
596600
mdtoast('<i class="bi bi-x-circle"></i>&nbsp;There was an error! ('+data.responseText+')', { type: 'error'});
597601
$("#sformFeedback").html('<div class="mt-2 alert alert-danger" role="alert"><i class="bi bi-x-circle"></i>&nbsp;Failed! <a class="alert-link" href="https://github.com/femto-code/Raspberry-Pi-Dashboard/issues/new" target="blank">Create an issue</a> mentioning error message: <kbd>'+data.responseText+'</kbd>.</div>');

0 commit comments

Comments
 (0)