Menu

change the value of a property programatically

2017-03-01
2017-03-01
  • Andres Marti

    Andres Marti - 2017-03-01

    Hi,

    From the source code of my own plugin, I'm changing the values of some properties. In particular, I'm playing with the values cooling_setpoint and heating_setpoint of the object house_e. I assume they are input values. The problem is that, according to some data I'm collecting by means of a recorder, the values of the setpoints are changed, but just for one iteration: in the next iteration they recover the default values (the values setted in the GLM file). Is it possible to change the default values permanently from the source code?

    I have changed the values in several ways, but I get the same result:

    1)

        house->cooling_setpoint = ....
    

    2)

        PROPERTY* propCooling = house->get_property("cooling_setpoint");
        double coolingValue = ...;
        gl_set_value(house->my(), propCooling, coolingValue);
    

    Best Regards,

     
  • Alessio Melis

    Alessio Melis - 2017-03-02

    can you post the completed code of thjis class ?

    thanks

     
  • Jason Fuller

    Jason Fuller - 2017-03-02

    Andres,

    Hard to say without seeing the GLM. I would check to see that your model doesn't include a schedule or player on the cooling_setpoint, which will "force" it to change on the scheduled command.

    That said, this code looks like it is in the controller, not the house. The controller is designed to modify the set point around the baseline set point, as there is an assumption that (1) the customer has a base set point they would like to stick to and (2) they could change that base set point at any given time. You may consider whether you want to set the actual set point or rather set the set point plus a differential.

     
  • Andres Marti

    Andres Marti - 2017-03-06

    Hi,

    You're right, in the GLM file (which derives from the node 8500) the setpoints of the HVAC system are programmed with schedules. The typical household is modeled as follows:

    object house {
      parent "SX2673305B_1";
      schedule_skew 2564;
      name "SX2673305B_1_house";
      floor_area 2200.5;
      thermal_integrity_level 3;
      hvac_power_factor 0.868;
      cooling_setpoint cooling8*1.64+71.64;
      heating_setpoint heating6*1.72+66.27;
      auxiliary_system_type NONE;
      heating_system_type RESISTANCE;
      cooling_system_type ELECTRIC;
      // ... zip loads, waterheater
    }
    

    Sorry. Now I see that the sepoints are not defined one time, but they are modified throughout the simulation. I thought that the sepoints were set at the beginning of the simulation, and that the demand were only guided by the internal temperature of the household. I see that I was wrong.

    As for the code, my plugin defines new elemtents. One of them is the DRBox, which is included as a subelement of the house_e element. According to a DR program, the DRBox decides when to act on the load items. This is done on the presync pass (before your clarification, I also tried with the other stages). The code is working well but, as you pointed out, its actions are overridden by the presence of the schedule in the GLM file.

      TIMESTAMP OadrBox::presync(TIMESTAMP t0) {
        if (events.size() == 0) {
            return TS_NEVER;
        }
    
        const oadr::ProgramEvent &event = events[0];
        const TIMESTAMP startTime = event.getStartTime();
        const TIMESTAMP stopTime = event.getStopTime();
        if (t0 < startTime) {
            return startTime;
        } else if ((t0 > startTime) && (t0 < stopTime)) {
            return stopTime;
        } else if (t0 == startTime) {
            this->eventProcessor->process(event);
            return stopTime;
        } else if (t0 == stopTime) {
            this->eventProcessor->stop(event);
            popEvent();
        }
    
        // Start time of the next DR event.
        long nextStartTime = nextEventStartTime();
        if (nextStartTime == -1) {
            return TS_NEVER;
        }
    
        return nextStartTime;
    }
    

    As you can see, the actions attached to both the start and end of the event are carried out by an entity called EventProcessor. This is really an interface which supports multiple implementations: I've developed processors that play with the HVAC system, the waterheater, the ZIPloads... or a combination of them. In this case, I'm loading an EventProcessor that just varies the setpoints of the HVAC system. Bellow I copy a snippet of this event processor:

    void EventProcessorHvac::process(const ProgramEvent &event) {
       const OpenadrLevel level = event.getLevel();
       if (level == OADR_MODERATE) {
          house->cooling_setpoint = data.defaultCoolingSetpoint + DELTA_HVAC_MODERATE;
          house->heating_setpoint = data.defaultHeatingSetpoint - DELTA_HVAC_MODERATE;
       }
       ...
    

    As for the message of Jason Fuller, I don't undertand when you say that the code seems to be in the controller. In particular, what does mean the controller?

    Thank you for all your comments, and sorry for the delayed response.

    Best regards,

     
  • Jason Fuller

    Jason Fuller - 2017-03-07

    Typically, we wouldn't develop new control code within the house object itself, but rather as a "controller" agent. You hadn't specified where your new code is located, so it was impossible to tell whether you had timing/synchronization issues.

     
  • Andres Marti

    Andres Marti - 2017-03-08

    Sorry. The control code is not within the house object. I guess that it can be said that the house object is modified from an inner object, which is the one that, when necessary, modifies the setpoints of the house object. Specifically, each house object includes an OadrBox object, which holds a reference to the parent house object. So a typical house object is defined as shown in the following example:

    object house {
      parent "SX3048196B_2";
      schedule_skew 1476;
      name "SX3048196B_2_house";
      floor_area 1741.9;
      thermal_integrity_level 6;
      hvac_power_factor 0.861;
      cooling_setpoint cooling7*1.53+70.79;
      heating_setpoint heating7*1.77+65.76;
      auxiliary_system_type NONE;
      heating_system_type GAS;
      cooling_system_type NONE;
    
      // zips loads and waterheater
      ...
      ...
    
     object OadrBox {
        ...
     };
    }
    

    As said, the modification of the house setpoints is done from the OadrBox element using the reference to the parent element. Perhaps what I'm looking for is the possibility of setting for a period the setpoints of the HVAC system under certain circumstances such as the incoming of a new DR event.

    I've also thought that may be this would be better for me to play with the waterheaters because their setpoints seem to be defined without players. I've been trying with HVAC systems because, in case of DR events, the variation of their operation is commonly considered a measure of comfort.

    Please let me know if this email does not clarify all the doubts.

    I really appreciate your comments.

    Best regards,

     
  • Jason Fuller

    Jason Fuller - 2017-03-08

    I've also thought that may be this would be better for me to play with the waterheaters because their setpoints seem to be defined without players.<<

    Note, the water heater set points can be modified by players/schedules and the house set points do not have to be set with players/schedules.

    The reason I mention this is that instead of holding the smart thermostate schedule in the home, you could hold it in the OadrBox object, which then pushes the set point changes to the house object. This would be effectively turn the house object into a "dumb" thermostat control and pull the smarts back into the OadrBox, giving you full control. This is very similar to how we do it with controller objects (base_cooling_setpoint).

    At that point, you GLM might look like:

    object house {
    parent "SX3048196B_2";
    schedule_skew 1476;
    name "SX3048196B_2_house";
    floor_area 1741.9;
    thermal_integrity_level 6;
    hvac_power_factor 0.861;
    auxiliary_system_type NONE;
    heating_system_type GAS;
    cooling_system_type NONE;

    heating_setpoint 72; // make it a default
    cooling_setpoint 78;

    // zips loads and waterheater
    ...
    ...

    object OadrBox {
    base_cooling_setpoint cooling71.53+70.79;
    base_heating_setpoint heating7
    1.77+65.76;
    };
    }

     
  • Andres Marti

    Andres Marti - 2017-03-13

    I've been examining the market module, and the OadrBox element actually imitates the controllers. I've been studying the controllers the past few days, but their code is not easy to understand, so I think I'll need some more time.

    I'm focusing on the passive controller, which seems the simplest. However, even in this case, I haven't found out how the controller manages the setpoint not being overridden. In the sync method, after calling the corresponding control method, if I'm not wrong, the method updates the setpoint and rc_override properties. I think this is what the block of code below does:

    if(output_setpoint_addr != 0){
        *(double *)output_setpoint_addr = output_setpoint;
    }
    if(output_state_addr != 0){
        *(int *)output_state_addr = output_state;
    }   
    

    Maybe the trick is in the value that the function should return. I have to look it better.

    I've also found the DLC property of house_e. Changes on this property (combined with re_override) do seem to be permanent. Are they? In any case, I think this is not valid for me, because the sync_thermosthat method recalculates the TOn and TOff temperatures from the current setpoint value, which is actually overridden by the player.

    Thank you for your comments and time!

     

    Last edit: Andres Marti 2017-03-13
  • Jason Fuller

    Jason Fuller - 2017-03-13

    Andres,

    Great question. By placing the thermostat schedule in the controller (rather than the house), we can prevent the schedule from updating the house object's thermostat setting. This happens, because the controller only updates the house setpoint every market cycle, whether the schedule changes or not. Note, that the calc_ramp() function is inside an if statement that makes sure we have advanced one market period.

    Of course, this is just a logic choice. An equally valid choice would be to allow the user (i.e., the home owner) to override the set point.

    Do you mean the DLC mode in the passive controller or the dlc_offset in the house object? These were orginally exclusively linked, but now dlc_offset is used to do a lot of other things. Using re_override with dlc_offset lets you manipulate the set point, then return to normal operation (re_override == OV_NORMAL). But, you are correct, if the house object has a schedule/player on it's thermostat control, the offset will be from the scheduled value.

    The key to all of this, though, is to remove the schedule/player from the house and place it in your controller. Then you can manipulate it however you want.

     
  • Andres Marti

    Andres Marti - 2017-03-13

    Now, thanks to you, I understand everything better.

    Regards,

     
  • Andres Marti

    Andres Marti - 2017-03-14

    Sorry, one more question... When does the value of players apply? Can I assume that this value has been applied before the "presync" walk starts? In this case I guess that this is correct to change the value of the setpoint in the presync stage of the child, so that in the sync stage the house reads and processes the new value.

     
    • Frank Tuffner

      Frank Tuffner - 2017-03-15

      Hello Andres,

      Players push their values out to the objects in the presync pass. They are usually one of the lowest ranked items (so they execute as one of the first items in the presync pass). However, this isn't always the case, so you need to be careful. Ideally, anything that uses a player value should be handled inside the sync pass instead, but sometimes that isn't possible.

      A work-around is to try and force the objects to have different ranks (http://gridlab-d.sourceforge.net/wiki/index.php/Object_(directive)). If you set the player to a lower rank than the object it is playing into, it should update that value before the "played into" object's presync pass. Basic syntax, with explicit parenting, would look like (yes, this is a completely contrived example):

      object house {
          name object_to_play_into;
          rank 1;
          floor_area 255 m^2;
      }
      
      object player {
          name floor_area_player;
          parent object_to_play_into;
          rank 0;
          property floor_area;
          file floor_area_data.csv;
      }
      

      Note that ranks can be a little fiddly to work with though, so this is very much a kludge/work-around that may not work as well as hoped. You may find that the player and next object work fine, but then something higher up is updating out of step.

      -Frank

       
  • Andres Marti

    Andres Marti - 2017-03-15

    Thank you. Good to know.

    I followed your previous advice and changed the code so that the controller (OadrBox) is the one who receives the cooling and heating setpoints coming from the player. Then, the controller decides with which values the house's thermostat is updated. Now, it is working fine. Thank you very much and I'm sorry for any inconvenience.

     

Log in to post a comment.