Compare commits

..

77 commits

Author SHA1 Message Date
Christian Hesse
3a6f5feb4a netwatch-dns: check with a HTTP/2 request
We need RouterOS 7.24 for this to catch runtime errors for bad
command parameters.

Actually this would work with RouterOS 7.23 on architectures that
support http-version=http2 ...
2026-07-17 11:48:22 +02:00
Christian Hesse
cd9e3feb54 Merge branch 'dhcp-to-dns' into next 2026-07-17 11:48:22 +02:00
Christian Hesse
3e903b479f bump required RouterOS version for all scripts 2026-07-17 11:48:22 +02:00
Christian Hesse
7de44c9200 dhcp-to-dns: allow to ignore for specific lease 2026-07-17 11:48:22 +02:00
Christian Hesse
02a87dae3c global-functions: $NetMask6: use shift operator...
... and drop the workaround. This requires RouterOS 7.22beta3.
2026-07-17 11:48:22 +02:00
Christian Hesse
800a82ba05 update list of contributors 2026-07-17 11:48:22 +02:00
Christian Hesse
d54af97513 Merge branch 'break-in-loop' into next 2026-07-17 11:48:22 +02:00
Łukasz Witkowski
7ab66fc7a9 dhcp-to-dns: allow to specify domain for CNAMEs...
... in network or lease.

Co-authored-by: Christian Hesse <mail@eworm.de>
2026-07-17 11:48:22 +02:00
Christian Hesse
6ffb08066f Merge branch 'continue-in-loop' into next 2026-07-17 11:48:22 +02:00
Christian Hesse
2d04d78b05 telegram-chat: fix indention 2026-07-17 11:48:22 +02:00
Łukasz Witkowski
9b47e6b8a7 dhcp-to-dns: set $LeaseInfo
Co-authored-by: Christian Hesse <mail@eworm.de>
2026-07-17 11:48:22 +02:00
Christian Hesse
0a6cad5b2b Merge branch 'early-exit-with-exit' into next 2026-07-17 11:48:22 +02:00
Christian Hesse
3315ca52c6 dhcp-to-dns: fix indention 2026-07-17 11:48:22 +02:00
Christian Hesse
7eb3c21cfa telegram-chat: use :break in loop 2026-07-17 11:48:22 +02:00
Łukasz Witkowski
ece7e9a5cd dhcp-to-dns: convert DNS names to lower case
Co-authored-by: Christian Hesse <mail@eworm.de>
2026-07-17 11:48:22 +02:00
Christian Hesse
c3fc2bf22c Merge branch 'compare-ids' into next 2026-07-17 11:48:22 +02:00
Christian Hesse
6bc651d51c global-functions: deprecate $ExitError 2026-07-17 11:48:22 +02:00
Christian Hesse
a0d8f280d9 dhcp-to-dns: use another :continue in loop 2026-07-17 11:48:22 +02:00
Christian Hesse
a36a17b444 check-certificates: use :break in loop 2026-07-17 11:48:22 +02:00
Christian Hesse
a5b02f27b0 dhcp-to-dns: support to ignore networks
Closes: https://github.com/eworm-de/routeros-scripts/issues/119
2026-07-17 11:48:22 +02:00
Christian Hesse
a8ba5ee13b Merge branch 'mode-button' into next 2026-07-17 11:48:22 +02:00
Christian Hesse
539fcc3844 global-functions: deprecate $HexToNum 2026-07-17 11:48:22 +02:00
Christian Hesse
f5a814df60 update-tunnelbroker: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
9559b2e21f dhcp-to-dns: use :continue in loop 2026-07-17 11:48:22 +02:00
Christian Hesse
16cfe335c2 announce the change on mode-button, run migration 2026-07-17 11:48:22 +02:00
Christian Hesse
6cfde9def4 log-forward: fix indention 2026-07-17 11:48:22 +02:00
Christian Hesse
db93e792e6 update-gre-address: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
2289d69b01 telegram-chat: use :continue in loop 2026-07-17 11:48:22 +02:00
Christian Hesse
68dfe26198 mode-button: drop all global variables
With RouterOS 7.24 (actually 7.24beta1 I think) the mode, reset and wps
button scripts are run with limited policy. This causes global variables
not being available... So let's drop them here.

