hello ,
how can I get the modem information (signal \ networks \ status …) while using c# api?
/interface ppp-client info ppp-out1?
it this kind of thing even possiable?
Thanks ,
hello ,
how can I get the modem information (signal \ networks \ status …) while using c# api?
/interface ppp-client info ppp-out1?
it this kind of thing even possiable?
Thanks ,
Using tik4net:
using (var conn = tik4net.ConnectionFactory.OpenConnection(TikConnectionType.Api, "192.168.88.1", 8728, "admin", "mypassword"))
{
var result = conn.CreateCommandAndParameters("/interface/ppp-client/info", TikCommandParameterFormat.NameValue, "number", "ppp-out1").ExecuteList();
result.Dump(); // Or whatever.
}
In MT C# API:
mikrotik.Send("/interface/ppp-client/info");
mikrotik.Send("=number=ppp-out1", true);
may help this link;
https://wiki.mikrotik.com/wiki/Manual:API#Command_examples
I know the command -
but I get nothing - no replay
mikrotik.Send("/interface/ppp-client/info");
mikrotik.Send("=number=ppp-out1", true);
foreach (string h in mikrotik.Read())
{
Test3.Text = h ;
}
but after I shutdown the “job” in the scripts job - then he give the replay ..
I don’t need to give him 6 seconds and then close the info or something - so the code will continue?
Thanks ,
Hmm, you’re right.. It seems you have to wait for the required info (which is pushed to you), ignoring the incomplete answers, after which you can stop the operation by invoking /cancel.
C# tik4net:
using (var conn = tik4net.ConnectionFactory.OpenConnection(TikConnectionType.Api, "192.168.88.1", 8728, "admin", "mypassword")))
{
var ts = new CancellationTokenSource();
var command = conn.CreateCommand("/interface/ppp-client/info");
command.AddParameterAndValues("number", "ppp-out1");
command.ExecuteAsync(response =>
{
if (response.Words.ContainsKey("modem-status"))
{
response.Dump();
ts.Cancel();
}
});
try
{
Task.Delay(TimeSpan.FromSeconds(15), ts.Token).Wait();
}
catch (AggregateException ex)
{
ex.Handle(e => e is TaskCanceledException);
}
command.Cancel();
}
Result:

