Read values auto update UWA/UWP - c#

private async void CharacteristicReadButton_Click()
{
// BT_Code: Read the actual value from the device by using Uncached.
GattReadResult result = await selectedCharacteristic.ReadValueAsync(BluetoothCacheMode.Uncached);
if (result.Status == GattCommunicationStatus.Success)
{
string formattedResult = FormatValueByPresentation(result.Value, presentationFormat);
rootPage.NotifyUser($"Read result: {formattedResult}", NotifyType.StatusMessage);
}
else
{
rootPage.NotifyUser($"Read failed: {result.Status}", NotifyType.ErrorMessage);
}
}
I'm facing a problem with the read value change. I have setup mpu5060 with my rfduino, so whenever my rfduino moved, it will display the angle on my Arduino serial monitor.
for my c#, I can read the value when I press the "read" button. But if my value(angle) change, it will not auto update to notify user. I have to manually click the "read" button again to change. How do I make it auto update ?

you need to create timer thread to monitor changing of your value.
see this
Timer class

Why not setting up your RfDuino to send a notification, if that is possible.
Or even add your data as advertising, then there is no need for a connection, just reed in in OnAdvertisementReceived.
In your RfDuino do it like this:
void advertise(const char *data, uint32_t ms)
{
// this is the data we want to appear in the advertisement
// /make sure that the RfDuino name + data is not more than 31 bytes
RFduinoBLE.advertisementData = data;
// start the BLE stack
RFduinoBLE.begin();
// advertise for ms milliseconds
RFduino_ULPDelay(ms);
// stop the BLE stack
RFduinoBLE.end();
}
If you want to send new data call:
// advertise "data" for indicated time
advertise("your data", duration);

Related

How to get most recent update in Telegram Bot API

I am struggling on how to get the text of a message to my C#-console tool with a telegram bot. Here is a piece of that is supposed to just print all messages in the telegram channel
private async Task getTelegramMessage()
{
var bot = new Telegram.Bot.TelegramBotClient("token")
var updates = await bot.GetUpdatesAsync();
foreach (var update in updates)
{
Console.WriteLine("Bot: " + update.Message.Text);
}
}
the problem is that i always get all old updates. The maximum length of the array updates is 100. So after I sent 100 messages in the telegram channel, I would only have access to the first 100 messages and no access to the newest. How can I get access to the most recent update? Or can I somehow delete the message after my tool has processed it?
I have seen that the bot provides the Event OnUpdate but I couldnt figure out how to use it.
Thanks a lot for help on that issue.
According documentation, you can use offset -1 to get the last update.
Just put in mind all previous updates will forgotten.
getUpdates Docs
https://api.telegram.org/bot{TOKEN}/getUpdates?offset=-1
oh, I just figured it out. for the offset you have to set the ID returned in the update.
Notes
2. In order to avoid getting duplicate updates, recalculate offset after each server response.
Instead subscribe to the BotOnUpdateReceived event to handle the updates. In main.cs:
Bot.OnUpdate += BotOnUpdateReceived;
Bot.StartReceiving(Array.Empty<UpdateType>());
Console.WriteLine($"Start listening!!");
Console.ReadLine();
Bot.StopReceiving();
And handle the event:
private static async void BotOnUpdateReceived(object sender, UpdateEventArgs e)
{
var message = e.Update.Message;
if (message == null || message.Type != MessageType.Text) return;
var text = message.Text;
Console.WriteLine(text);
await Bot.SendTextMessageAsync(message.Chat.Id, "_Received Update._", ParseMode.Markdown);
}
The Offset is internally working in it and it also internally call GetUpdatesAsync().
From Here you can also get channel post via:
var message = e.Update.ChannelPost.Text; // For Text Messages
I hope it will Help!!

Reading data from a serialport from different threads

