Exemple #1
0
class Charger(models.YearTSModel):
    '''
    Data products from the MX charge controller
    '''
    address = cCols.Text(primary_key=True)
    current = cCols.Float()
    pvcurrent = cCols.Float()
    pvvolt = cCols.Float()
    daykwh = cCols.Float()
    aux = cCols.Integer()
    error = cCols.Integer()
    chargemode = cCols.Text()
    batteryvolt = cCols.Float()
    dayah = cCols.Float()

    access_name = 'charger'
    __table_name__ = models.resource_table_name(access_name, res_name)

    def get_df(self, start, end=None, freq=None):
        return super(Charger, self).get_df(start=start,
                                           end=end,
                                           freq=freq,
                                           index='ts')

    def get_day_kwh(self):
        q = self.objects.all()
        q = q.limit(2)  # should read how many to expect
        # TODO this is really ugly
        return sum(entry.daykwh for entry in q[:])
Exemple #2
0
class Training(TrainingBase):
    # you automatically get all the same columns as the existing training table
    # because we inherited from VT.Training
    # in addition to those, lets define a new column
    day_type = cCols.Integer()
    target_predict = cCols.Float()
    kWh_tot_predict = cCols.Float()
    kWh_next_hr = cCols.Float()
    kWh_next_hr_predict = cCols.Float()

    # access_name is how the this table is stored in data_clients
    # this has nothing to do with cassandra, only the data_client
    access_name = 'training'
    # CQLEngine uses this syntax to define the table name in cassandra
    # I think it is a nice convention to use <res name>_<access_name>
    # as the actual table name in cassandra.
    # This is purely stylistic though and not enforced by anything
    __table_name__ = models.resource_table_name(access_name, res_name)

    day_type_view = VTviews.DayType

    def create_views(self):
        self.create_view(self.day_type_view)
        return super(Training, self).create_views()

    def get_by_day_type(self, hour, day_type, yrydays=None, limit=None):
        view_inst = self.attach_view(self.day_type_view)(**self)
        return view_inst.find_type(hour=hour,
                                   yrydays=yrydays,
                                   day_type=day_type,
                                   limit=limit)

    def get_df_by_day_type(self, *args, **kwargs):
        q = self.get_by_day_type(*args, **kwargs)
        return self.convert_to_df(q)
Exemple #3
0
class Holidays(YrydayBaseModel):
    yryday = cCols.Integer(primary_key=True)

    # must specify this access name so client knows what to call it
    __table_name_case_sensitive__ = True
    access_name = 'holidays'
    __table_name__ = models.resource_table_name(access_name, res_name)

    def get(self, yrydays):
        q = self.filter(yryday__in=yrydays)
        q.limit(None)
        return q

    def get_df(self, *args, **kwargs):
        q = self.get(*args, **kwargs)
        return self.convert_to_df(q, index='yryday')

    @classmethod
    def insert_df(cls, df):
        df.index.name = 'yryday'
        df = df.reset_index()
        return cls.insert_concurrent(df)

    def rewind(self, **kwargs):
        # TODO PLACEHOLDER!  We need to rewind this table somehow
        pass
Exemple #4
0
class Thermostat(models.YearTSModel):
    temp = cCols.Float()
    t_heat = cCols.Float()
    tmode = cCols.Integer()
    tstate = cCols.Integer()

    access_name = 'tstat'
    __table_name__ = models.resource_table_name(access_name, res_name)
Exemple #5
0
class Switches(models.YearTSModel):
    # operation = cCols.Text()  #the name of the overall state.
    mensheater = cCols.Integer()  # 1 is on, 0 is off
    ladiesheater = cCols.Integer()
    wellpump = cCols.Integer()
    waterheater = cCols.Integer()

    access_name = 'switches'
    __table_name__ = models.resource_table_name(access_name, res_name)
Exemple #6
0
class FX(models.YearTSModel):
    '''
    Data products from the FX inverter
    '''
    current = cCols.Integer()  # inverter current
    acoutv = cCols.Integer()  # ac output in volts
    opmode = cCols.Integer()  # FX operational mode
    error = cCols.Integer()  # FX errors
    batteryvolt = cCols.Float()  # battery voltage
    warning = cCols.Integer()

    access_name = 'inverter'
    __table_name__ = models.resource_table_name(access_name, res_name)
