Search code examples
pythonclassobjectvariablesreal-time-clock

Retrieving variable value in Python from a class object


I would like to access the variable values defined with a class but everything I try results in an error of one kind or another.

I will include the extract of Python code which defines the class which reads and shows the day, time and date from a DS3231 real time clock:

class ds3231(object):
    weekday  = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
    address = 0x68
    start_reg = 0x00
    alarm1_reg = 0x07
    control_reg = 0x0e
    status_reg = 0x0f
    
    def __init__(self,i2c_port,i2c_scl,i2c_sda):
        self.bus = I2C(i2c_port,scl=Pin(i2c_scl),sda=Pin(i2c_sda))
   
    def read_time(self):
        t = self.bus.readfrom_mem(int(self.address),int(self.start_reg),7)
        sec = t[0]&0x7F  #second
        min = t[1]&0x7F  #minute
        hrs = t[2]&0x3F  #hour
        wek = t[3]&0x07  #week
        day = t[4]&0x3F  #day
        mon = t[5]&0x1F  #month
        yer = t[6]&0x3F  #year
        print("%s %02x:%02x:%02x %02x/%02x/20%x" %(self.weekday[wek-1],hrs,min,sec,day,mon,yer))

The remaining code is as follows:

rtc = ds3231(I2C_PORT,I2C_SCL,I2C_SDA)

while True:
    
    rtc.read_time()
    sleep(3)

The output is:

Monday 12:23:09 07/11/2022

However, what I would like to do is to have access to the variables outside of the class so that I can do more with the data that is available such as:

print ('The year is ' + yer)

But this results in:

NameError: name 'yer' isn't defined

Further research shows that I need to specify the class and the variable, which I deduce as this:

print ('The year is ' + (read_time.yer))

But this results in:

NameError: name 'read_time' isn't defined

I've tried so many different variations, including trying to read the value into another variable as a string and then trying to output that, like this:

ryear = str(ds3231.yer())
print (rdate)

But this results in:

AttributeError: type object 'ds3231' has no attribute 'yer'

It is at this point I realise I need help and I really hope someone can guide me in the right direction.

I appreciate your help.


Solution

  • Before reading a variable from a class, in that case a property, you have to declare and initialize it.

    you could definitely do this within your read_time function by adding the self keyword:

    class ds3231:
    
    ...
       
        def read_time(self):
            t = self.bus.readfrom_mem(int(self.address), int(self.start_reg), 7)
            self.sec = t[0] & 0x7F  # second
            self.min = t[1] & 0x7F  # minute
            self.hrs = t[2] & 0x3F  # hour
            self.wek = t[3] & 0x07  # week
            self.day = t[4] & 0x3F  # day
            self.mon = t[5] & 0x1F  # month
            self.yer = t[6] & 0x3F  # year
            print("%s %02x:%02x:%02x %02x/%02x/20%x" %
                  (self.weekday[self.wek-1], self.hrs, self.min, self.sec, self.day, self.mon, self.yer))
    

    to use these properties outside the function you have to adress it in conjunction with the insatntiated class. But in that case you first have to call the function at least once.

    rtc = ds3231(I2C_PORT, I2C_SCL, I2C_SDA)
    rtc.read_time()
    ryear = str(rtc.yer)
    print (ryear)
    

    Also, properties are not meant to be called, like a function would, so no () after yer.

    And you had a little mistake with the naming there:

    ryear = str(ds3231.yer())
    print (rdate)
    

    Here rdate was not defined, you have used ryear in the line above.