running libserialport in any event loop - serial-port

I am trying to integrate libserialport library to a solution which can use poll, libev and libuv.
while its relatively easy to get the fd for the serial port file from libserialport and watch it using libev or libuv,
uv_poll_init(loop, &poller, serial_port_fd);
uv_poll_start(&poller, UV_READABLE /*| UV_PRIORITIZED*/, cb);
I do not know how to get it working using the default loop using poll.
the main loop is like:
while(!interrupted){
interrupted = service_one_loop();
//// THIS IS ONE PLACE TO poll (serial_port_fd) CODE and call callback function for serial
}
Is there any other way? Something like :
while(!interrupted){
interrupted = service_one_loop();
read_size = sp_nonblocking_read(machine_port, read_buffer, read_buffer_size);
if (read_size >= 0) {
cb();
}
}
Thanks for helping out in advance.

Related

watchkit: sleep -- can the isIdleTimer be changed/disabled?

I'm looking for an equivalent to the following iOS option: UIApplication.shared.isIdleTimerDisabled = true
That is, I'd like my Watch application to stay alive longer than the quick "sleep"/idle time that gets triggered when you don't move your wrist.
Its not perfect -- the watch will still sleep with inactvity, but this extension does slow it down by tricking the watch do ignore a 'wrist-down' or 'wrist-move' motion: Add the WKExtension inside one of your #IBActions:
#IBAction func mySlidefunction(){
// ... etc ...
WKExtension.shared().isAutorotating = true;
// ... etc ...
}

Pause/Stop AjaxDataSource Bokeh Stream

I am able to set up my graph for streaming just fine. Here's the initialization:
self.data_source = AjaxDataSource(data_url='my_route',
polling_interval=1000, mode='append', max_size=300)
Now I want to 'pause' the polling of the AjaxDataSource. I couldn't find a way to do this in the documentation. I'm NOT running a bokeh server, so bokeh server solutions I am unable to use.
I came up with one possible solution: just return empty data set to the function that is appending the data via AjaxDataSource. So in the example above, the my_route function would look something like this:
def my_route:
if not self.is_paused:
data = normal_data_to_graph
else:
data = []
return data
Once you set the polling_interval = None in Python, it will not request it. In CustomJS, you can start the paused request. Here, the source is an AJaxDataSource instance.
source.polling_interval = 1000; // the interval you want
source.intialized = false;
source.setup();

Recovering from ComPort drop-out

