How to access the targetTemperature variable in my program

How do I access the targetTemperature variable in the code below. I've commented where I am trying to access targetTemperature but I'm not sure the correct way to do this and it won't compile.

.ino:

#include "ThermostatAccessoryBase.h"

void setup() {

}

void loop() {

  float setpoint = ThermostatAccessoryBase.targetTemperature; //This is where I am trying to access the targetTerperature variable but it does not compile

}

.cpp:

#include "ThermostatAccessoryBase.h"

std::string ThermostatAccessoryBase::getTargetTemperature (HKConnection *sender) {
    return format("%0.1f", targetTemperature);
}

void ThermostatAccessoryBase::setTargetTemperature (float oldValue, float newValue, HKConnection *sender) {
    targetTemperature = newValue;
}

.h:

#include "HKAccessory.h"
#include "HAPAccessoryDescriptor.h"

class ThermostatAccessoryBase: public HAPAccessoryDescriptor {
private:
    std::string getTargetTemperature (HKConnection *sender);
    void setTargetTemperature (float oldValue, float newValue, HKConnection *sender);    
    intCharacteristics *brightnessStateChar = NULL;
    
public:
    float targetTemperature = 21.0;
    virtual void initAccessorySet();
};

The scopes seem wrong here.

You have the variable marked public and the accessor methods (getter & setter) private - typically you'd do it the other way round.
This way you can protect the "naive" float variable against unchecked changes via the respective accessor methods and return sane values in case the variable wasn't set properly.

BTW

If you also disclosed the error messages you get we might see better what the compiler dislikes :wink:

However, since targetTemperature is not a static variable you cannot access it via the class but need an object instance.
If it was static you'd access it via ThermostatAccessoryBase::targetTemperature.

1 Like

Thanks for the reply. I got this working. I am not sure if it is the correct way to do this and don't know much about classes. You mentioned "if it was static" so I looked into what that meant and ended up making my members static and now I can access them in my code and have it working. Does this sound like a bad idea?

It's typically not the way you'd do it.
A class is like a blueprint how to build something. Usually you'd not have a blueprint only and then not intend to build an actual object of that kind.
You can only live in an actual house - not in its blueprint (at least not comfortably :wink: )

Since static variables are shared between all objects they are typically not used for individual data like temperatures.
For example you had multiple DHT sensors each of them tied to its own object instance, you wouldn't want one instance to change the temperature reading of another.
Going with the house analogy: If you had multiple houses build according to one common blueprint, you wouldn't want that changing the setting for the inside temperature in one house also affected all the others.

Normally when you have a class ThermostatAccessory (the Base would typically be abstract) you'd have most fields and methods non-static and then instantiate objects like this

ThermostatAccessory ta1(dhtSensorPin); // allow for multiple objects, with a dedicated 
                                       // sensor each by having a fitting constructor
// access
  ta1.setTargetTemperature(x);
  temp = ta1.readTemperature();

Ok, thanks. Your explanation makes sense.

The example I copied this code from is used to create an accessory that apple homekit can pair with. What doesn't make sense to me is why the original author used classes. Every example that was provided was for a single accessory like a light bulb, a light switch or in my case I modified the code to create a thermostat. I get that you could have multiples of these accessories but I would think each accessory would have it's own instance of the entire program. This code does not act as a hub that would service multiple instances of an accessory type.

If you are interested in looking here is the project: https://github.com/ljezny/Particle-HAP

It would be great to understand why the examples uses classes.

I had a look at the examples and I see that they do it as expected.
e.g. in this example you find this line

which instantiates an object according to the class definition and then uses that object instance to access its members.

This is how it's typically done, even when you only need one instance.

Awesome! Thank you for looking at the examples.

Where in that example do they access a member of the instance? Would that be what is happening in this line:

47 didAnything |= acc->handle(); //handle accessory, did anything (i.e read some sensors)

Yup, that is the place.
Since acc is a pointer to the object they use the -> operator.
If it were a direct reference you'd use the . (dot) operator.

1 Like