In fact, there is in v2.6.14. It is a new attribute on a tag that gets the connection status from the PLC connection:
3.
Connection Status Attribute - Added
connection_status attribute. Only get, no set. All PLC types.
- PLCTAG_CONN_STATUS_UP = 0 -- Connected and ready for operations
- PLCTAG_CONN_STATUS_DOWN = 1 -- Not connected
- PLCTAG_CONN_STATUS_DISCONNECTING = 2 -- In process of disconnecting
- PLCTAG_CONN_STATUS_CONNECTING = 3 -- In process of connecting
- PLCTAG_CONN_STATUS_IDLE_WAIT = 4 -- Waiting to reconnect after idle disconnect
- PLCTAG_CONN_STATUS_ERR_WAIT = 5 -- Waiting to reconnect after error
- Added idle timeout tests to CI and real hardware tests.
I have not yet made a "PLC" object. I think it is coming, but the current tag model is not a great fit for it. If I add it the "right" way, it would require some fairly significant API updates or additions and I am still trying to figure out how to avoid breaking existing, working code. Backward compatibility is very, very important for libplctag users. You should be able to take code developed with v2.1.0 and drop in 2.6.15 and have it just work.
The closest I have come so far is possibly adding to the API (this is very, very preliminary, not even a sketch!):
dev = plc_tag_open_device(... device attribute string ...);
status = plc_tag_get_int_attribute(dev, "connection_status", PLCTAG_CONN_STATUS_DOWN);
num_tags = plc_tag_get_int_attribute(dev, "tag_count", 0);
tag = plc_tag_open_device_tag(dev, "name=myNiftyKeenTag[42]"); /* what about element count? */
??? = plc_tag_get_tag_metadata(dev, "myNiftyKeenTag[42]"); /* what should ??? be? It should be accessible with existing API */
??? = plc_tag_open_device_tag(dev, "name=myNiftyKeenTag[42]&type=metadata",???);
??? = plc_tag_get_tag_metadata(tag);
/* or maybe by name? */
int32_t tag_type = plc_tag_get_tag_type(dev, "myNiftyKeenTag"); /* returns PLCTAG_TAG_TYPE_ARRAY */
int32_t element_type = plc_tag_get_tag_type(dev, "myNiftyKeenTag[0]"); /* PLCTAG_TAG_TYPE_I32 */
There are other ideas that involve API additions that are not at all compatible with the existing functions. They are much more orthogonal and coherent, but they require a very different model of use.
The most important point is to make users able to slowly adopt new API functions and types without breaking any existing code.
Questions I am trying to answer:
- is it possible to use the existing tag API functions with devices via special tag names?
- what kind of format should tag metadata be in? Binary? JSON? YAML? TOML? Bespoke?
- if we have device tags, should they be able to have callbacks? If so, how would that work as there could be many threads with the same tag name that need callbacks when the device connection changed state (for example)?
- how can we iterate down the type tree/element tree of an aggregate tag like an array or a UDT/struct?
- how does Modbus fit into this?
- what about full mapping of tag definitions so that each part can be easily grabbed?
- what is the overhead of parsing a string each time we do a read or write? Is it low enough that we can have an API that just uses strings for the tag name/path?
etc.
Best,
Kyle