>>Message imported from previous forum - Category:ClearSCADA Software<< User: florian, originally posted: 2018-10-25 20:15:03 Id:300 This is a re-posting from the obsoleted (October 2018) "Schneider Electric Telemetry & SCADA" forum.
**_I've making a Simple Driver DDK driver which connects to a PLC via a .NET API._**
**_I have a number of questions about how to correctly use the DDK, which don't seem to be clearly answered by the "Creating a Driver with the Simple Driver Development Kit" guide, or the "Simple Driver Development Kit Reference" CHM file which ships with the DDK._**
**_I thought I might ask the questions here on the forum, so the answers are available to other people using the DDK._**
**_Here are the questions:_**
**_1. Because my driver just calls synchronous methods in a .NET assembly, I don't need to manage a socket or explicitly handle timeouts. But I do need to initialise a stateful .NET object which represents a connection to my target device, clean up that object when ClearSCADA disconnects, and re-create it when attempting to restore a failed connection. Should I be setting up and tearing down my channel's client object in OnConnect()/OnDisconnect() overrides, or in PerformConnect()/PerformDisconnect() overrides, or even OnDefine()/OnUnDefine()?_**
**_2. What's the difference between OnConnect() and PerformConnect(), anyway? When should I use one or the other?_**
**_3. What is my driver expected to do if the connection attempt fails? Should my OnConnect()/PerformConnect()/OnDefine() method throw exceptions? Or should it just call SetStatus() and set it to "Offline" or "Failed" or "FailedRetryDefine", perhaps with a message string?_**
**_4. If the connection is successfully established but fails later, what is the driver expected to do? I think the Channel is supposed to call SetStatus(Failed) rather than throw exceptions. Do I also need to SetStatus on the associated Scanners, or will that happen automatically when the Channel is marked as failed? Does my channel need to undefine its scanners, or will ClearSCADA manage the lifecycle of the scanners when the channel fails?_**
**_5. What's the expected trigger for attempting to reestablish a failed connection? Do I just wait for ClearSCADA to call OnDefine()/OnConnect()/PerformConnect() again? Or wait for OnPoll() to be called? Or should I attempt to re-establish the connection when OnScan() is called on a scanner linked to the failed Channel?_**
**_6. The documentation for the DriverScanner.OnTimeout() method says "You should call the base class if you find the timer id is not one of yours." Is there a specific range of uint values which are safe to use for my own timers? It's not clear which values ClearSCADA uses for its internal timers. I don't want to accidentally break an internal timer by defining a timer of my own with the same id._**
**_7. Same question for DriverChannel.OnExecuteAction(). The documentation says "You should call the base class if the transaction is not handled by your driver". What range of values for transaction ids are safe for me to use for my own custom transactions, so I don't risk masking one of ClearSCADA's internal driver action types?_**
**_8. On the channels and scanners, what's the difference between calling SetFailReason(), and calling SetStatus() with a "Failed" value and a string message?_**
**_9. Are there any diagrams avaiable which show the lifecycle of Channels and Scanners? I'm looking for schematic of their state machines, how the Channel and associated Scanner state machines interact, and what order the various methods will be called for the Channel and all its attached Scanners during startup and shut down. And, particularly, what ClearSCADA will do if various parts of the startup sequence fail, or the channel or scanner calls "SetFailed" or "SetStatus(Failed)". Do I ever have to call OnUndefine or OnDisconnect manually or does ClearSCADA ensure that these methods get called when things fail?_**
bevanweiss: I can only answer a few of these... (it's been a while since I was looking through the DDK) 1. PerformConnect() sounds like the correct method to override here. 'You should override this method if your driver needs to use its own connect code. If your driver uses the built-in serial, you should call the base class'. I think this fits your implementation. 2. OnConnect() is like a hook that is called when the channel itself is connected (i.e. after PerformConnect() returns a success status) 3. Yes, on failure you should SetStatus() and include a message string with SetFailReason(). 4. OnPoll() should throw an Exception here. OnPoll() is supposed to be the only thing which checks and drops channels I believe. 5. OnConnect() would be the appropriate method here I believe. 6. I'm not sure on the ID here, however... I would request a range of UIDs from Schneider for your driver development, you should already have done this for assigning them to OPC property ID.. I'd just use a spare ID from this. 7. This is definitely the OPC ID that you should get from Schneider.. 8. I believe SetStatus(status, failmessage) is a bit newer, and does replace the combo of SetStatus(), SetFailReason() 9. The state machine part... not sure how much info you'd get with this. But when it comes to the OnUndefine / OnDisconnect. You shouldn't have to call these yourself. They are hooks that trigger when the appropriate event within ClearSCADA occurs (i.e. OnUndefine will be called when configuration is modified and saved...
You should take all of this with a grain of salt however..
**_Well, I defined overrides for PerformConnect() and PerformDisconnect() - and they never get called by the driver framework, even when I disable and enable the channel. So, I'm still pretty confused about the purpose of those methods and the conditions under which they get invoked._**
**_I'm still having trouble with figuring out how to correctly indicate failures to the framework, too. I've got my target PLC turned off, so none of my connection attempts are working. In my OnConnect method, when I catch the exception from my failed connection attempt, I call SetStatus(SourceStatus.Failed, "Error message")._**
**_But as soon as I return from OnConnect without actually throwing an exception, ClearSCADA sets the channel status to "Online" by itself._**
**_I've put breakpoints on every reference to SourceStatus.Online or ServerStatus.Online in my code, and I'm not hitting any of them, but the channel is still getting set to "Online" somehow._**
bevanweiss: I would expect that given you're using a custom channel you would have overridden (on the channel): * OnDefine * OnUnDefine * OnValidateConfig * OnPoll (which should test the connection and throw an exception on error) * OnConnect (if you need to do stuff after connection is established) * OnDisConnect (if you need to do stuff after connection is disconnected) * OnExecuteAction (because you will generally want some custom actions available) * PerformConnect * PerformDisconnect * PerformWrite * PerformRead * PerformPurge * IsPortConnected
And then for your scanner you'd override: * OnDefine * OnUnDefine * OnValidateConfig * OnScan * OnControl (if you are allowing controls from points connected to the scanner) * OnExecuteAction * OnUpdateStatistics * CheckReply
We've really only done basic serial port comms using this DDK... so unfortunately I'm not speaking from experience on the PerformConnect etc overrides. But it's certainly what the DDK is alluding to (whether that matches reality may be a different story)