This is kind of inconvenient, but we can live with it. The second script
'mode-button-scheduler' is run from scheduler and does not suffer that
limitation.
2026-07-17 11:48:22 +02:00
Christian Hesse
57c954af1d log-forward: use comparison for ids
This was introduced with RouterOS 7.22beta1.

Initializing $LogForwardLast with boolean value looks odd, but this is
required to match the very first message.
2026-07-17 11:48:22 +02:00
Christian Hesse
f0cc45d2ab telegram-chat: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
1be42fc35b netwatch-dns: fix indention 2026-07-17 11:48:22 +02:00
Christian Hesse
198b088faa mode-button{,-scheduler}: store to and get count from scheduler's comment 2026-07-17 11:48:22 +02:00
Christian Hesse
dd51fd33e0 sms-forward: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
f1910d0832 netwatch-dns: use :continue in loop 2026-07-17 11:48:22 +02:00
Christian Hesse
9d0ad044a3 sms-action: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
4da0a30210 netwatch-dns: fix indention 2026-07-17 11:48:22 +02:00
Christian Hesse
71a4beabac ppp-on-up: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
83e71ffd5d netwatch-dns: use :continue in loop 2026-07-17 11:48:22 +02:00
Christian Hesse
57f713477b packages-update: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
e92d79b2b7 global-functions: $ScriptInstallUpdate: fix indention 2026-07-17 11:48:22 +02:00
Christian Hesse
389009453e ospf-to-leds: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
bcb1c77b2f global-functions: $ScriptInstallUpdate: use :continue in loop 2026-07-17 11:48:22 +02:00
Christian Hesse
d0b8e8f808 netwatch-notify: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
4c14186e18 global-functions: $CleanName: use :continue in loop 2026-07-17 11:48:22 +02:00
Christian Hesse
4ba4b6d16f netwatch-dns: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
381bb0038a fw-addr-lists: fix indention 2026-07-17 11:48:22 +02:00
Christian Hesse
363adaaa47 mode-button-scheduler: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
b407b08254 fw-addr-lists: use :continue in loop 2026-07-17 11:48:22 +02:00
Christian Hesse
a88eea6e64 log-forward: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
53d17d2981 ipv6-update: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
d4de082771 ipsec-to-dns: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
1b3ce0f834 hotspot-to-wpa-cleanup: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
ceafb0ed04 hotspot-to-wpa: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
add84f32ff gps-track: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
b065a314af fw-addr-lists: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
942c50aff8 firmware-upgrade-reboot: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
03d506d2bf dhcpv6-client-lease: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
5d912bc548 dhcpv4-server-lease: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
6155b6c2a4 dhcp-to-dns: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
7717b30c23 dhcp-lease-comment: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
21a1b32624 daily-psk: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
be629dbfba collect-wireless-mac: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
dc7d6c5c74 check-routeros-update: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
45721186ac check-perpetual-license: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
b9ae49b1bc check-lte-firmware-upgrade: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
9378d2977a check-health: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
f3df68f97d check-certificates: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
5370bc3d0f certificate-renew-issued: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
c946c9b9bb capsman-rolling-upgrade: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
b6a0293572 capsman-download-packages: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
63d76f031a backup-upload: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
bee12c01ae backup-partition: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
dff5444b1e backup-email: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
e0bfaddcff backup-cloud: early exit with :exit 2026-07-17 11:48:22 +02:00
Christian Hesse
0e5a30d946 mode-button: spilt the into two scripts 2026-07-17 10:22:25 +02:00
Christian Hesse
b3aa479515 mode-button: resolve nested conditions 2026-07-17 09:04:39 +02:00
5 changed files with 96 additions and 79 deletions

View file

@ -16,7 +16,7 @@ Mode button with multiple presses
Description
-----------
This script extend the functionality of mode button. Instead of just one
These scripts extend the functionality of mode button. Instead of just one
you can trigger several actions by pressing the mode button several times.
The hardware needs to have a mode button, see
@ -39,9 +39,9 @@ Copy this code to terminal to check:
Requirements and installation
-----------------------------
Just install the script:
Just install the scripts:
$ScriptInstallUpdate mode-button;
$ScriptInstallUpdate mode-button,mode-button-scheduler;
Then configure the mode button to run `mode-button`:

View file

