Hello, while doing testing I noticed that the system.device.addDevice functionality isn’t included for “free” in the 8.3 API anymore when I call on it to add my custom device implementation. Having a look at the warning message, I’ve pieced together that my device extension point needs to implement defaultSettings, and that I need a public static final instance in my related device config. The device that gets created uses the settings in that instance, but I can’t seem to get it to use any of the device props that I feed into addDevice’s deviceProp arg. If someone could point me in the right direction I’d appreciate it, thanks.
I'm interested in this, too. (The prior implementation depended on internal DB column names.)
What does your settings/config object look like, and what are the keys you are using in the deviceProps
dictionary?
It looks like:
addDevice
internally calls into your meta and asks it for its default settings object,- Encodes those settings into a JsonObject.
- Any supplied kwargs from
addDevice
are merged into that object (using.
to delimit nested settings identifiers). - Those settings are then passed back to the extension point to validate
- The device is created
How would an extra resource file be added? Is there callout to handle keys that aren't direct members of the config object? How do drivers that need a list of OPC Item Paths handle this?
Can I say that I'm becoming less and less enamored with java record
types?
Hi Kevin,
I’m calling the following in the designer:
deviceProps = {
"snmphostname":"127.0.0.2",
"snmpport":9000
}
system.device.addDevice(deviceType="snmpv2", deviceName="mytest", deviceProps=deviceProps)
And this is part of what my config looks like:
public record SnmpV2DeviceConfig(Connectivity connectivity, Security security, Advanced advanced) {
public record Connectivity( @FormCategory("CONNECTIVITY") @Label("SNMP host name*") @FormField(FormFieldType.TEXT) @DefaultValue("localhost") @Required String snmphostname, @FormCategory("CONNECTIVITY") @Label("SNMP port*") @FormField(FormFieldType.NUMBER) @DefaultValue("161") @Required int snmpport){} }
@paul-griffith It looks like step 3 is what I was missing. The props should have been:
deviceProps = {
"connectivity.snmphostname":"127.0.0.2",
"connectivity.snmpport":9000
}
I was fiddling around with addDevice using a Mitsubishi device to make sure I wasn’t screwing up my Python scripting and it doesn’t appear I need to do the nesting with those properties? Is there something I’m not doing properly for our module? I’m referring to these properties: system.device.addDevice - deviceProps Listing | Ignition User Manual
First party device drivers get extra handling for backwards compatibility so that you don't have to do extra nesting. For a third party, you're going to have to specify that extra depth in the keys you pass.
The real solution here is going to be our first party scripting API that gives you C/R/U/D of all config resources and overlaps system.device.addDevice
entirely.
Hi @Kevin.Herron @paul-griffith I have some other questions related to this. I have a couple of config fields that I have marked as FormFieldType.SECRET. Is it possible to create a device through scripting if I have these fields? I’d bet reference secret config would be possible, but what about embedded secret config?
I don't think that's possible right now.
edit: created IGN-14421 for this. Not sure about timeline/priority.
Thanks Kevin. I dunno if it matters on your end, but I think this would also have ramifications for the REST API portion as well.
No, it's possible with the REST API right now.
Do you mean if I were to pass the secret in clear text to the REST API it should work? Or do you mean passing an Embedded type JSON object? I found if I created a device through the web gui and copied the Embedded JSON object generated in the config.json file, I could pass those creds through the REST API and that second device would connect. I didn’t try that with addDevice, but I’d imagine it’d be similar?
Edit: Hm, they do not. Looks like my validate method thinks I’m passing nothing.
You need to pass the embedded secret JSON object.
There is an endpoint at /data/api/v1/encryption/encrypt
(see http://localhost:8088/openapi#tag/encryption) you can use to create embedded secrets.
The system.device.addDevice
function has no idea what to do with either an actual SecretConfig nor a JsonObject that is an encoded SecretConfig. I think if you tried to pass it a String that happened to be encoded SecretConfig JSON it would be escaped and embedded in a JSON string value, not end up as a SecretConfig.
Good to know, thanks Kevin.
@paul-griffith Is there anywhere I can read up on that 1st party scripting API?
IA is the first party, and the implication is that the little backwards compatibility hacks are private because they are part of the scripting implementation. There's nothing to read up on and it's just not available to you or any other 3rd party.