Using this example I created two classes used to read a device on a serial port. The device is a laser which I can control (turn system/lasers on/off, read stats etc.) using commands like SYST:STAT?. Most of the commands immediately send back a response that I can read using the _serialPort.ReadLine().
However, the command SYST:STAT ON that turns on the system is one of the commands that takes about ten seconds. This is where the makers of the laser decided it's nice to send back a message that says: system ready. I can read this response asynchonously using the NewSerialDataRecieved event. In here, I read every line like this:
private void OnDataReceived(object sender, SerialDataEventArgs e)
{
_dataReceived += Encoding.ASCII.GetString(e.Data);
// Loop as long as there's full lines available
while (_dataReceived.Length > 0 && _dataReceived.Contains("\r\n"))
{
int delimiterIndex = _dataReceived.IndexOf("\r\n", StringComparison.Ordinal) + 2;
string line = _dataReceived.Substring(0, delimiterIndex); // Get first line from data
_dataReceived = _dataReceived.Substring(delimiterIndex, _dataReceived.Length - line.Length); // Remove first line from data
line = line.Substring(0, line.Length - 2);
TryParseSystemReadyResponse(line);
TryParseEnteringStandbyModeResponse(line);
TryParseTemperatureResponse(line);
OnResponseReceived?.Invoke(line);
}
}
The method reads the incoming data, stores it, and then parses the data line by line. This works perfectly for my asynchronous, well defined responses. Here's the catch: most of the responses are formatted like '0 0' or '0 1'. This means there's no way to parse them like that. This is why I read them directly after sending my command to the serial device, like this:
public void UpdateLaserState()
{
// Get the selected laser
_serialPortManager.SendCommand("LSR:NSEL?");
int selectedLaser = _serialPortManager.ReadIntegerResponse();
// Do stuff with the laser number
OnSystemStateChange?.Invoke();
}
ReadIntegerResponse is a method that does a ReadLine, strips the response of the preceding '0 ' and then parses the remaining string to int. Up to now, communication works as well as I would expect. Messages that can be synchronous are being read instantly and asynchronous messages can be parsed by my OnDataReceived method.
Here comes the problem. I need to read the temperature of the laser system about twice a second. My solution was to create a thread that reads the temperature, like this:
public Laser(){
_temperatureThread = new Thread(TemperatureTask);
_temperatureThread.Start();
_temperatureThreadRunning = true;
}
public void Dispose()
{
_temperatureThreadRunning = false;
_temperatureThread.Join();
}
private void TemperatureTask()
{
while (_temperatureThreadRunning)
{
this.UpdateTemperatures();
Thread.Sleep(TemperatureTaskSleep);
}
}
public void UpdateTemperatures()
{
_serialPortManager.SendCommand("SYST:TEMP?");
//string line = _serialPortManager.ReadResponse();
//TryParseTemperatureResponse(line);
}
This gives problems as UpdateTemperatures sends responses very often on a different thread. I resolved a lot of problems by implementing a lock. However, my responses often get mixed up. I think the following is happening:
Main thread Temperature thread
-----------------------------------------
Sends command |
| Sends command
Reads response |
| Reads response
This means the threads are reading eachothers responses. There is no good way to identify responses like '0 0' as belonging to a certain command.
Is there a way to prevent this from happening?
P.S. the ReadResponse methods of the _serialPortManager all look like this (except for parsing the response):
public string ReadResponse()
{
string response = SafeReadLine();
return StripResponse(response);
}
private string SafeReadLine()
{
lock (_serialPortLock)
{
string response = _serialPort.ReadLine();
return StripResponse(response);
}
}

How can I coordinate between COM port sends and receives?

