Class LgxProbe
- java.lang.Object
-
- com.automation_pros.odva.logix.LgxProbe
-
- All Implemented Interfaces:
CipReplyConsumer
public class LgxProbe extends java.lang.Object implements CipReplyConsumer
Implementation of Rockwell's Data Access manual's tag discovery process. With helpers to construct the various requests and to process responses. The entire probe process is kicked off by supplying a UCMM message processor instance and a route path. A CompletableFuture delivers the results.The manual describing the tag discovery process, data type decoding, and the tag read/write services is publicly available:
Note that Micro8xx controllers implement the global tag enumeration part of this procedure, without any support for the GetAttributeList service or templates. GetAttributeSingle is supported, but only for Class Attributes of Symbol Class 0x6b. That means dimensions for controller tags must be obtained during the GetInstanceAttributeList sequence.
While not declared, Micro8xx controllers permit tag accesses to items that aren't enumerated by this procedure, using normal encodings of ANSI symbols and member segments in the application path. Only leaf nodes of structures and arrays are accessible.
The manual describing Micro8xx support (appendix D in particular) is also publicly available:
Progress Listeners may be attached before probe start and will be called as each complete query is received (except the last). The progress object points to the results obtained to that point.
The procedure may be tweaked to exclude system tags/types and/or exclude program tags. The tag enumeration pass can also be tweaked to obtain tag attributes 3, 5, 7, 10, and 11. These options are set in the constructor.
After probe completion, this object may be used to construct tag read and write requests and decode their responses.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interface
LgxProbe.LgxProbeListener
Listeners added to this probe object will receive reports after each message is received, except the last, which will be delivered to the future.
-
Field Summary
Fields Modifier and Type Field Description protected boolean
abort
protected boolean
abortEqual
protected int[]
attrsGIAL
protected int
capacity
protected int[]
changeManagement
protected boolean
checkMicro8xx
protected boolean
doSymbolGAL0
protected java.util.concurrent.CompletableFuture<LgxProbeReport>
future
protected int
idxA1011
protected int
idxA35
protected int
idxA7
protected int
idxA8
protected int
idxA9
protected java.util.Set<LgxProbeReport.LgxProbedProgram>
incompletePrograms
While probing, contains those programs that have not been scanned for program-local tags.protected java.util.Map<java.lang.Integer,java.util.Set<LgxProbeReport.LgxProbedTag>>
incompleteTags
While probing, contains those tags that reported any array dimensions that have not yet been retrieved.protected java.util.Set<LgxProbeReport.LgxProbedType>
incompleteTypes
While probing, hold types that have had their basic attributes retrieved, but do not yet have a recursively complete member list.protected int
lastInstance
protected java.util.List<LgxProbe.LgxProbeListener>
listeners
Holds the list of registered progress listenersprotected java.io.StringWriter
log
protected int
maxInstance
static CipPath
Micro8xxChgMgmt
static CipPath
Micro8xxMaxInst
protected CipReplyConsumer
multipleConsumer
protected java.util.Map<java.lang.String,LgxProbeReport.LgxProbedProgram>
namedPrograms
protected java.util.Set<java.lang.Integer>
neededTypes
While probing, holds structure IDs that are used by any tag or other template member but are not yet probed.protected java.util.LinkedList<GetAttrListReq>
programGALs
While probing controller tags, construct GALs to obtain the max instance number of any programs encountered, so all program tag scans can show progress.protected java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedProgram>
programs
Contains all tag-like objects returned in a GIAL response from the target's Symbol class that refer to Programs.protected int
receivedCount
protected java.util.concurrent.LinkedBlockingDeque<CipRequest>
requestQueue
protected CipPath
route
boolean
scanPrograms
protected java.lang.Thread
sender
protected LgxProbeReport
skipChgManagement
static org.slf4j.Logger
sLogger
boolean
strictTags
Scan settings.protected java.util.Map<java.lang.Integer,java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedTag>>
tags
Contains all tags and tag-like objects returned in a GIAL response from the target's Symbol Class.protected int
tplReadClip
protected java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedType>
types
Contains all structured types that have at least their basic attributes.protected BaseDataType<?>[]
typesGIAL
protected CipMsgProcessor
ucmm
boolean
verbose
-
Constructor Summary
Constructors Constructor Description LgxProbe()
Common options for common modern Logix processors.LgxProbe(boolean verbose)
Get everything possible, optionally verbose.LgxProbe(boolean strictTags, boolean scanPrograms, boolean allTypes, boolean verbose, boolean getA35, boolean getA7, boolean deferA8, boolean getA9, boolean getA1011)
An instance of this class manages the series of requests need to obtain tag names and datatype details from a Logix processor, using the procedure documented in the public Data Access Manual:
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description protected void
_accept(CipReply reply)
void
accept(CipReply reply)
void
addListener(LgxProbe.LgxProbeListener listener)
protected void
addLog(java.lang.String s)
protected boolean
conditionalLogException(CipReply reply)
protected LgxProbeReport
constructReport()
protected CipRequest
determineNext()
protected CipRequest
handleChgMgmtGAL(CipReply reply, GetAttrListReq gal)
protected CipRequest
handleGAL(CipReply reply, CipRequest req)
The Get Attribute List service is used to obtain array dimensions of tags and to obtain critical attributes of data types.protected CipRequest
handleGAS(CipReply reply, CipRequest gas)
protected CipRequest
handleGIAL(CipReply reply, CipRequest req)
Get Instance Attribute List Service is only used to read tag names/symbol type codes from the Symbol Class (0x6b).protected CipRequest
handleTagGAL(CipReply reply, GetAttrListReq gal, LgxProbeReport.LgxProbedTag pt)
protected CipRequest
handleTemplateRead(CipReply reply, CipRequest req)
Template Read Service is only used to read data type details (name, members) from the Template Class (0x6c).protected CipRequest
handleTplGAL(CipReply reply, GetAttrListReq gal, int objinst)
protected void
logException(java.lang.Throwable t)
protected CipRequest
makeGIAL(java.lang.String program, int instance)
protected CipRequest
makeTemplateRead(CipPath target, int offset, int targetLen)
protected static java.util.List<LgxProbeReport.LgxProbedProgram>
programSnap(java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedProgram> source, java.util.Map<java.lang.Integer,java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedTag>> tags)
protected java.lang.String
resetLog()
protected void
send(CipRequest bare)
void
setSkipChgMgmt(LgxProbeReport priorReport)
The probe sequence can be terminated early when the request for the change management information yields the same value(s) as recorded in the report supplied here.java.util.concurrent.CompletableFuture<LgxProbeReport>
start(CipMsgProcessor mp, CipPath route)
Actual message traffic begins when an UnConnected Message Manager port is supplied, along with a route path to the target processor (through the port).protected static java.util.List<LgxProbeReport.LgxProbedTag>
tagSnap(java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedTag> source)
protected static java.util.List<LgxProbeReport.LgxProbedType>
typeSnap(java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedType> source)
-
-
-
Field Detail
-
sLogger
public static final org.slf4j.Logger sLogger
-
tags
protected java.util.Map<java.lang.Integer,java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedTag>> tags
Contains all tags and tag-like objects returned in a GIAL response from the target's Symbol Class. The outer map is the instance of the program object within the Symbol Class, or zero for global tags.
-
programs
protected java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedProgram> programs
Contains all tag-like objects returned in a GIAL response from the target's Symbol class that refer to Programs. Programs must be probed with an addition GIAL sequence to identify Program-local tags.
-
namedPrograms
protected java.util.Map<java.lang.String,LgxProbeReport.LgxProbedProgram> namedPrograms
-
incompleteTags
protected java.util.Map<java.lang.Integer,java.util.Set<LgxProbeReport.LgxProbedTag>> incompleteTags
While probing, contains those tags that reported any array dimensions that have not yet been retrieved.
-
programGALs
protected java.util.LinkedList<GetAttrListReq> programGALs
While probing controller tags, construct GALs to obtain the max instance number of any programs encountered, so all program tag scans can show progress.
-
incompletePrograms
protected java.util.Set<LgxProbeReport.LgxProbedProgram> incompletePrograms
While probing, contains those programs that have not been scanned for program-local tags.
-
neededTypes
protected java.util.Set<java.lang.Integer> neededTypes
While probing, holds structure IDs that are used by any tag or other template member but are not yet probed.
-
incompleteTypes
protected java.util.Set<LgxProbeReport.LgxProbedType> incompleteTypes
While probing, hold types that have had their basic attributes retrieved, but do not yet have a recursively complete member list.
-
types
protected java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedType> types
Contains all structured types that have at least their basic attributes.
-
listeners
protected java.util.List<LgxProbe.LgxProbeListener> listeners
Holds the list of registered progress listeners
-
strictTags
public final boolean strictTags
Scan settings.
-
scanPrograms
public final boolean scanPrograms
-
verbose
public final boolean verbose
-
attrsGIAL
protected final int[] attrsGIAL
-
typesGIAL
protected final BaseDataType<?>[] typesGIAL
-
idxA35
protected final int idxA35
-
idxA7
protected final int idxA7
-
idxA8
protected final int idxA8
-
idxA9
protected final int idxA9
-
idxA1011
protected final int idxA1011
-
ucmm
protected transient CipMsgProcessor ucmm
-
route
protected transient CipPath route
-
capacity
protected transient int capacity
-
tplReadClip
protected transient int tplReadClip
-
future
protected transient java.util.concurrent.CompletableFuture<LgxProbeReport> future
-
sender
protected transient java.lang.Thread sender
-
requestQueue
protected transient java.util.concurrent.LinkedBlockingDeque<CipRequest> requestQueue
-
log
protected transient java.io.StringWriter log
-
changeManagement
protected transient int[] changeManagement
-
doSymbolGAL0
protected transient boolean doSymbolGAL0
-
checkMicro8xx
protected transient boolean checkMicro8xx
-
lastInstance
protected transient int lastInstance
-
maxInstance
protected transient int maxInstance
-
receivedCount
protected transient int receivedCount
-
abort
protected transient volatile boolean abort
-
abortEqual
protected transient volatile boolean abortEqual
-
skipChgManagement
protected transient LgxProbeReport skipChgManagement
-
multipleConsumer
protected final CipReplyConsumer multipleConsumer
-
Micro8xxMaxInst
public static CipPath Micro8xxMaxInst
-
Micro8xxChgMgmt
public static CipPath Micro8xxChgMgmt
-
-
Constructor Detail
-
LgxProbe
public LgxProbe()
Common options for common modern Logix processors.
-
LgxProbe
public LgxProbe(boolean verbose)
Get everything possible, optionally verbose.- Parameters:
verbose
-
-
LgxProbe
public LgxProbe(boolean strictTags, boolean scanPrograms, boolean allTypes, boolean verbose, boolean getA35, boolean getA7, boolean deferA8, boolean getA9, boolean getA1011)
An instance of this class manages the series of requests need to obtain tag names and datatype details from a Logix processor, using the procedure documented in the public Data Access Manual:Probing doesn't start until the .start() method is called, supplying a UCMM and a route path. Callers should attach a listener, if desired, before calling .start(). If any listener is attached, the log will be delivered piecemeal with the interim reports.
- Parameters:
strictTags
- When scanning, strictly discard tags as directed in the Data Access Manual. When false, all non-tag elements other than Programs will be included in the reported lists of tags.scanPrograms
- When scanning controller tags, capture the entries for Programs, and then scan them for tags, too.allTypes
- Instead of scanning only template types used by tags, probe all 4095 instance numbers.verbose
- Log all requests sent and replies received.getA35
- Include address attributes 3 and 5 in the tag enumeration.getA7
- Include element size attribute 7 in the tag enumeration.deferA8
- Omit array dimensions from tag enumeration. Tags with dimensions will be probed with GAL seperately. Not supported by Micro8xx.getA9
- Include CIP Safety boolean attribute 9 in the tag enumeration.getA1011
- Include attributes 10 and 11 in the tag enumeration to determine if the tag is readonly.
-
-
Method Detail
-
tagSnap
protected static java.util.List<LgxProbeReport.LgxProbedTag> tagSnap(java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedTag> source)
-
programSnap
protected static java.util.List<LgxProbeReport.LgxProbedProgram> programSnap(java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedProgram> source, java.util.Map<java.lang.Integer,java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedTag>> tags)
-
typeSnap
protected static java.util.List<LgxProbeReport.LgxProbedType> typeSnap(java.util.Map<java.lang.Integer,LgxProbeReport.LgxProbedType> source)
-
addListener
public void addListener(LgxProbe.LgxProbeListener listener)
-
setSkipChgMgmt
public void setSkipChgMgmt(LgxProbeReport priorReport)
The probe sequence can be terminated early when the request for the change management information yields the same value(s) as recorded in the report supplied here. If there's a match, the report given here is delivered to the CompletableFuture instead of a new report.ControlLogix and CompactLogix use an array of five values. Micro8xx uses a single value.
- Parameters:
priorReport
- Complete previous report to compare against.
-
addLog
protected void addLog(java.lang.String s)
-
logException
protected void logException(java.lang.Throwable t)
-
conditionalLogException
protected boolean conditionalLogException(CipReply reply)
-
resetLog
protected java.lang.String resetLog()
-
constructReport
protected LgxProbeReport constructReport()
-
send
protected void send(CipRequest bare)
-
start
public java.util.concurrent.CompletableFuture<LgxProbeReport> start(CipMsgProcessor mp, CipPath route)
Actual message traffic begins when an UnConnected Message Manager port is supplied, along with a route path to the target processor (through the port). Execution proceeds asynchronously via a dedicated thread.Progress reports are delivered to listeners as responses are received, except when assembling fragments of a data type template definition.
- Parameters:
mp
- This message processor instance must be a UnConnected Message Manager. Typically, it will be an instance ofTcpConx
, though it could also be an implementation ofAbstractPort
.route
- The route may be null or empty if connecting to a target processor's built-in ethernet port.- Returns:
- The completable future that will receive the final LgxProbeReport. Use of the .whenComplete() method to attach a handler is recommended.
-
accept
public void accept(CipReply reply)
- Specified by:
accept
in interfaceCipReplyConsumer
-
makeGIAL
protected CipRequest makeGIAL(java.lang.String program, int instance)
-
makeTemplateRead
protected CipRequest makeTemplateRead(CipPath target, int offset, int targetLen)
-
determineNext
protected CipRequest determineNext()
-
_accept
protected void _accept(CipReply reply)
-
handleGIAL
protected CipRequest handleGIAL(CipReply reply, CipRequest req)
Get Instance Attribute List Service is only used to read tag names/symbol type codes from the Symbol Class (0x6b). Per the Logix Data Access manual. It can have large responses, so is never placed in a multiple-service request. It can report error code 6 along with a payload when more records are available after the last instance in the payload.When processing program tags, any error other than code 6 will remove the program from the set of incomplete programs.
This routine is only called from the outermost .accept() method.
- Parameters:
reply
- The complete reply object, typically with payload.req
- The original request object. Used to distinguish between queries against the list of controller tags versus against a particular program's tags.- Returns:
- A continuation request if this reply was code 6. Null if the list is complete.
-
handleTemplateRead
protected CipRequest handleTemplateRead(CipReply reply, CipRequest req)
Template Read Service is only used to read data type details (name, members) from the Template Class (0x6c). Per the Logix Data Access manual. It can have large responses, so is never placed in a multiple-service request. It can report error code 6 along with a payload when more bytes are available beyond the end of the payload.Any error other than code 6 will remove the data type from the set of incomplete types.
This routine is only called from the outermost .accept() method.
- Parameters:
reply
- The complete reply object, typically with payload.req
- The original request object. Used to recover the byte offset into definition and the definition length requested. The latter may be less than the ideal in some cases (reduced for certain errors).- Returns:
- A continuation request if this reply was code 6. Null if the data type is complete.
-
handleGAL
protected CipRequest handleGAL(CipReply reply, CipRequest req)
The Get Attribute List service is used to obtain array dimensions of tags and to obtain critical attributes of data types. All of its uses have known reply sizes, so can be combined efficiently into multiple service requests.The scan algorithm can yield a solo GAL to send directly to the UCMM, so this routine may be called by the primary .accept() method or by the CipReplyConsumer dedicated to requests embedded in a multiple service request.
- Parameters:
reply
-req
-
-
handleTagGAL
protected CipRequest handleTagGAL(CipReply reply, GetAttrListReq gal, LgxProbeReport.LgxProbedTag pt)
-
handleTplGAL
protected CipRequest handleTplGAL(CipReply reply, GetAttrListReq gal, int objinst)
-
handleGAS
protected CipRequest handleGAS(CipReply reply, CipRequest gas)
-
handleChgMgmtGAL
protected CipRequest handleChgMgmtGAL(CipReply reply, GetAttrListReq gal)
-
-