D5-pro:
Using TurboPower APro and the ComPort and Terminal Components with USB Arduino Nano for a very basic Comms-Terminal. All works fine until I unplug the USB to simulate losing the Port. It all just hangs and will not restart without closing and restarting.
I cannot find an Event or process that is monitoring the Port status so I can gracefully shut the Port. I am able to prevent the Port being opened if it doesn't exist, but once opened and data streaming in, I seem to lose all access to it.
I also tried TComPort and Terminal by Dejan Crnila and it also does not stop gracefully either. It actually crashes and I have to use TaskManager to shut it all down.
Can someone please guide me with some code snippets that might give an indication that the port has gone missing. Or is there a better free Component for doing this.
Some modifications in the AwUser unit are required.
Add a new event for I/O errors.
TPortIOErrorEvent = procedure(CP : TObject; Error : Cardinal) of object;
property OnPortIOError: TPortIOErrorEvent read FOnPortIOError write FOnPortIOError;
Modify the TComThread.Execute method in the AwUser unit.
{Release time slice until we get a communications event}
if not WaitComEvent(CurrentEvent, #ComOL) then begin
if GetLastError = ERROR_IO_PENDING then begin
if GetOverLappedResult(CidEx,
ComOL,
Junk,
True) then begin
{WIN32 bug workaround: Apro gets the modem status bits
with a call (later) to GetCommModemStatus. Unfortunately,
that routine never seems to return either RI or TERI.
So, we note either EV_RING or EV_RINGTE here and later
manually merge the TERI bit into ModemStatus.}
if ((CurrentEvent and EV_RINGTE) <> 0) or
((CurrentEvent and EV_RING) <> 0) then
RingFlag := True;
{Read complete, reset event}
ResetEvent(ComOL.hEvent);
end else begin
{Port closed or other fatal condition, just exit the thread}
SetEvent(GeneralEvent);
CloseHandle(ComOL.hEvent);
H.ThreadGone(Self);
Exit;
end;
end else begin
Err := GetLastError; {!!! added code}
{ If we get an ERROR_INVALID_PARAMETER, we assume it's our }
{ use of ev_RingTe -- clear the flag and try again }
if (GetLastError = ERROR_INVALID_PARAMETER) and
(LastMask and EV_RINGTE <> 0) then begin
LastMask := DefEventMask and not EV_RINGTE;
SetCommMask(CidEx, LastMask);
end;
{!!! added code begin}
if (Err <> ERROR_INVALID_PARAMETER) and (Err>0) and Assigned(FOnPortIOError) then
FOnPortIOError(H.fOwner, Err)
{!!! added code end}
end;
end;
Add the similar code to "ProcessOutputEvent".
In the new event handler analyze the I/O error and close/re-open the port.

xmlhttp request in a node-red function node

Is it possible to make http GET requests from within a node-red "function" node.
If yes could somebody point me to some example code please.
The problem I want to solve is the following:
I want to parse a msg.payload with custom commands. For each command I want to make an http request and replace the command with the response of a HTTP GET request.
expl:
msg.payload = "Good day %name%. It's %Time% in the %TimeOfDay%. Time for your coffee";
The %name%,%TimeOfDay% and %Time% should be replaced by the content of a Get request to http://nodeserver/name,..., http://nodeserver/Time.
thnx Hardilb,
After half a day searching I found out that the http-node can also be configured by placing a node just before it setting the
msg.url = "http://127.0.0.1:1880/" + msg.command ;
msg.method = "GET";
I used the following code to get a list of commands
var parts = msg.payload.split('%'),
len = parts.length,
odd = function(num){return num % 2;};
msg.txt= msg.payload;
msg.commands = [];
msg.nrOfCommands = 0;
for (var i = 0; i < len ; i++){
if(odd(i)){
msg.commands.push(parts[i]);
msg.nrOfCommands = msg.nrOfCommands + 1;
}
}
return msg;
You should avoid doing asynchronous or blocking stuff in function nodes.
Don't try to do it all in one function node, chain multiple function nodes with multiple http Request nodes to build the string up a part at a time.
You can do this by stashing the string in another variable off the msg object instead of payload.
One thing to looks out for is that you should make sure you clear out msg.headers before each call to the next http Request node

Flex3 / Air 2: NativeProcess doesn't accepts standard input data (Error #2044 & #3218)

I'm trying to open cmd.exe on a new process and pass some code to programatically eject a device; but when trying to do this all I get is:
"Error #2044: Unhandled IOErrorEvent:. text=Error #3218: Error while writing data to NativeProcess.standardInput."
Here's my code:
private var NP:NativeProcess = new NativeProcess();
private function EjectDevice():void
{
var RunDLL:File = new File("C:\\Windows\\System32\\cmd.exe");
var NPI:NativeProcessStartupInfo = new NativeProcessStartupInfo();
NPI.executable = RunDLL;
NP.start(NPI);
NP.addEventListener(Event.STANDARD_OUTPUT_CLOSE, CatchOutput, false, 0, true);
NP.standardInput.writeUTFBytes("start C:\\Windows\\System32\\rundll32.exe shell32.dll,Control_RunDLL hotplug.dll");
NP.closeInput();
}
I also tried with writeUTF instead of writeUTFBytes, but I still get the error. Does anyone have an idea of what I'm doing wrong?.
Thanks for your time :)
Edward.
Maybe cmd.exe doesn't handle standardInput like a normal process.
You could try passing what you want to execute as parameters to the cmd process, rather than writing to the standard input
I think
cmd.exe /C "start C:\Windows\System32\rundll32.exe shell32.dll,Control_RunDLL hotplug.dll"
is the format to pass something as a parameter to cmd to execute immediately.
This site has an example of passing process parameters using a string vector:
http://blogs.adobe.com/cantrell/archives/2009/11/demo_of_nativeprocess_apis.html
Try it without the last line "NP.closeInput();"
See also:
http://help.adobe.com/en_US/as3/dev/WSb2ba3b1aad8a27b060d22f991220f00ad8a-8000.html
I agree with abudaan, you shouldn't need to closeInput().
Also, suggest you add a line break at the end of the writeUTFBytes() call, e.g.:
NP.standardInput.writeUTFBytes("start C:\\Windows\\System32\\rundll32.exe shell32.dll,Control_RunDLL hotplug.dll **\n**");
Lastly, I recommend you listen to other events on the NativeProcess, I use a block of code something like this:
NP.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onStdOutData);
NP.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onStdErrData);
NP.addEventListener(Event.STANDARD_OUTPUT_CLOSE, onStdOutClose);
NP.addEventListener(ProgressEvent.STANDARD_INPUT_PROGRESS, onStdInputProgress);
NP.addEventListener(IOErrorEvent.STANDARD_ERROR_IO_ERROR, onIOError);
NP.addEventListener(IOErrorEvent.STANDARD_INPUT_IO_ERROR, onIOError);
NP.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onIOError);
with the normal event handler functions that at least trace what they receive.
Best of luck - I've just spent a few hours refining NativeProcess with cmd.exe - its fiddly. But I got there in the end and you will too.

Resources