Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
07ebe4f
Initial Commit for Mover Status rc3+
SimonFair Mar 8, 2022
70a3707
Code clean up
SimonFair Mar 8, 2022
0b933a9
Add additional lines and progress barss
SimonFair Mar 9, 2022
942ce08
Update ArrayOperation.page
SimonFair Apr 2, 2022
2ef7202
Revert "Update ArrayOperation.page"
SimonFair Apr 2, 2022
5f68b82
Merge branch 'master' into Mover-Progress-NCHAN-rc3+
SimonFair Apr 2, 2022
41d9842
Merge branch 'master' into Mover-Progress-NCHAN-rc3+
SimonFair May 9, 2022
cd6293f
Merge branch 'master' into Mover-Progress-NCHAN-rc3+
SimonFair May 9, 2022
33080ba
Merge branch 'limetech:master' into Mover-Progress-NCHAN-rc3+
SimonFair May 9, 2022
6d638d3
Merge branch 'Mover-Progress-NCHAN-rc3+' of https://github.com/SimonF…
SimonFair May 9, 2022
b9461fc
Merge remote-tracking branch 'upstream/master' into Mover-Progress-NC…
SimonFair Feb 11, 2023
8a6de1a
Merge remote-tracking branch 'upstream/master' into Mover-Progress-NC…
SimonFair Nov 26, 2023
298a997
Add mover file.
SimonFair Nov 26, 2023
ce37cb7
Update mover
SimonFair Nov 26, 2023
d8dd7ed
Update mover
SimonFair Nov 26, 2023
6e69743
Change processing.
SimonFair Nov 27, 2023
2dc0d78
Update mover files
SimonFair Nov 28, 2023
534b0a2
Add bash version
SimonFair Nov 28, 2023
ac6aa90
Make script executable
SimonFair Nov 28, 2023
a91f1d5
Add new options to mover.
SimonFair Nov 28, 2023
d0b67d4
Add help text
SimonFair Nov 28, 2023
ffa1b10
Merge remote-tracking branch 'upstream/master' into Mover-Progress-NC…
SimonFair Dec 2, 2023
8713e5b
Update parity_list
SimonFair Dec 2, 2023
50f5930
Update parity_list
SimonFair Dec 2, 2023
7d08940
Update parity_list
SimonFair Dec 2, 2023
bbd6fa2
Merge remote-tracking branch 'upstream/master' into Mover-Progress-NC…
SimonFair Jun 18, 2026
68aece2
Update mover to current version before progress.
SimonFair Jun 22, 2026
60ac24a
Updates following CR review.
SimonFair Jun 22, 2026
defeec9
Add additional gates.
SimonFair Jun 22, 2026
3080303
Update sleep
SimonFair Jun 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions emhttp/languages/en_US/helptext.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2158,6 +2158,10 @@ For the other schedules choose here the time of the day the mover should start.
Write mover messages to the syslog file.
:end

:mover_progress_help:
Enable progress display and allow a user override.
:end