I'm trying to refactor some ultra-complex legacy code that sends data from a handheld device to an app running on a PC, to which the handheld device is connected.
There is a "conversation" that goes on between the two apps that follows a protocol; the server (the app running on the PC) responds based on what the client tells it, and vice versa. Actually, the "conversation" can be seen about two thirds of the way down here.
Anyway, my problem is: how can I let the client wait for the server to respond without interrupting it, or thinking it's not going to respond and failing to continue? This is what I have right now:
public class FileXferLegacy : IFileXfer
{
private SerialPort cereal;
private String lastDataReceived;
private String receivedData;
. . .
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// This method will be called when there is data waiting in the port's buffer
try
{
receivedData += cereal.ReadLine();
lastDataReceived = receivedData;
ExceptionLoggingService.Instance.WriteLog(String.Format("Received {0} in FileXferLegacy.SendDataContentsAsXML", receivedData));
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
}
}
#region IFileFetchSend Members
. . .
public void SendDataContentsAsXML(string destinationPath, string data)
{
byte[] stuff;
ExceptionLoggingService.Instance.WriteLog("Reached
FileXferLegacy.SendDataContentsAsXML");
cereal.Open();
stuff = System.Text.UTF8Encoding.UTF8.GetBytes("PING" + "\n");
cereal.Write(stuff, 0, stuff.Length);
if (lastDataReceived.Contains("PING")) // Expecting "PING|ACKNOWLEDGE|"
{
stuff =
System.Text.UTF8Encoding.UTF8.GetBytes("LOGIN|foo|000003|LOC_HOST|PPP_PEER|1.4.0.42|bar" + "\n");
// TODO: replace this test data with dynamic data
cereal.Write(stuff, 0, stuff.Length);
}
if (lastDataReceived.Contains("JOIN|LEVEL")) // Expecting something like "JOIN|LEVEL|1
SETTING|ALT_ID|FALSE"
{
stuff = System.Text.UTF8Encoding.UTF8.GetBytes("HHTCOMMAND|GETHHTSUPDATE|");
cereal.Write(stuff, 0, stuff.Length);
}
. . .
String lastResponse = lastDataReceived; // Expecting something like
"RESULT|FILECOMPLETE|INV_000003_whatever(not identical to what was sent earlier!).XML"
// Parse out and do something with the filename ("INV_000003_whatever(not identical to
what was sent earlier!).XML" above)
}
As you can see, the client/handheld sends a string; it then reads "lastDataReceived" which is assigned in the DataReceived method. But what if there has been a delay, and "lastDataReceived" is null? What do I need to do to force a delay (without going to an extreme that would cause the app to appear slothlike in its slowness)? Or what is the way this should be done, if I'm totally off base?
A typical approach is to use a reader thread that pulls bytes off the port with blocking reads (though it can be done with async notification instead) and, once detecting that an entire message has been delivered, it either:
Puts them into a blocking queue (with consumer blocking on calls to dequeue until either a msg is added or a timeout reached
or
Notifies a listener with an event that contains the message.
Which of those two depends a lot on the consumer of those messages. Your code above would benefit from #1, though if the consumer is the UI thread then you should look at #2.
The protocol seems to be half-duplex so rewriting it with synchronous calls to Write/Readline seems to be the simplest way to handle it.

Reliably identifying and tracking Asterisk calls using C# and Aster.NET

I have been building a WinForms desktop application using C# that interfaces with Asterisk using Aster.NET (formerly/forked from Asterisk.NET). We're having real trouble reliably identifying and tracking calls that are related to an individual extension/user.
The problem we're having is due to the unpredictable/fuzzy nature of the events fired/triggered by Asterisk, with them being massively variable depending on how the call is routed before it hits an extension.
For example, the event sequence/format is different when: a call hits an IVR before getting blind transferred; if a call hits an IVR before it is attended transferred; if a call goes direct to the user's extension.
This is further hampered by the way that Asterisk tracks each side of the call using a different Unique ID (e.g. the incoming side of the call has a different UID than the received side of the call). Whilst we've managed to account for that in the (subsequently ugly!) code, we're still hitting issues with accounting for the different routing paths the call can take.
As such, I'm looking for any advice on how we can do the following:
Reliably identify an incoming call to a user's extension
We need to be able to identify the extension being called and the originating caller ID (after either a blind or attended transfer and direct call from external)
Reliably track the Unique ID for that incoming call as it's used to link to the call recording
Reliably identify an outgoing call from a user's extension
With the same caveats as above in mind
As it stands at the minute we have an extremely complex chain of event handlers that operate differently dependent on the 'current state' of the app.
To give one example: if we detect a NewStateEvent with a ChannelState of 6 ('Up'), we check if there is an ongoing call in process and that the UIDs match, and if so then the current call has been answered. If the UIDs don't match, but other factors do (e.g. channel, connectedlinenum, etc), then we pick this up as being the 'other side' of the call (i.e. the receiving or incoming side).
I'm not sure if the problem lies with the API or with AMI - but whichever it is it's causing us some real headaches.
Any advice greatly appreciated.
Is it possible for you to update to Asterisk 12? The channel names in AMI are now stable in Asterisk 12.
https://wiki.asterisk.org/wiki/display/AST/AMI+v2+Specification
i'm using package Aster.NET in c# . firstly install latest package of aster.net
than check that code .this code work perfect for me .
manager = new ManagerConnection(address, port, user, password);
manager.UnhandledEvent += new ManagerEventHandler(manager_Events);
manager.NewState += new NewStateEventHandler(Monitoring_NewState);
try
{
// Uncomment next 2 line comments to Disable timeout (debug mode)
// manager.DefaultResponseTimeout = 0;
// manager.DefaultEventTimeout = 0;
manager.Login();
if (manager.IsConnected())
{
Console.WriteLine("user name : " + manager.Username);
Console.ReadLine();
}
}
catch (Exception ex)
{
Console.WriteLine("Error connect\n" + ex.Message);
manager.Logoff();
Console.ReadLine();
}
void manager_Events(object sender, ManagerEvent e)
{
Console.WriteLine("Event : " + e.GetType().Name);
}
void Monitoring_NewState(object sender, NewStateEvent e)
{
string state = e.State;
string callerID = e.CallerId;
Console.WriteLine("caller num ...", e.CallerIdNum);
//Console.WriteLine("state =", state);
//Console.WriteLine("callerID =", callerID);
if ((state == "Ringing") | (e.ChannelState == "5"))
{
Console.WriteLine("hello rining your phone now ...");
String connectedLineNum;
String connectedLineName;
Dictionary<String, String> attributes = e.Attributes;
attributes.TryGetValue("connectedlinenum", out connectedLineNum);
attributes.TryGetValue("connectedlinename", out connectedLineName);
// "callerID" - called phone number
// "connectedLineNum" - calling phone number
// CallIn. Incoming call
}
else if ((state == "Ring") | (e.ChannelState == "4"))
{
Console.WriteLine("hello out going your call ...");
// CallOut. Outcoming call
}
else if ((state == "Up") | (e.ChannelState == "6"))
{
String connectedLineNum;
String connectedLineName;
Dictionary<String, String> attributes = e.Attributes;
attributes.TryGetValue("connectedlinenum", out connectedLineNum);
attributes.TryGetValue("connectedlinename", out connectedLineName);
// "callerID" - called phone number
// "connectedLineNum" - calling phone number
// human lifted up the phone right no
Console.WriteLine("human lifted up the phone...");
}
}

SQL Server2008: BeginExecuteNonQuery / EndExecuteNonQuery Problem

I have a stored procedure, which writes a backup of a specific database. I call this SP in a C# / Windows Forms application asynchrounously. Here is the code snipped:
IAsyncResult result = command.BeginExecuteNonQuery();
while (!result.IsCompleted)
{
System.Threading.Thread.Sleep(1000);
...
}
command.EndExecuteNonQuery(result));
After some time the program leaves the loop, because IsCompleted = true and calls EndExecuteNonQuery.
The problem now is, that the Job is still busy and EndExecuteNonQuery is blocked!
This causes a server timeout after some minutes.
It seems that the IsCompleted value is not consistent respectively what's wrong with IsCompleted?
How can I achieve that my program recognizes the "real job status"?
Make sure your stored procedure does not print anything and has no count reports (SET NOCOUNT ON). Async TDS calls call back at the very first packet sent by the server, but this packet might be a intermediate result (as in 1 row updated) and happen long, long before the actual completion. Does this suck? Yes. Can you do anything about it? No.
As a side note, is it infinitely more efficient to just pass a callback to the BeginExecute(...):
// Set form's state to 'executing',
// eg. Button.Enabled = false; label.Text = 'Executing';
command.BeginExecuteNonQuery((asyncstate)=>
{
try
{
command.EndExecuteNotQuery();
}
catch(SqlException ex)
{
...
}
// Reset the form's state to 'Ready'
Invoke (()=>
{
// eg. Button.Enabled = true; label.Text = 'Ready';
}
}

Categories