Raw dump:
/interface/ppp-client/info
=number=ppp-out1
.tag=8
!re
.tag=8
=modem-status=
=pin-status=
=functionality=
=manufacturer=
=model=
=revision=
=serial-number=
=current-operator= (cellid )
=access-technology=
=signal-strengh=
=frame-error-rate=
=.section=0
!re
.tag=8
=modem-status=
=pin-status=
=functionality=
=manufacturer=
=model=
=revision=
=serial-number=
=current-operator= (cellid )
=access-technology=
=signal-strengh=
=frame-error-rate=
=.section=1
!re
.tag=8
=modem-status=ready
=pin-status=no password required
=functionality=full
=manufacturer=huawei
=model=E173
=revision=11.126.85.00.209
=serial-number=xxxxxxxxxxxxxxx
=current-operator=ERROR (cellid unknown)
=access-technology=ERROR
=signal-strengh=-93 dBm
=frame-error-rate=n/a
=.section=2
/cancel
=.tag=8
!trap
.tag=8
=category=2
=message=interrupted
!done
!done
.tag=8
great - so we found the problem and a solution ![]()
can you help me do the same code in
MT C# API ?
my all code is in MT and I don’t want to change it now…
this is what I did -
mikrotik.Send("/interface/disable");
mikrotik.Send("=numbers=SIM1", true);
mikrotik.Send("/interface/ppp-client/info");
mikrotik.Send("=numbers=SIM1",true);
Task.Delay(TimeSpan.FromSeconds(15));
foreach (string h in mikrotik.Read())
{ Test1.Text = (h);}
mikrotik.Send("/interface/enable");
mikrotik.Send("=numbers=SIM1", true);
and I can see it disable \ enable the interface and this is all
i don’t even see gim try to do “Info”
why ?
The delay is to prevent application hangs. First, parse the answer and wait till you get what you are looking for.
Then break out of loop. This is why i pasted the raw data.
foreach (string h in mikrotik.Read())
{
if (h != null && h.StartsWith("=signal-strengh=") && h.Length > 16)
{
Test3.Text = h.Substring(16);
break;
}
};
mikrotik.Send("/cancel", true);
Note that you should also assign a tag and refer to the tag in the cancel command. This is properly taken care of in tik4net for you..
The LINQPad example file can be downloaded here: http://share.linqpad.net/wuqfaq.linq
Just download LINQPad 5 to run this example: http://www.linqpad.net/Download.aspx
Type F4 or open file as text to check out namespaces and references.
I have try to do waht you said
but I don’t see it waiting for 15 seconds
it’s only diable \ enable the interface.
maybe something wrong in the delay command?
Task.Delay(TimeSpan.FromSecond(15));
isn’t say it should wait 15 seconds?
Thanks ,
Err. right. You should disable the interface before checking for info.
Have you tried disabling the interface before running info command?
After enabling/disabling interface you should do a .Read() to be sure the command has been accepted.
yes I disable the interface
now I can see he is waitng 15 seconds
but I still get no replay
this is the all command :
private void button2_Click(object sender, EventArgs e)
{
var ts = new CancellationTokenSource();
mikrotik.Send("/interface/disable");
mikrotik.Send("=numbers=SIM1", true);
mikrotik.Send("/interface/ppp-client/info");
mikrotik.Send("=numbers=SIM1", true);
Task.Delay(TimeSpan.FromSeconds(15), ts.Token).Wait();
foreach (string h in mikrotik.Read())
{
if (h == "!done")
break;
// Console.WriteLine(h);
string[] PPPAnswer = h.Split('='); // give me the answer without the "="
int sizePPPAnswer = PPPAnswer.Length; // give numbers of answers
for (int x = 0; x < sizePPPAnswer; x++) // save the wanted answers in string
switch (PPPAnswer[x])
{
case "!re":
break;
case "!done":
break;
case "model":
Model = PPPAnswer[x + 1];
break;
case "serial-number":
Serial = PPPAnswer[x + 1];
break;
case "current-operator":
Operator = PPPAnswer[x + 1];
break;
case "access-technology":
Access = PPPAnswer[x + 1];
break;
case "signal-strengh":
Signal = PPPAnswer[x + 1];
break;
default:
break;
}//switch
Test1.Text = (Model);
Test2.Text = (Serial);
Test3.Text = (Operator);
Test4.Text = (Signal);
Test5.Text = (Access);
mikrotik.Send("/interface/enable");
mikrotik.Send("=numbers=SIM1", true);
}
}
It seems that the MT class does not support !re commands. I have altered the function to return intermediate results (by using yield return).
Then, the loop will break as soon as all the parameters are set (not empty).
Result:

Download: http://share.linqpad.net/o6asrt.linq
First of all Thank you!
maybe in Sierra Modem we need to add timeout for the answer?
10 seconds - no replay return “ERROR”?
now I’m getting response but not like you did :
!re.tag=aaa=name=Test
!done.tag=aaa
!done.tag=bbb
Model: MC7304
Serial: 356853052638440
Operator: Partner (cellid 75f802!trap.tag=ccc=category=2=message=interrupted
!done
I see it enable to modem - so the code run OK
but it won’t print the last 2 var: access-technology , signal
I think it because the signal\access take 1-2 more seconds to show (even in cmd info command)
so mayne we need to give him a 7 seconds and then return answer?
“We” need to do nothing. But if you are missing some fields, debugging you should ![]()
(Set breakpoints, evaluate local variables, analyze network traffic using Wireshark, etc.)
OK ![]()
I think I found the problem
something in the “@operator” was too long or something…
when I did this"
@operator = (@operator.Substring(0,8))
it start to work and didn’t get stuck…
strange no?
and thank you again !
Nice find, probably some weird character in operator field which is not supported by Internet Explorer (LINQPad result panel).
Wrapping code in a task and executing with timeout results in program getting stuck on the line: o += (Char)connection.ReadByte();
So, you’re better off counting the responses and cancel operation after a few (30 or so) tries. Example:
// ...
int responseCount = 0;
// ...
foreach (string h in mikrotik.Read())
{
responseCount++;
// ...
if (new[] { model, serial, @operator, signal, access }.All(x => !string.IsNullOrEmpty(x)) || responseCount >= 30)
{
// ...
I have found a way to “quit” and enable the interface when I get no replay
and in the LINQ it’s working just great …
but when I take the code into the Visual Studio
it doesn’t work…
any idea why?
I have change your 1 line of code into 5 in order to understand what you did (this is all);
private void button2_Click(object sender, EventArgs e)
{
Test5.Text = ("Start!");
mikrotik.Send("/interface/disable");
mikrotik.Send("=numbers=SIM1" );
mikrotik.Send(".tag=bbb", true);
foreach (string h in mikrotik.Read())
{
// Console.WriteLine(h);
}
mikrotik.Send("/interface/ppp-client/info");
mikrotik.Send("=number=SIM1" );
mikrotik.Send(".tag=ccc", true);
int counter = 0;
foreach (string h in mikrotik.Read())
{
if (h == "!done")
{
break;
}
// Console.WriteLine(h);
string[] PPPAnswer = h.Split('='); // give me the answer without the "="
int sizePPPAnswer = PPPAnswer.Length; // give numbers of answers
for (int x = 0; x < sizePPPAnswer; x++) // save the wanted answers in string
switch (PPPAnswer[x])
{
case "!re":
break;
case "!done":
break;
case "model":
model = PPPAnswer[x + 1];
break;
case "serial-number":
serial = PPPAnswer[x + 1];
break;
case "current-operator":
op = PPPAnswer[x + 1];
op = (op.Substring(0, 8));
break;
case "access-technology":
access = PPPAnswer[x + 1];
break;
case "signal-strengh":
signal = PPPAnswer[x + 1];
break;
default:
break;
}//switch
var arry = new[] { model, serial, op, signal, access };
if (arry.All(check))
{
Test1.Text = ($"Model: {model}");
Test2.Text = ($"Serial: {serial}");
Test3.Text = ($"Operator: {op}");
Test4.Text = ($"Signal: {signal}");
Test5.Text = ($"Access: {access}");
// Console.WriteLine("-------------------");
break;
}
counter++;
Test5.Text = counter.ToString();
if (counter == 6)
{
mikrotik.Send("/cancel");
mikrotik.Send("=tag=ccc", true);
// Console.WriteLine("-------------------");
Test1.Text = ($"Model: Error");
Test2.Text = ($"Serial: Error");
Test3.Text = ($"Operator: Error");
Test4.Text = ($"Signal: Error");
Test5.Text = ($"Access: Error");
// Console.WriteLine("-------------------");
}
}
mikrotik.Send("/cancel");
mikrotik.Send("=tag=ccc", true);
mikrotik.Send("/interface/enable");
mikrotik.Send("=numbers=SIM1", true);
foreach (string h in mikrotik.Read())
{
// Console.WriteLine(h);
}
Test5.Text = ("Done!");
}
bool check(string x)
{
return !string.IsNullOrEmpty(x);
}
The modified code runs fine here.. in LINQPad.
So there’s nothing wrong with the modifications you have made.
This is a very unhelpful problem description.
Could you describe what works and what doesn’t?
Does the code compile?
Does the window appear?
Does the Start! message appear?
Does the loop complete?
Try stepping through the code using breakpoints and F10 to step through.
I know it’s work on LINQ - this is why I copy it as is to virtual
the code compile wihtout any errors.
the window appear.
but I don’t get “start!” massage
the loops get stuck - it doesn’t enable the interface
I don’t know where to look …
I have started to debug it
line after line
and I think the problem is in 1 of the mikrotik.Read
because I can see it doesn’t give the answer I want in the place I want …
I will let you know (unless you find the problem before
)
I have notich now that some time after I press the button he “Skip” this part:
private void button2_Click(object sender, EventArgs e)
{
Test5.Text = ("Donefgjklfgjklgfjkla!");
mikrotik.Send("/interface/disable");
mikrotik.Send("=numbers=SIM1" , true );
// mikrotik.Send(".tag=bbb", true);
foreach (string h in mikrotik.Read())
{ }
int counter = 0;
mikrotik.Send("/interface/ppp-client/info");
mikrotik.Send("=number=SIM1" );
// mikrotik.Send(".tag=ccc", true);
Thanks ,
That makes much more sense. You probably haven’t applied the modifications to the MK class.
In MK class, change:
public List<string> Read()
{
List<string> output = new List<string>();
Into:
public IEnumerable<string> Read()
{
Change:
if (tmp[3] == 0)
{
Output.Add(o);
Into:
if (tmp[3] == 0)
{
yield return o;
And remove:
return output;
![]()
this is what I wanted to write now
it get stuck on
if (tmp[3] == 0)
{
Output.Add(o);
I have change what you have told but now I have many errors:
all of them is where I have this line
string temp = mikrotik.Read()[0];
CS0021 C# Cannot apply indexing with to an expression of type ‘IEnumerable’
?
Thanks ,