:notifications_display_help:
In *Detailed* view all notifications will be displayed on screen as soon as they arrive.<br>
Notifications can be acknowledged individually or all at once.
Expand Down
56 changes: 56 additions & 0 deletions emhttp/plugins/dynamix/ArrayOperation.page
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ $('.tooltip_diskio').tooltipster({delay:100,trigger:'custom',triggerOpen:{mousee

<?if (_var($var,'fsState') == 'Started'):?>
var mymonitor = new NchanSubscriber('/sub/mymonitor',{subscriber:'websocket', reconnectTimeout:5000});
var maxmoverlines = 5 ;
mymonitor.on('message', function(state) {
switch (state) {
case '0': // normal operation
Expand All @@ -426,6 +427,9 @@ mymonitor.on('message', function(state) {
<?if (_var($var,'shareUser') == 'e' && $pool_devices):?>
$('#mover-button').prop('disabled',false);
$('#mover-text').html("<b>_(Move)_</b> _(will immediately invoke the Mover)_.&nbsp;<a href=\"/Main/Settings/Scheduler\"<?if($tabbed):?> onclick=\"$.cookie('one','tab2')\"<?endif;?>>(_(Schedule)_)</a>");
for (let i = 0; i < maxmoverlines; i++) {
$('#moverrow'+i ).hide();
}
<?endif;?>
<?if (!$pool_devices):?>
$('#mover-button').prop('disabled',false);
Expand All @@ -446,6 +450,9 @@ mymonitor.on('message', function(state) {
<?if (!$pool_devices):?>
$('#mover-button').prop('disabled',true);
$('#mover-text').html("_(Disabled)_ -- _(Parity operation is running)_");
for (let i = 0; i < maxmoverlines; i++) {
$('#moverrow'+i ).hide();
}
<?endif;?>
break;
case '2': // mover running
Expand All @@ -454,6 +461,8 @@ mymonitor.on('message', function(state) {
<?if (_var($var,'shareUser') == 'e' && $pool_devices):?>
$('#mover-button').prop('disabled',true);
$('#mover-text').html("_(Disabled)_ - _(Mover is running)_.");


<?endif;?>
<?if (!$pool_devices):?>
$('#mover-button').prop('disabled',true);
Expand All @@ -470,6 +479,9 @@ mymonitor.on('message', function(state) {
<?if (!$pool_devices):?>
$('#mover-button').prop('disabled',true);
$('#mover-text').html("_(Disabled)_ -- _(BTRFS operation is running)_");
for (let i = 0; i < maxmoverlines; i++) {
$('#moverrow'+i ).hide();
}
<?endif;?>
break;
}
Expand All @@ -482,6 +494,45 @@ arraymonitor.on('message', function(state) {
if (state == 1 && !timers.arraymonitor) timers.arraymonitor = setTimeout(refresh,1250);
});

var moverStatus = new NchanSubscriber('/sub/mover',{subscriber:'websocket'});
moverStatus.on('message', function(moverdata) {
var moverlines = 0;
var selectlines = [] ;
try {
moverdata = JSON.parse(moverdata);
$.each(moverdata,function(key,value) {
if(key=="Showlines") {moverlines=value;}
if(key=="Selectlines") {selectlines=String(value).split(',');}
$('#'+key).html(value);
});
} catch(e) {
$.each(moverdata.split(';'),function(k,v) {
var keydata = v.split('#');
if(keydata[0]=="Showlines") {moverlines=keydata[1];}
if(keydata[0]=="Selectlines") {selectlines=keydata[1].split(',');}
$('#'+keydata[0]).html(keydata[1]);
});
}

if(moverlines > maxmoverlines) moverlines = maxmoverlines;
if(moverlines == 0) {
for (let i = 0; i < 5; i++) {
$('#moverrow'+i ).hide();
};
};
for (let i = 0; i < maxmoverlines; i++) {
$('#moverrow'+i).hide();
}
for (let i = 0; i < moverlines; i++) {
var selectline = i + 1;
var selectlinestr = selectline.toString();
var checkselectline = selectlines.includes(selectlinestr);
if (checkselectline == true) $('#moverrow'+i ).show(); else $('#moverrow'+i ).hide();
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.
});

moverStatus.start();

var devices = new NchanSubscriber('/sub/devices<?=$spot?",parity":""?>',{subscriber:'websocket', reconnectTimeout:5000});
devices.on('message', function(msg, meta) {
switch (<?if($spot):?>meta.id.channel()<?else:?>0<?endif;?>) {
Expand Down Expand Up @@ -877,6 +928,11 @@ endswitch;
<form name="mover_schedule" method="POST" action="/update.htm" target="progressFrame">
<table markdown="1" class="ArrayOperation-Table array_status noshift">
<tr><td></td><td><input type="submit" id="mover-button" name="cmdStartMover" value="_(Move)_"></td><td id="mover-text"></td></tr>
<tr id="moverrow0" hidden><td></td><td><span id="movertitle0">_(File being processed)_</span></td><td id="moverline0"></td><td></td></tr>
<tr id="moverrow1" hidden><td></td><td id="movertitle1">_(Action)_</td><td id="moverline1"></td><td></td></tr>
<tr id="moverrow2" hidden><td></td><td id="movertitle2">_(Progress)_</td><td><span id="moverline2" style="width:50"></span></td><td></td></tr>
<tr id="moverrow3" hidden><td></td><td id="movertitle3">_(Transfering To Array)_:</td><td id="moverline3"></td><td></td></tr>
<tr id="moverrow4" hidden><td></td><td id="movertitle4">_(Transfering From Array)_:</td><td id="moverline4"></td><td></td></tr>
</table>
</form>
<?endif;?>
Expand Down
9 changes: 9 additions & 0 deletions emhttp/plugins/dynamix/MoverSettings.page
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@ _(Mover logging)_:

:mover_logging_help:

_(Mover Progress)_:
: <select name="shareMoverProgress">
<?$var['shareMoverProgress'] = $var['shareMoverProgress'] ?? "disabled"; ?>
<?=mk_option($var['shareMoverProgress'], "enabled", _("Enabled"))?>
<?=mk_option($var['shareMoverProgress'], "disabled", _("Disabled"))?>
</select>

:mover_progress_help:

Comment thread
coderabbitai[bot] marked this conversation as resolved.
<?endif;?>
&nbsp;
: <span class="buttons-spaced">
Expand Down
76 changes: 72 additions & 4 deletions emhttp/plugins/dynamix/nchan/parity_list
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ $varroot = '/var/local/emhttp';
$log = '/boot/config/parity-checks.log';
$stamps = '/var/tmp/stamps.ini';
$resync = '/var/tmp/resync.ini';
$md5_old = $spot_old = $fs_old = $proc_old = -1;
$md5_old = $spot_old = $fs_old = $proc_old = $mover_old = -1;
$remove_resync_files = 0;
$timer = 3;

require_once "$docroot/webGui/include/Helpers.php";
require_once "$docroot/webGui/include/publish.php";
Expand Down Expand Up @@ -68,6 +69,25 @@ function create_sync($file) {
function create_file($file,...$data) {
if (!file_exists($file)) file_put_contents($file,implode(',',$data));
}
function mover_percent($value) {
return max(0, min(100, is_numeric($value) ? round($value, 2) : 0));
}
function mover_html($value) {
return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
function mover_duration($seconds) {
$seconds = (int)$seconds;
if ($seconds <= 0) return _('Unknown');
$hours = floor($seconds / 3600);
$mins = floor(($seconds % 3600) / 60);
$secs = $seconds % 60;
return ($hours ? $hours.':' : '').sprintf($hours ? '%02d:%02d' : '%d:%02d', $mins, $secs);
}
function mover_bar($percent, $text='') {
$percent = mover_percent($percent);
$text = $text ?: $percent.'%';
return "<div class='usage-disk' style='width:50%'><span style='width:$percent%' class='greenbar'></span><span>$text</span></div>";
}

while (true) {
$var = (array)@parse_ini_file("$varroot/var.ini");
Expand Down Expand Up @@ -121,6 +141,9 @@ while (true) {
}
}




/* Handle fsState changes */
if (_var($var, 'fsState') == 'Copying') {
$fsState = _var($var, 'fsCopyPrcnt') . "% " . _('completed');
Expand All @@ -147,15 +170,60 @@ while (true) {
$process = 0;
}

if ($process == 2) {
$moverdata = [];
if ( file_exists("$varroot/mover.ini")) {
$moverstat = @parse_ini_file("$varroot/mover.ini") ?: [];
$mover = $moverstat;
$totalSize = _var($moverstat, 'TotalSize', _var($moverstat, 'TotalToArray', 0) + _var($moverstat, 'TotalFromArray', 0));
$remainSize = _var($moverstat, 'RemainSize', _var($moverstat, 'RemainToArray', 0) + _var($moverstat, 'RemainFromArray', 0));
$perc = mover_percent(_var($moverstat, 'Filepercent', 0));
$throughput = _var($moverstat, 'Throughput', 0);
$eta = mover_duration(_var($moverstat, 'ETA', 0));
$rate = $throughput > 0 ? my_scale($throughput, $unit, 1)." $unit/sec" : _('Unknown');
$value1 = mover_bar($perc);
if ($totalSize > 0) {
$totalPerc = mover_percent(($totalSize - $remainSize) / $totalSize * 100);
$value2 = $remainSize > 0
? mover_bar($totalPerc)
: _("Transfer complete");
} else {
$value2 = _("Nothing to move");
}
$value3 = _("ETA").": $eta &bullet; "._("Speed").": $rate";
$moverdata = [
'Showlines' => (int)_var($moverstat, 'Showlines', 0),
'Selectlines' => _var($moverstat, 'Selectlines', ''),
'movertitle0' => mover_html(_(_var($moverstat, 'movertitle1', 'File being processed:'))),
'movertitle1' => mover_html(_(_var($moverstat, 'movertitle2', 'Action:'))),
'movertitle2' => mover_html(_(_var($moverstat, 'movertitle3', 'Progress:'))),
'movertitle3' => mover_html(_(_var($moverstat, 'movertitle4', 'Overall Progress:'))),
'movertitle4' => mover_html(_(_var($moverstat, 'movertitle5', 'Estimated Completion:'))),
'moverline0' => mover_html(_var($moverstat, 'File')),
'moverline1' => mover_html(_var($moverstat, 'Action')),
'moverline2' => $value1,
'moverline3' => $value2,
'moverline4' => $value3,
];
$timer = 1;
} else {
$moverdata['Showlines'] = 0; $mover = -1 ; $timer = 3 ;
}
} else {
$moverdata = [];
$moverdata['Showlines'] = 0; $mover = -1 ; $timer = 3 ;
}

// publish but don't republish duplicate messages
publish_noDupe('parity', json_encode($echo));
publish_noDupe('parity', json_encode($echo));
publish_noDupe('paritymonitor', $spot > 0 ? 1 : 0);
publish_noDupe('fsState', $fsState);
publish_noDupe('fsState', $fsState);
publish_noDupe('mymonitor', $process);
publish_noDupe('mover', json_encode($moverdata));

// ping the page so we can terminate if nobody is listening
ping("mainPingListener");

sleep(3);
sleep($timer);
}
?>
Loading
Loading