@ -15,7 +15,7 @@
# Git commit id & info, expected configuration version
:global CommitId "unknown";
:global CommitInfo "unknown";
:global ExpectedConfigVersion 143;
:global ExpectedConfigVersion 144;
# global variables not to be changed by user
:global GlobalFunctionsReady false;

80
mode-button-scheduler.rsc Normal file
View file

@ -0,0 +1,80 @@
#!rsc by RouterOS
# RouterOS script: mode-button-scheduler
# Copyright (c) 2018-2026 Christian Hesse <mail@eworm.de>
# https://rsc.eworm.de/COPYING.md
#
# requires RouterOS, version=7.22
# requires device-mode, scheduler
#
# act on multiple mode and reset button presses
# https://rsc.eworm.de/doc/mode-button.md
:onerror Err {
:global GlobalConfigReady; :global GlobalFunctionsReady;
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global ModeButton;
:global LogPrint;
:global ModeButtonScheduler;
:global ValidateSyntax;
:local LEDInvert do={
:global ModeButtonLED;
:global IfThenElse;
:local LED [ /system/leds/find where leds=$ModeButtonLED \
!disabled type~"^(on|off)\$" interface=[] ];
:if ([ :len $LED ] = 0) do={
:return false;
}
/system/leds/set type=[ $IfThenElse ([ get $LED type ] = "on") "off" "on" ] $LED;
}
:local Scheduler [ /system/scheduler/find where name="mode-button-scheduler" ];
:if ([ :len $Scheduler ] = 0) do={
$LogPrint error $ScriptName ("Scheduler does not exist.");
:exit;
}
:local Count ([ :deserialize from=json [ /system/scheduler/get $Scheduler comment ] ]->"count");
:local Code ($ModeButton->[ :tostr $Count ]);
/system/scheduler/remove $Scheduler;
:if ([ :len $Code ] = 0) do={
$LogPrint info $ScriptName ("No action defined for " . $Count . " mode-button presses.");
:exit;
}
:if ([ $ValidateSyntax $Code ] = false) do={
$LogPrint warning $ScriptName \
("The code for " . $Count . " mode-button presses failed syntax validation!");
:exit;
}
$LogPrint info $ScriptName ("Acting on " . $Count . " mode-button presses: " . $Code);
:for I from=1 to=$Count do={
$LEDInvert;
:if ([ /system/routerboard/settings/get silent-boot ] = false) do={
:beep length=200ms;
}
:delay 200ms;
$LEDInvert;
:delay 200ms;
}
:onerror Err {
[ :parse $Code ];
} do={
$LogPrint warning $ScriptName \
("The code for " . $Count . " mode-button presses failed with runtime error: " . $Err);
}
} do={
:global ExitOnError; $ExitOnError [ :jobname ] $Err;
}

View file

