ATDDriverSettings initialization issue

Ignition 7.6.5rc2 and the associated SDK.

I create a driver based on the AbstractTagDriverExample.
Here are the device parameters :
[attachment=2]ping1.png[/attachment]

When created device parameters aren’t correctly saved.
(for example : NumberOfThread)
[attachment=1]ping2.png[/attachment]
[attachment=0]ping3.png[/attachment]

If I change the value and save again, it’s Ok.
I don’t understand why :scratch: !!!
I’ve tried to delete device, unload module, restart GW and reload module, recreate device…
Same issue.

ATDDriverSettings.properties

DriverPingCategory=ParametersDriverPing

RootAddress.Name=RootAddress
RootAddress.Desc=IPv4 addresses beginning (Groups X.Y.Z)<br>[example : 192.168.1].

StartOfAddress.Name=StartOfAddress
StartOfAddress.Desc=IPv4 addresses beginning value for the last group<br>[value from 1 to 255]. 

EndOfAddress.Name=EndOfAddress
EndOfAddress.Desc=IPv4 addresses ending value for the last group<br>[value from 1 to 255].

PingTimeOutMs.Name=PingTimeOutMs
PingTimeOutMs.Desc=Ping TimeOut in Milliseconds

PingPeriodeSec.Name=PingPeriodeSec
PingPeriodeSec.Desc=Period in Seconds for Ping

NumberOfThread.Name=NumberOfThread
NumberOfThread.Desc=Number Of Thread to use to manage ping command<br>[value from 1 to 100].

NumberOfRetry.Name=NumberOfRetry
NumberOfRetry.Desc=Number Of Retry for ping command<br>[value from 1 to 10].

ListOfAddress.Name=ListOfAddress
ListOfAddress.Desc=List of IPv4 addresses separated by a comma.<br>[example : 192.168.1.1,192.168.1.2].<br><b>Leave "-" to use StartOfAddress/EndOfAddress parameters</b>

ATDDriverSettings.java

package com.byesapps.driverping.gateway.configuration.settings;

import simpleorm.dataset.SFieldFlags;

import com.inductiveautomation.ignition.gateway.localdb.persistence.Category;
import com.inductiveautomation.ignition.gateway.localdb.persistence.IntField;
import com.inductiveautomation.ignition.gateway.localdb.persistence.LongField;
import com.inductiveautomation.ignition.gateway.localdb.persistence.PersistentRecord;
import com.inductiveautomation.ignition.gateway.localdb.persistence.RecordMeta;
import com.inductiveautomation.ignition.gateway.localdb.persistence.ReferenceField;
import com.inductiveautomation.ignition.gateway.localdb.persistence.StringField;
import com.inductiveautomation.xopc.driver.api.configuration.DeviceSettingsRecord;

/**
 * Implements all functionality needed to save a device and its settings in the internal database.
 *
 */
public class ATDDriverSettings extends PersistentRecord {

	private static final long serialVersionUID = 1L;
	
	/**
	 * Needed so that the device record can be saved in the internal database.
	 */
	public static final RecordMeta<ATDDriverSettings> META = 
			new RecordMeta<ATDDriverSettings>(ATDDriverSettings.class, "ATDDriverSettings");
	
	/**
	 * Reference to parent DeviceSettingsRecord: holds items like Device Name setting and Enabled setting.
	 * These fields also appear in the General category section when creating a new driver in the Gateway.
	 */
	public static final LongField DEVICE_SETTINGS_ID = new LongField(META, "DeviceSettingsId", SFieldFlags.SPRIMARY_KEY);
	
	/**
	 * Needed to link a device settings record to the device record in the internal database.
	 */
	public static final ReferenceField<DeviceSettingsRecord> DEVICE_SETTINGS = new ReferenceField<DeviceSettingsRecord>(
			META,
			DeviceSettingsRecord.META,
			"DeviceSettings",
			DEVICE_SETTINGS_ID);
	
	@Override
	public RecordMeta<?> getMeta() {
		return META;
	}
	
