Editing Facets PRogramatically

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;
}```

This is a program object not a module?

Thats Right. Not a module currently, testing with a program object. I’ll go in a module eventually.

Do you have your original code? I’m still trying to work out exactly what you’re trying to do? Happy to help once I understand it :slight_smile:

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());
    }
}
  String[] range = {"Range1", "Range2"};
  BFacets facets = BFacets.makeEnum(BEnumRange.make(range));
  BEnumWritable writable = new BEnumWritable();
  writable.setFacets(facets);

Does this not work?

3 Likes

That works! Thanks!
Here’s my final code

public void onExecute() throws Exception
{ 
      String[] range = {"Range1", "Range2"};
      BFacets facets = BFacets.makeEnum(BEnumRange.make(range));
      BEnumWritable writable = new BEnumWritable();
      this.getComponent().add("hello", writable, Flags.SUMMARY);
      writable.setFacets(facets);
}
2 Likes