I have a program block that I fire manually. Upon firing, I want it to create a StringWritable slot that has predefined facets.
I have included the code below.
I was originally only creating BStatusEnum and I was able to assign a enum range to it. When I converted the code to use BEnumWritable, it stopped working. I finally chose to use a seperate code block to test my code to eliminate any variables. Thus, I came up with the code below.
How do i change the facets of writable? I would like to do this upon creating the writable block.
public void onExecute() throws Exception
{
// Create the value you want to store
BValue slotValue = createStringWritable("HelloWorld");
// Define the enum range for facets
String[] range = {"Range1", "Range2"};
BFacets facets = BFacets.makeEnum(BEnumRange.make(range));
// Add the slot to the component
this.getComponent().add("slotName", slotValue, Flags.SUMMARY, facets);
}
private BStringWritable createStringWritable(String value) {
BStringWritable writable = new BStringWritable();
writable.set(BString.make(value));
return writable;
}```
I do have the code but its 500+ lines, thats why i created a seperate testing block. I can share the function I’m trying to get right.
Basically, I’m bringing in xml data from a http request, parse it and then extract key/value pairs.
I use these pairs to then create writable blocks. Since i know all the possible key/values, i can assign types to each. I’m making the blocks just fine. But can’t assign facets to any of them. That’s what i need help with. In the example below, I’m trying to edit facets on enums. I’ll try on edit others types once I figure out the enums.
private void addTypedSlot(BComponent target, String slotName, String value, String objectType) {
String oldSlot = slotName;
slotName = normalizeName(slotName);
String type = TYPE_MAPPINGS.getOrDefault("Thermostat", Collections.emptyMap()).get(oldSlot);
type = type != null ? type : "string"; // Default to string
//debug("Type is: " + type);
synchronized (keys) {
keys.add(slotName);
values.add(value);
}
try {
BValue slotValue = null;
BStatusString statusString;
BStatusBoolean statusBoolean;
BStatusNumeric statusNumeric;
BStatusEnum statusEnum;
switch (type) {
case "numeric":
try {
BNumericWritable numWritable = new BNumericWritable();
numWritable.set(BDouble.make(Double.parseDouble(value)));
slotValue = numWritable;
} catch (NumberFormatException e) {
debug("Error converting to numeric, falling back to string");
slotValue = createStringWritable(value);
}
break;
case "boolean":
try {
BBooleanWritable boolWritable = new BBooleanWritable();
boolWritable.set(BBoolean.make(Boolean.parseBoolean(value)));
slotValue = boolWritable;
} catch (Exception e) {
debug("Error converting to boolean, falling back to string");
slotValue = createStringWritable(value);
}
break;
case "enum":
try {
String[] enumValues = ENUM_VALUES.getOrDefault(objectType, Collections.emptyMap()).get(oldSlot);
if (enumValues != null) {
debug("Processing enum: " + oldSlot);
// Create enum range and find matching index
BEnumRange range = BEnumRange.make(enumValues);
int index = findEnumIndex(value, enumValues);
if (index >= 0) {
BEnumWritable enumWritable = new BEnumWritable();
enumWritable.set(BDynamicEnum.make(index, range));
slotValue = enumWritable;
debug("Created enum writable with index: " + index);
} else {
debug("Value not in enum range, falling back to string");
slotValue = createStringWritable(value);
}
} else {
debug("No enum mapping found, falling back to string");
slotValue = createStringWritable(value);
}
} catch (Exception e) {
debug("Error processing enum: " + e.getMessage());
slotValue = createStringWritable(value);
}
break;
case "string":
default:
slotValue = createStringWritable(value);
break;
}
String[] enumValues2 = ENUM_VALUES.getOrDefault(objectType, Collections.emptyMap()).get(oldSlot);
if (slotValue != null) {
if (target.getSlot(slotName) == null) {
debug("Creating new writable slot: " + slotName);
if(type.equals("enum"))
{
for(String enumValue : enumValues2) {
debug("Enum value: " + enumValue);
}
target.add(slotName, slotValue, Flags.SUMMARY, BFacets.makeEnum(BEnumRange.make(enumValues2)));
}
else
{
target.add(slotName, slotValue, Flags.SUMMARY);
}
debug("Added new writable slot: " + slotName);
} else {
debug("Updating existing writable slot: " + slotName);
Slot[] slotArray = ((BComplex)target).getSlotsArray();
for(Slot singleSlot : slotArray)
{
debug(singleSlot.getName());
}
Slot slot = slotArray[0];
debug("Slot found: " + slot);
Property property = slot.asProperty(); //this.getComponent().add(name, new BStatusString(),Flags.SUMMARY);
debug("Property found: " + property);
switch (type) { //BFacets.makeEnum(BEnumRange.make(range, index))
case "numeric":
debug("Updating numeric slot: " + oldSlot);
BStatusNumeric currentNum = (BStatusNumeric) target.get(property);
currentNum.setValue(Double.parseDouble(value));
break;
case "boolean":
debug("Updating boolean slot: " + oldSlot);
BStatusBoolean currentBool = (BStatusBoolean) target.get(property);
currentBool.setValue(Boolean.parseBoolean(value));
break;
case "enum":
debug("Updating enum slot: " + oldSlot);
String[] enumValues = ENUM_VALUES.getOrDefault(objectType, Collections.emptyMap()).get(oldSlot);
if (enumValues != null) {
debug("Processing enum: " + oldSlot);
}
// Create enum range and find matching index
BEnumRange range2 = BEnumRange.make(enumValues);
int index2 = findEnumIndex(value, enumValues);
BStatusEnum currentEnum = (BStatusEnum) target.get(property);
currentEnum.setValue(BDynamicEnum.make(index2, range2));
break;
default:
debug("Updating string slot: " + oldSlot);
BStatusString currentStr = (BStatusString) target.get(property);
currentStr.setValue(value);
break;
}
target.set(property, slotValue);
debug("Updated existing writable slot: " + slotName);
}
}
else {
debug("Slot value is null, not updating");
}
} catch (Exception e) {
error("Failed to update slot " + slotName + ": " + e.getMessage());
}
}