	/**
	 * Settings specific to the ATDDriver- each one must be placed in a Category.
	 */
	//public static final IntField TAG_COUNT = new IntField(META, "TagCount", SFieldFlags.SMANDATORY);
	public static final StringField ROOTADDRESS = new StringField(META, "RootAddress", SFieldFlags.SMANDATORY);
	public static final IntField STARTOFADDRESS = new IntField(META, "StartOfAddress", SFieldFlags.SMANDATORY);
	public static final IntField ENDOFADDRESS = new IntField(META, "EndOfAddress", SFieldFlags.SMANDATORY);
	public static final IntField PINGTIMEOUTMS = new IntField(META, "PingTimeOutMs", SFieldFlags.SMANDATORY);
	public static final IntField PINGPERIODESEC = new IntField(META, "PingPeriodeSec", SFieldFlags.SMANDATORY);
	public static final IntField NUMBEROFTHREAD = new IntField(META, "NumberOfThread", SFieldFlags.SMANDATORY);
	public static final IntField NUMBEROFRETRY = new IntField(META, "NumberOfRetry", SFieldFlags.SMANDATORY);
	public static final StringField LISTOFADDRESS = new StringField(META, "ListOfAddress", SFieldFlags.SMANDATORY);
	
	
	/**
	 * Categories specific to the ATDDriver- each category appears below the General
	 * category in the Gateway when creating a new driver.
	 * 
	 * In this case, the displayKey below is referencing ATDDriverSettings.properties,
	 * which is located next to the Java file on the file system. You must put the actual
	 * category name into this file.
	 * 
	 * The order number determines the order in which multiple categories are displayed on the page.
	 */
	public static final Category EXAMPLE_CATEGORY = 
			new Category("ATDDriverSettings.DriverPingCategory", 1001).include(
					ROOTADDRESS,STARTOFADDRESS,ENDOFADDRESS,PINGTIMEOUTMS,PINGPERIODESEC,NUMBEROFTHREAD,NUMBEROFRETRY,LISTOFADDRESS);
	static {
		// Hides some generic ReferenceField settings that are not needed in our driver example.
		DEVICE_SETTINGS.getFormMeta().setVisible(false);
			
		ROOTADDRESS.setDefault("192.168.1");
		STARTOFADDRESS.setDefault(1);
		ENDOFADDRESS.setDefault(10);
		PINGTIMEOUTMS.setDefault(2000);
		PINGPERIODESEC.setDefault(30);
		NUMBEROFTHREAD.setDefault(2);
		NUMBEROFRETRY.setDefault(1);
		LISTOFADDRESS.setDefault("-");
	}
	
	/**
	 * Get the number of tags that will be exposed to the driver
	 * @return an int with the saved tag count
	 */
//	public int getTagCount(){
//		return getInt(TAG_COUNT);
//	}
//	
//	/**
//	 * Set the number of tags that will be exposed to the driver
//	 * @param tagCount an int that represents the tag count to save
//	 */
//	public void setTagCount(int tagCount){
//		setInt(TAG_COUNT, tagCount);
//	}
	
	public void setListOfAddress(String listOfAddress){
		if (listOfAddress.isEmpty()){
			listOfAddress = "-";
		}		
		setString(LISTOFADDRESS, listOfAddress);
	}

	public String getListOfAddress(){
		if (getString(LISTOFADDRESS).isEmpty()){
			return "-";	
		} else {
			return getString(LISTOFADDRESS);	
		}		
	}	
	
	public void setRootAddress(String racineAdresse){
		setString(ROOTADDRESS, racineAdresse);
	}

	public String getRootAddress(){
		return getString(ROOTADDRESS);
	}
	
	public int getStartOfAddress(){
		return getInt(STARTOFADDRESS);
	}	
	public void setStartOfAddress(int debutAdresse){
		if ((debutAdresse < 1) || (debutAdresse > 255)) {
//			if (debutAdresse > getEndOfAddress()) {
//				debutAdresse = getEndOfAddress();				
//			} else {
//				debutAdresse = 1;				
//			}
			debutAdresse = 1;
		}		
		setInt(STARTOFADDRESS, debutAdresse);
	}
	
	public int getEndOfAddress(){	
		return getInt(ENDOFADDRESS);
	}	
	public void setEndOfAddress(int finAdresse){
		if ((finAdresse < 1) || (finAdresse > 255)) {
			finAdresse = 1;
		}		
		setInt(ENDOFADDRESS, finAdresse);
	}
	
	public void setPingTimeOutMs(int pingTimeOutMs){
		if ((pingTimeOutMs < 200) || (pingTimeOutMs > 60000)) {
			pingTimeOutMs = 2000;
		}		
		setInt(PINGTIMEOUTMS, pingTimeOutMs);
	}

	public int getPingTimeOutMs(){
		return getInt(PINGTIMEOUTMS);
	}	

	public void setPingPeriodeSec(int pingPeriodeSec){
		if ((pingPeriodeSec < 1) || (pingPeriodeSec > 3600)) {
			pingPeriodeSec = 30;
		}		
		setInt(PINGPERIODESEC, pingPeriodeSec);
	}

	public int getPingPeriodeSec(){
		return getInt(PINGPERIODESEC);
	}
	
	public void setNumberOfThread(int numberOfThread){
		if ((numberOfThread < 1) || (numberOfThread > 100)) {
			numberOfThread = 1;		
		}
		setInt(NUMBEROFTHREAD, numberOfThread);
	}

	public int getNumberOfThread(){
		return getInt(NUMBEROFTHREAD);
	}

	public void setNumberOfRetry(int numberOfRetry){
		if ((numberOfRetry < 1) || (numberOfRetry > 10)) {
			numberOfRetry = 1;		
		}
		setInt(NUMBEROFRETRY, numberOfRetry);
	}

	public int getNumberOfRetry(){
		return getInt(NUMBEROFRETRY);
	}
	
	
}

Your code looks correct… and I can’t reproduce the issue here at all… so I’m not sure what your’e seeing :scratch:

You were right.
I changed the name of the table for the devices settings to work with a fresh configuration.
the trouble was probably due to the use of the same name for oldest driver test…