Exemple #7
0
class Usage(models.Usage):
    airhandler = cCols.Float()
    compressor = cCols.Float()
    lighting = cCols.Float()
    plug1 = cCols.Float()
    plug2 = cCols.Float()
    __table_name__ = models.resource_table_name(models.Usage, res_name)

    # gets called when packets come in to tpks and they need to enter the db

    def process_packet(self, res_pkt):
        # need to unify the terms in the pkt and the names of the columns
        dd = self.parse_packet_for_usage(res_pkt)

        if dd:
            use_data = res_pkt.get('other', {})
            circuit_usage = {}
            for circuit_name, circuit_info in use_data.iteritems():
                circuit_usage[circuit_name] = circuit_info['Power Sum']

            dd.update(circuit_usage)
            self.insert_row(dd)
Exemple #8
0
class Flexnet(models.YearTSModel):
    shuntamps_a = cCols.Float()
    shuntamps_b = cCols.Float()
    shuntamps_c = cCols.Float()
    extraid = cCols.Integer()
    extradata = cCols.Integer()
    batteryvolt = cCols.Float()
    soc = cCols.Float()

    # shunts enabled
    # 0 is enabled for some strange reason
    a_enable = cCols.Integer()
    b_enable = cCols.Integer()
    c_enable = cCols.Integer()

    batterytemp = cCols.Integer()
    statusflags = cCols.Integer()
    '''
    From the Flexnet DC documentation
    Status Flags: 00 to 63 This is an ASCII expression of an 8 bit byte, with each bit representing a
    different flag.  Relay state is 1 when relay is closed, 0 if relay is open.
    Relay mode is 0 if manual mode, 1 if relay control is in automatic mode.
    e.g. A returned 009 would be charge parms met and shunt 1 values are negative.

    BIT     #   Value Warning
    ----------------------------
    1       1   Charge parms met
    2       2   Relay mode:
    3       4   Relay state:
    4       8   Shunt A values are negative
    5       16  Shunt B values are negative
    6       32  Shunt C values are negative
    '''

    access_name = 'flexnet'
    __table_name__ = models.resource_table_name(access_name, res_name)
Exemple #9
0
class Usage(models.Usage):
    pv_production = cCols.Float()

    access_name = 'usage'
    __table_name__ = models.resource_table_name(access_name, res_name)
Exemple #10
0
class TrainingBase(YrydayBaseModel):
    hour = cCols.Integer(primary_key=True)
    yryday = cCols.Integer(primary_key=True, clustering_order='DESC')
    f_m7 = cCols.Float()
    f_m718 = cCols.Float()
    f_start2now = cCols.Float()
    f_now2end = cCols.Float()
    dow = cCols.Integer()
    kWh_now = cCols.Float()
    kWh_L = cCols.Float()
    kWh_A = cCols.Float()
    kWh_tot = cCols.Float()
    target = cCols.Float()

    HOURS_RANGE = range(0, 23)

    __table_name_case_sensitive__ = True
    # must specify this access name so client knows what to call it
    access_name = 'training_base'
    __table_name__ = models.resource_table_name(access_name, res_name)
    _has_datetime_primary_key = False

    def get(self, hour=None, yrydays=None):
        if hour is None:
            q = self.day_records_query(yrydays)
        else:
            q = self.objects.filter(hour=hour)
            if yrydays is not None:
                q = q.filter(yryday__in=yrydays)
        q.limit(None)
        return q

    def get_df(self, *args, **kwargs):
        q = self.get(*args, **kwargs)
        return self.convert_to_df(q)

    @classmethod
    def format_df(cls, df, hour=None):
        df.index.name = 'yryday'
        df = df.reset_index()
        if hour is not None:
            df['hour'] = hour
        return df

    def rewind(self, hours=None, **kwargs):
        hours = hours or self.HOURS_RANGE
        self.rewind_multiple(iterable=hours, col_name='hour', **kwargs)

    def day_records_query(self, yrydays):
        q = self.objects.filter(hour__in=self.HOURS_RANGE)
        try:
            # accept a list of yrydays
            q = q.filter(yryday__in=yrydays)
        except QueryException:
            # or a single yryday
            q = q.filter(yryday=yrydays)
        return q

    def day_records(self, yrydays):
        q = self.day_records_query(yrydays)
        return self.convert_to_df(q, index='hour')