@ -10,86 +10,21 @@
# https://rsc.eworm.de/doc/mode-button.md
:onerror Err {
:global GlobalConfigReady; :global GlobalFunctionsReady;
:retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \
do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50;
:local ScriptName [ :jobname ];
:global ModeButton;
:global LogPrint;
:set ($ModeButton->"count") ($ModeButton->"count" + 1);
:local Scheduler [ /system/scheduler/find where name="_ModeButtonScheduler" ];
:local Scheduler [ /system/scheduler/find where name="mode-button-scheduler" ];
:if ([ :len $Scheduler ] = 0) do={
$LogPrint info $ScriptName ("Creating scheduler _ModeButtonScheduler, counting presses...");
:global ModeButtonScheduler do={ :onerror Err {
:local FuncName $0;
:global ModeButton;
:global LogPrint;
:global ModeButtonScheduler;
:global ValidateSyntax;
:local LEDInvert do={
:global ModeButtonLED;
:global IfThenElse;
:local LED [ /system/leds/find where leds=$ModeButtonLED \
!disabled type~"^(on|off)\$" interface=[] ];
:if ([ :len $LED ] = 0) do={
:return false;
}
/system/leds/set type=[ $IfThenElse ([ get $LED type ] = "on") "off" "on" ] $LED;
}
:local Count ($ModeButton->"count");
:local Code ($ModeButton->[ :tostr $Count ]);
:set ($ModeButton->"count") 0;
:set ModeButtonScheduler;
/system/scheduler/remove [ find where name="_ModeButtonScheduler" ];
:if ([ :len $Code ] > 0) do={
:if ([ $ValidateSyntax $Code ] = true) do={
$LogPrint info $FuncName ("Acting on " . $Count . " mode-button presses: " . $Code);
:for I from=1 to=$Count do={
$LEDInvert;
:if ([ /system/routerboard/settings/get silent-boot ] = false) do={
:beep length=200ms;
}
:delay 200ms;
$LEDInvert;
:delay 200ms;
}
:onerror Err {
[ :parse $Code ];
} do={
$LogPrint warning $FuncName \
("The code for " . $Count . " mode-button presses failed with runtime error: " . $Err);
}
} else={
$LogPrint warning $FuncName \
("The code for " . $Count . " mode-button presses failed syntax validation!");
}
} else={
$LogPrint info $FuncName ("No action defined for " . $Count . " mode-button presses.");
}
} do={
:global ExitOnError; $ExitOnError $0 $Err;
} }
/system/scheduler/add name="_ModeButtonScheduler" \
on-event=":global ModeButtonScheduler; \$ModeButtonScheduler;" interval=3s;
:log info ($ScriptName . ": Creating scheduler mode-button-scheduler, counting presses...");
/system/scheduler/add name="mode-button-scheduler" interval=3s \
comment=[ :serialize to=json ({ count=1 }) ] \
on-event="/system/script/run mode-button-scheduler;";
} else={
$LogPrint debug $ScriptName ("Updating scheduler _ModeButtonScheduler...");
/system/scheduler/set $Scheduler start-time=[ /system/clock/get time ];
:log debug ($ScriptName . ": Updating scheduler mode-button-scheduler...");
:local Presses (([ :deserialize from=json [ /system/scheduler/get $Scheduler comment ] ]->"count") + 1);
/system/scheduler/set $Scheduler start-time=[ /system/clock/get time ] \
comment=[ :serialize to=json ({ count=$Presses }) ];
}
} do={
:global ExitOnError; $ExitOnError [ :jobname ] $Err;
:log error ([ :jobname ] . ": " . $Err);
}

View file

@ -68,6 +68,7 @@
141="Introduced script 'dhcpv6-client-lease' to run several scripts on IPv6 DHCP client lease.";
142="Added a setting for 'mod/notification-email' to check availability of certificate chain.";
143="Made backup scripts 'backup-email' and 'backup-upload' support date & time in filenames.";
144="Split and reworked 'mode-button' for compatibility with RouterOS 7.24, configuration was updated automatically.";
};
# Migration steps to be applied on script updates
@ -79,4 +80,5 @@
132=":if ([ :len [ /system/script/find where name=\"check-health\" ] ] > 0) do={ :local Code \":local Install \\\"check-health\\\"; :if ([ :len [ /system/health/find where type=\\\"\\\" name~\\\"-state\\\\\\\$\\\" ] ] > 0) do={ :set Install (\\\$Install . \\\",check-health.d/state\\\"); }; :if ([ :len [ /system/health/find where type=\\\"C\\\" ] ] > 0) do={ :set Install (\\\$Install . \\\",check-health.d/temperature\\\"); }; :if ([ :len [ /system/health/find where type=\\\"V\\\" ] ] > 0) do={ :set Install (\\\$Install . \\\",check-health.d/voltage\\\"); }; :global ScriptInstallUpdate; \\\$ScriptInstallUpdate \\\$Install;\"; :global ValidateSyntax; :if ([ \$ValidateSyntax \$Code ] = true) do={ :do { [ :parse \$Code ]; } on-error={ }; }; };";
138="/certificate/set trusted=yes [ find where trusted=yes ];";
140=":if ([ :len [ /system/script/find where name=\"lease-script\" ] ] > 0) do={ /system/script/set name=\"dhcpv4-server-lease\" \"lease-script\"; :global ScriptInstallUpdate; \$ScriptInstallUpdate; /ip/dhcp-server/set lease-script=\"dhcpv4-server-lease\" [ find where lease-script=\"lease-script\" ]; };";
144=":if ([ :len [ /system/script/find where name=\"mode-button\" ] ] > 0) do={ :global ScriptInstallUpdate; \$ScriptInstallUpdate mode-button-scheduler; };";
};