Jump to content

Stobber

Members
  • Posts

    213
  • Joined

  • Last visited

  • Days Won

    5

Everything posted by Stobber

  1. The error description from the log file is:
  2. When throwing an error from the API, could you add the SQLite error code to the error description? My client got error 402864 last night, and it took a lot of digging to figure out what that meant. The code doesn't resolve in the Explain Error dialog, and even if it did, I'm more interested in the code returned by the sqlite3 DLL because I use that code to search their documentation when troubleshooting.
  3. It's almost 2016. Can I serialize LabVIEW objects to a standard interchange format yet?
  4. FWIW, I'd stick to the Boolean. There's no reason to assume any other extensions would need to be mutually exclusive from the LV numeric extensions. An enum would enforce that exclusion. Same index, of course. I'm specifying the default value of the aggregated data structure. If I want all elements to have the same default values, then I'll either need an interface that lets me specify the element type of the array (instead of the array), or I'll have to use the "Initialize Array" prim.
  5. Is consensus among the original authors needed to act, or is there a public repo I can fork to add the feature?
  6. And that's that, huh? No interest in making it interoperable with the LV API by "supporting LV's extensions to JSON"?
  7. Any chance of adding support for Inf and NaN to this API? I want to move off of the native LV prims because of their rigidity with data type and missing items in a JSON stream, but I can't let go of their support for these DBL values. Maybe you can add a property node to the JSON Value class that sets whether or not to allow these values in numeric fields? Edit: Let me clarify, since playing with the API further shows that there is some support for those values. When I try this code on a stream that doesn't have the "updated period " field in its clusters, I don't get NaN out. I get the default value for the data type, instead.
  8. Sounds like you made the same discoveries I did through field testing! A FSM executes state-check logic on every "clock tick", so it's still synchronous error handling. I suspect you're usually aborting normal logic downstream of an error and letting your "error case" do its work before executing the intended logic again or changing state and executing other logic. This all follows what I think is the only realistic way to address errors in LV run-time logic: deal with them as close to the code that threw them as possible, so you have the "context" of that code available to your handler. And yes, providing a template for handling -- along with maybe a couple of very common generic handlers that get used all over, like "log and clear" -- is the only realistic way to spread error handling know-how to an entire team. Each handler has to be (at least somewhat) custom, so you can't reasonably expect to create an all-purpose error handler for direct reuse.
  9. I think we both chose avatars that fit our personalities nicely
  10. I'm not the one who decided to marry a dataflow language to an asynchronous execution model. Even a single BD with a couple of structures can break the damned paradigm.
  11. Which is why error handling should be synchronous!!!
  12. Who says a redesign has to bolt on fancy new features that hog memory or demand extra CPU cycles? A totally functional redesign might just look like removing the Boolean from the cluster and defining a standard set of tags for segmenting metadata in the string! Are you still clinging to the same computer you had when that dusty old copy of LV 7.1 was released? Memory and CPU have gotten so big/fast that architecting applications with async message-based processes basically comes for free these days.
  13. Frankly, I don't think error handling code will ever be effectively abstracted to a framework or set of reuse components. The appropriate handler for each error in a finished app is too dependent on the data structures and running logic of that particular piece of code. The best I think we could do for one another is to create tutorials with example code for people to learn from. It's the structure of the error cluster and the information it carries that stands to be improved. Standardizing what goes into the string would be nice, even if it's just a set of established tags or formatting that differentiates one section of data from another, so each team can embed whatever custom information they like without stomping on anyone else's. Defining a zero-allocation structure for memory-critical RT code would be really nice, too. I should finally to look through cref's slides from years ago...
  14. Back on-topic: (No worries, hooovahh!) I used and studied RyanK's CEH back when he published it. I found two major (IMO) problems with the approach: CEH handles errors asynchronously Based on my experience as an app developer, I believe error handling should be done synchronously. ("Handling" involves clearing an error and responding to it gracefully, even if that response is to ignore the error or translate it into other information like a "timed out" Boolean parameter.) If the error can't be handled sync, then it can be reported to a higher-level entity async for logging, display to an operator, or handling at a broader scope than the "thread" (LV loop) that threw the error and failed to handle it locally. Broad-scope handling actions in my RT apps often look like resetting the application's operating mode or forcing output signals to fail over to a safe state until the operator reviews and clears the critical error. I think ShaunR's suggestion of an "Error Event" has the same flaw: events are asynchornous in LV. What I think we need is an "Error Callback" so it's handled synchronously with context-sensitive dispatch of which handler to use. On that note... CEH is insensitive to context An error code has no context whatsoever. Error 7 ("File not found") might be safely ignored in some processes, but it might represent a critical failure in others. It gets thrown by native APIs that have nothing to do with file access, too, so you might not think to deifne a general-purpose handler for code 7 that addresses an unexpected API or app process. Errors should be handled as close to where they're thrown as possible, so the handling code can be written in the same design context as the code that generated the error.
  15. Two dusty threads from 2007 and 2009. I'll just lay this rug back down and walk away. There are probably more productive ways to occupy my spare time at work.
  16. I went mucking around inside General Error Handler.vi and am aghast at what I found. It seems like error definition is split between error code lookup (defined in error files) and extra information jammed into the description string using bracketed tags (like call chain and suggestions for handling the error). Why we're forced to handle specific error codes anyway is beyond me. There isn't any way of knowing which codes will be thrown by a given function, and many of the first 100 codes are reused in mysterious ways all over NI's APIs. (e.g. error 7 coming from a property node inside the VI that establishes an SMTP connection) Surely there's a better way to organize and transfer information about something having gone wrong? I realize that LV will always be dependent on returned error values from each function instead of cooler systems like exceptions, but there still seems to be a lot of opportunity for improving HOW those errors are encoded, decoded, and handled. Has anybody spent time thinking about this? Should I just put the rug back down and pretend I never looked under it?
  17. Edit: The screenshot I had attached didn't convert from seconds to days. Removing it. Edit2: Second screenshot had another bug. Fixed it, tested thoroughly, adding "final" version. Referencing Wikipedia: (https://en.wikipedia.org/wiki/Julian_day Here's an attempt at converting LV time to SQLite time for type REAL.
  18. I was mistaken when I said DBL should convert to Unix time in my bug report. It will still help me (and everyone who writes to a db using LV and reads from it using other tools/languages) to convert LV time to the correct format for whichever datatype is used when storing the value. Bind Timestamp (Real) should convert to Gregorian time Bind Timestamp (Text) should convert to ISO8601 Bind Timestamp should stay LV time, since it's a BLOB I'd like it if you added Bind TImestamp (Int) and wrote Unix time with that Edit: My use case is to write to the db using a LV app on cRIO, then read from it using modern data analysis and visualization tools. Using LV to display and analyze datalogs is like cooking dinner with a hammer and a campfire. So this fix will very much help me. Right now I'm using Bind Integer as a workaround.
  19. Rolf beat me to it. One addition: SQLite does have a defined epoch and constraints. Actually, it has several epochs depending on the datatype of each time value (see https://www.sqlite.org/datatype3.html#datetime ).Their implementation of helper functions that manipulate time using an old C library is described at the bottom of this page: http://www.sqlite.org/lang_datefunc.html Note that trying to use any of the library functions on that page will result in storing time as a string instead of the column affinity, unless you cast the returned value. Since your API provides access to SQLite from LV, as Rolf said, you have to change LV's understanding of time to match SQLite's. This allows any other APIs/apps to retrieve time from the db under the common (SQLite) definition so they can convert it to their own definitions.
  20. Bind Timestamp (Real).vi has a bug. It writes the LV timestamp (offset from 1/1/1904) instead of the Unix timestamp (1/1/1970). Non-LabVIEW applications reading the timestamp are getting bad values out of the db.
  21. http://zone.ni.com/reference/en-XX/help/371361L-01/lvhowto/creating_cond_disable_struc/
  22. I appreciate the tip on INSERT OR IGNORE, but I'm concerned about SELECT not working in a prepared statement because I intend to write more statements like it. I noticed that "Valid Statement" was FALSE....which is obviously untrue. Maybe it's an issue with executing against the Linux SO that NI distributes?
  23. I'm having trouble binding parameters to a SELECT statement. This is the statement I want to execute (including a valid param value): SELECT id FROM variable WHERE label = "BooleanTestVariable"; When I run that statement in my database viewer, it returns a row with id = 1. When I run my code (pictured below) with this string on Prepare.vi, no rows are returned by First Step.vi: SELECT id FROM variable WHERE label = ? I noticed that string values have to be quoted in Execute SQL.vi, so I tried that: SELECT id FROM variable WHERE label = "?" But it returns "Error 402884 occurred at datalogdb.lvlib:Define Test Variables.vi on "SELECT id FROM variable WHERE label = "?"" Possible reason(s): bind or column index out of range" What am I missing? My code:
  24. drjdpowell, that path ^^^ is the standard NI installation of SQLite3 on a cRIO target. (I'm using NI's opkg server to install the package.) Can you add that path as a default for the OS and targettype inside your API?
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.