Macros: Elementary system (old)
Macros (or scripts) are a powerful internal automation mechanism for SIM Roulette aggregators. With macros, virtually any operating scenario can be implemented. It’s also very important that writing macros is accessible even to users unfamiliar with programming: macros do not require compilation (pre-translation into machine code), are always ready to run, and are available for editing.
Macro structure
Syntax
First steps
Useful techniques
Examples
First steps
So what is a macro or script? It’s a set of commands for the aggregator (all commands for your device are described in detail in the corresponding Documentation section), some of which you may already know. For example, modem>connect — a command to connect the contact group to the SIM card.
Let’s try to write our first macro. Go to the Macros section of your device’s WEB interface and click “Create macro.” In the “Name” field enter my_connect. And in the “Content” field:
modem>connect
modem>on
The macro is ready. The 1st command connects the contact group, the second turns on the modem. Just like that, we’ve already done a small automation. Now save the macro by clicking the corresponding button.
How to run (execute) a macro. You can start a macro from the WEB interface in two ways:
- In the Macros section, find the row with the desired macro name and click the run icon. The running macro’s row will be highlighted, and a new icon — the stop icon — will appear.
- In the Terminal section, enter the command macro: and your macro name — macro:my_connect. There’s also a shortened command m — m:my_connect. Starting via the terminal allows you to pass input data to the macro. Do it like this: m:my_connect>Text_to_pass_to_macro. After the macro starts, a run icon will appear in the terminal status bar; hovering over it shows the name of the running macro.
How to stop a macro. There are also 2 ways to interrupt macro execution:
- In the Macros section, find the row with the running macro and click the stop icon.
- In the Terminal section, enter the command macro:stop. The shortened command m:stop also exists.
So, start your first macro in any way. Did it work?
Let’s go back to editing (the edit icon in the macro row) and add new functionality. Before connecting, we’ll check whether the contacts are already connected. If so, we don’t need to reconnect — we’ll save time.
modem>status:connect
if next
modem>connect
modem>on
[next]
Three new lines have been added:
The modem>status:connect command returns the current contact status: 0 (NULL) — contacts are not connected, 1 — contacts are connected. The next line if next contains a branching operator. If the previous command returns 1, the operator will redirect further program execution to the next label. If not, the command in the line following the operator will be executed. The last new line [next] contains the label to which control will jump from the line with the if operator.
Save and run the updated macro. As you can see, nothing happened, because the modem was already attached to the SIM card and turned on. If you now detach the modem using modem>disconnect and run the macro again, the modem will be attached and turned on again.
So, did you like it? Shall we continue?
Let’s make the macro more sophisticated — add a check for SIM registration in the mobile network:
modem>status:connect
if next
modem>connect
modem>on
[next]
pause 30000
buffer>clear
buffer>modem:grab=1
modem>send:AT+CREG?
pause 200
buffer>test:0,1
if ok
echo>SIM card not registered in the network
goto end
[ok]
echo>SIM card ready for use
[end]
buffer>modem:grab=0
Let’s go through the new lines:
pause 30000 — a 30,000 millisecond (30 second) pause in the program. It is needed so that the SIM card has enough time to register on the mobile network.
buffer>clear — we begin working with the buffer, since it may contain data left over from previous operations — we clear it. The buffer in SIM Roulette is similar to a clipboard on a computer, but you can perform many more operations with it: search, text replacement, executing a command from the buffer, etc. More details can be found in the programming section of your SR model.
buffer>modem:grab=1 — this command enables capturing modem responses into the buffer. Before this command, everything the modem returned was simply sent to the terminal output stream.
modem>send:AT+CREG? — we send the modem an AT command to check the SIM card’s registration status in the network. More details about AT commands can be found in the corresponding section of the documentation.
pause 200 — a short 0.2 second pause is needed for the modem to form and return its response.
buffer>test:0,1 — checks if the modem’s fairly long response contains the code 0,1, which signals that the SIM card has been accepted by the mobile network.
if ok — if the code 0,1 is present, the previous command will return 1, meaning the branching operator will redirect execution to the ok label.
echo>SIM card not registered in the network — if there is no registration, we output a message to the Terminal.
goto end — unconditionally jumps to the end label.
[ok] — label ok.
echo>SIM card ready for use — outputs a message to the Terminal.
[end] — label end.
buffer>modem:grab=0 — before finishing the macro, we restore settings by disabling modem response capture into the buffer.
Run the macro through the Terminal. At the end we now see the result of execution, but during the process intermediate operation responses are also output to the stream — we don’t need them, so let’s hide them. To disable output, add answer=0 at the beginning, and at the end return everything back with the command answer=1.
answer=0
modem>status:connect
if next
modem>connect
modem>on
[next]
pause 30000
buffer>clear
buffer>modem:grab=1
modem>send:AT+CREG?
pause 200
buffer>test:0,1
if ok
echo>SIM card not registered in the network
goto end
[ok]
echo>SIM card ready for use
[end]
buffer>modem:grab=0
answer=1
Now the macro is much better. But we can make another useful modification — add comments to the commands:
answer=0 // Disable output
modem>status:connect // Request connection status
if next // If contacts are connected, jump to label next
modem>connect // Connect contacts
modem>on // Turn on modem
[next]
pause 30000 // Wait 30 seconds
buffer>clear // Clear buffer
buffer>modem:grab=1 // Enable modem response capture
modem>send:AT+CREG? // Ask modem for registration status
pause 200 // Wait 0.2 seconds for response
buffer>test:0,1 // Check if response contains registration code
if ok // If yes, jump to label ok
echo>SIM card not registered in the network // Otherwise print not registered
goto end // Jump to label end
[ok]
echo>SIM card ready for use // Print ready
[end]
buffer>modem:grab=0 // Disable modem response capture
answer=1 // Enable output
Comments help navigate the code, but they also serve another purpose — comments are displayed on the device screen when the debugging function is enabled with the Terminal command debug=1 (disabled with debug=0). This way, if you are confused in your macro branching, enable debugging and watch how the program executes.
Later, new commands and operators will be described in comments.
And what about our macro? It is ready. But not everything in it is optimal. Try to find the place where we are wasting time and which should be rewritten.
Found it?
Yes, it’s where we wait 30 seconds for modem registration, while the minimum registration time is 9 seconds. But how do we know how long it will actually take? The solution is to keep checking until we get either a positive or negative response:
answer=0 // Disable output
modem>status:connect // Request connection status
if next // If contacts are connected, jump to label next
modem>connect // Connect contacts
modem>on // Turn on modem
[next]
pause 5000 // Wait 5 seconds
buffer>clear // Clear buffer
buffer>modem:grab=1 // Enable modem response capture
modem>send:AT+CREG? // Ask modem for registration status
pause 200 // Wait 0.2 seconds for response
buffer>test:0,1 // Check if response contains registration code
if ok // If yes, jump to label ok
buffer>test:0,5 // Check if response contains registration code “Roaming”
if ok // If yes, jump to label ok
buffer>test:0,2 // Look for status “not registered, searching new network”
if next
[error]
echo>SIM card not registered in the network // Otherwise print not registered
goto end // Jump to label end
[ok]
echo>SIM card ready for use // Print ready
[end]
buffer>modem:grab=0 // Disable modem response capture
answer=1 // Enable output
That’s it — now you know how to write macros for SIM Roulette. Read the macro syntax, check the documentation for SR-Nano, SR-Train, SR-Box, and see macro examples. And when you create a useful macro, you can share it with others for free or put it up for sale.
Macro structure
Lines in a macro are executed sequentially from top to bottom. To change the execution order, use labels, branching operators, and unconditional jumps.
Label — any Latin word enclosed in square brackets, placed above the line to which control should jump.
Example of a label: [next]
The macro text must not contain empty lines. Each macro command can be accompanied by a comment separated from the command by the symbols //. The debug=1 command allows you to trace macro execution: the device screen will show comments for the lines being executed by the macro. debug=0 turns this mode off.
When launching a macro through the Terminal, you can pass it input parameters: m:my_macros>Text_to_pass_to_macro The string after > will go to the buffer and can then be parsed using standard buffer operations.
Macros are stored in the /m folder of the file system.
Complex macros are sets of files; in this case it’s advisable to keep them in one folder. When launching a macro through the terminal, it’s enough to specify the folder name — SR will find and run the file of the same name inside the specified folder. If you have a macro m/scanner/scanner, you can run it with m:scanner/scanner or simply m:scanner.
It’s also helpful to supply complex macro sets with a manual in macro format (there is a sample among the examples) named help, and a menu file if you intend to launch different macros from the set (there is an example as well).
Syntax
Branching operators
if — Checks the result of the previous command. If the result equals 1, control jumps to the specified label.
value>a<10
if next
...
[next]
...
unless — Checks the result of the previous command. If the result equals 0 (NULL/Empty), control jumps to the specified label.
unless next
Unconditional jump operator
goto — Performs a jump to the specified label.
goto next
...
[next]
...
Program termination operators
stop — Terminates the macro.
stop
return — Performs an early return from a nested macro (by default, return occurs after executing the command on the last line of the nested macro).
return
Input operator
input — Requests an action from the human operator in the Operator section of the WEB interface. Parameters: maximum input length; text to display above the input field.
input 1;Choose an action:<br>1-first option<br>2-second option
Operators for executing a command from the buffer
exec Executes the command from the buffer (the text placed in the buffer will be executed as a command).
buffer>write=sound:beep
exec
exec2 Executes the command from the buffer copy on the stack.
buffer>write=sound:beep
buffer>push
exec2
Operator for including a nested macro
include Includes the specified macro and transfers control to it (macro nesting depth is unlimited); upon completion, control returns to the current macro.
include macrosname
Pause
pause Pause (program suspension) in milliseconds (1/1000 of a second)
pause 1000
Useful techniques
Text formatting
In the text output to the terminal stream, you can use the following mnemonics for transformations:
[br] — line break
[b]bold text[/b]
[i]italic[/i]
Tables
You can output data to the Terminal stream as a table using the following syntax (for readability it’s spread over lines here, but in a macro the command text is always a single line):
[table]
[tr]
[th]Header of column 1[/th]
[th]Header of column 2[/th]
[/tr]
[tr]
[td]Content of column 1[/td]
[td]Content of column 2[/td]
[/tr]
[/table]
Navigating to another WEB interface page / Reloading the page
To navigate to any _URL_ within text output to the Terminal stream (using echo> or buffer>view), insert the command sr>reload_URL_;
buffer>write=sr>reload/terminal;
buffer>view
echo>sr>reloadhttps://google.com;
Clearing the Terminal output stream
To clear the Terminal output stream, insert the command sr>clear;
buffer>write=sr>clear;
buffer>view
echo>sr>clear;
Emulating manual command entry and execution
To execute any command (_COM_) anywhere in the text output to the Terminal stream (using echo> or buffer>view), insert sr>com:_COM_; The command will be executed with the current Terminal step and will remain in the command log.
buffer>write=sr>com:sound:beep;
buffer>view
echo>sr>com:sound:beep;
Outputting text to the Terminal command input field
To output arbitrary text (_TEXT_) into the Terminal’s command input field anywhere in the text output to the Terminal stream (using echo> or buffer>view), insert sr>enter:_TEXT_; After inserting the text, the browser focus will also move to the command input field.
buffer>write=sr>text:sound:;
buffer>view
echo>sr>text:sound:;
Hyperlinks
For easier navigation, instead of or alongside a list of commands, you can output ready-made hyperlinks that contain commands. To do this, insert the construct [link]_COMMAND_[name]_TITLE_[/name][/link] anywhere in the text output to the Terminal stream (using echo> or buffer>view).
buffer>write=sr>Command [link]sound:beep[name]SOUND[/name][/link]
buffer>view
echo>sr>Command [link]sound:beep[name]SOUND[/name][/link]
Examples
autoexec (SR-Nano)
A macro for controlling the device with a remote control; it offers a menu to choose card scanning on the disk, moving to card A0, or moving to the next card.
answer=0 // Disable output
key>discover // Check if remote control mode is enabled
unless finish // If not — exit
[loop]
display=10::C::64::0::[ {MENU~МЕНЮ} ]|10::L::0::10::1 {Cards scanning~Сканирование карт}|10::L::0::25::2 {Card A0~Карта A0}|10::L::0::40::3 {Next card~Следующая карта} // Show menu on the device screen
[next]
buffer>clear // Clear buffer
key // Request a command from the remote
unless wait // If there’s no command — go wait for it
buffer>test:1 // Look for 1 in the buffer
if a1 // If found
buffer>test:2 // Look for 2 in the buffer
if a2 // If found
buffer>test:3 // Look for 3 in the buffer
if a3 // If found
[wait]
pause 100 // Wait 0.1 seconds
goto next // Repeat
[a1]
sound:beep // Beep
display=10::C::64::15::1 {Cards scanning~Сканирование карт} // Show text on the device screen
include scanner // Transfer control to the SIM card scanning macro
goto loop
[a2]
sound:beep // Beep
display=10::C::64::15::1 {Card A0~Карта A0} // Show text on the device screen
card:A0 // Select card A0
goto loop
[a3]
sound:beep // Beep
display=10::C::64::15::1 {Next card~Следующая карта} // Show text on the device screen
card>next // Select next card
goto loop
[finish]
answer=1 // Enable output
com_add
Macro for adding quick-link buttons to the Terminal.
answer=0 // Disable output
buffer>swap // Swap buffer and copy
buffer>fs>load>file:/terminal.dat // Load current buttons into buffer
buffer>merge= // Merge buffer and its copy
buffer>postfix=; // Add a semicolon at the end
buffer>fs>save>file:/terminal.dat // Save the edited file
buffer>write=Command added // Prepare a “button added” notification
answer=1 // Enable output
buffer>view // Show the notification
answer=0 // Disable output
pause 1000 // Wait one second
buffer>write=sr>reload/terminal; // Prepare text to reload Terminal window
answer=1 // Enable output
buffer>view // Reload the Terminal window