Ejemplo n.º 1
0
    def __init__(self,
                 ID_fridge,
                 ID_beer=None,
                 ID_ambient=None,
                 cooler=None,
                 heater=None,
                 door=None):
        # We must have at least a fridge sensor

        self.cs = ControlSettings()
        self.cv = ControlVariables()
        self.cc = ControlConstants()

        # State variables
        self.state = STATES['IDLE']
        self.cs.mode = MODES['MODE_OFF']

        self.doPosPeakDetect = None
        self.doNegPeakDetect = None

        self.door = door
        self.doorOpen = None

        self.cooler = cooler
        self.heater = heater
        self.light = None  # Not implemented
        self.fan = None  # Not implemented

        self.lastIdleTime = ticks.seconds()
        self.waitTime = None

        self.storedBeerSetting = None

        # cameraLight.setActive(false);

        # this is for cases where the device manager hasn't configured beer/fridge sensor.
        # if (self.beerSensor==None):
        self.beerSensor = tempSensor.sensor(ID_beer)

        # if (self.fridgeSensor==None):
        self.fridgeSensor = tempSensor.sensor(ID_fridge)

        self.ambientSensor = tempSensor.sensor(ID_ambient)

        self.beerSensor.init()
        self.fridgeSensor.init()
        self.ambientSensor.init()

        self.updateTemperatures()
        self.reset()

        # Do not allow heating/cooling directly after reset.
        # A failing script + CRON + Arduino uno (which resets on serial
        # connect) could damage the compressor
        # For test purposes, set these to -3600 to eliminate waiting
        # after reset
        self.lastHeatTime = ticks.seconds()
        self.lastCoolTime = ticks.seconds()

        self.integralUpdateCounter = 0
Ejemplo n.º 2
0
    def pickTempSetting(self, readTemp, writeTemp, tempName, printAnnotation, row):

        # Handle temperatures as integers internally, with a resolution of 0.1C
        # i.e. divide by 10
        oldSetting = readTemp()
        startVal = oldSetting
        minVal = int(self.tempControl.cc.tempSettingMin * 10)
        maxVal = int(self.tempControl.cc.tempSettingMax * 10)
        if oldSetting is None:  # previous temperature was not defined, start at 20C
            startVal = 20.0

        startVal *= 10
        t = float(startVal) / 10

        startPos = self.encoder.pos  # The encoder is free-running, so establish zero point

        # rotaryEncoder.setRange(startVal, minVal, maxVal)

        blinkTimer = 0
        lastChangeTime = ticks.seconds()

        while (ticks.timeSince(lastChangeTime) < MENU_TIMEOUT):  # time out at 10 seconds
            if (self.encoder.changed):
                lastChangeTime = ticks.seconds()
                blinkTimer = 0
                # startVal = tenthsToFixed(encoder.read())
                t = startVal + (self.encoder.pos - startPos)
                t = max(minVal, min(t, maxVal))
                t = float(t) / 10

                display.printTemperatureAt(12, row, t)
                display.update()

            if (self.encoder.pushed):
                # rotaryEncoder.resetPushed()
                writeTemp(t)
                printAnnotation("%s temp set to %s in Menu." % (tempName, t))
                while self.encoder.pushed:
                    pass
                return True

            if (blinkTimer == 0):
                display.printTemperatureAt(12, row, t)
                display.update()

            elif (blinkTimer == 128):
                display.printAt(12, row, " " * 5)
                display.update()

            blinkTimer += 1
            blinkTimer &= 0xff  # Blink timer is an 8-bit value
            time.sleep(0.003)  # delay for blinking

        # Time Out. Setting is not written
        return False  # FIXME: Do something if the encoder is not pushed
Ejemplo n.º 3
0
    def __init__(self, ID_fridge, ID_beer=None, ID_ambient=None, cooler=None, heater=None, door=None):
        # We must have at least a fridge sensor

        self.cs = ControlSettings()
        self.cv = ControlVariables()
        self.cc = ControlConstants()

        # State variables
        self.state = STATES['IDLE']
        self.cs.mode = MODES['MODE_OFF']

        self.doPosPeakDetect = None
        self.doNegPeakDetect = None

        self.door = door
        self.doorOpen = None

        self.cooler = cooler
        self.heater = heater
        self.light = None  # Not implemented
        self.fan = None  # Not implemented

        self.lastIdleTime = ticks.seconds()
        self.waitTime = None

        self.storedBeerSetting = None

        # cameraLight.setActive(false);

        # this is for cases where the device manager hasn't configured beer/fridge sensor.
        # if (self.beerSensor==None):
        self.beerSensor = tempSensor.sensor(ID_beer)

        # if (self.fridgeSensor==None):
        self.fridgeSensor = tempSensor.sensor(ID_fridge)

        self.ambientSensor = tempSensor.sensor(ID_ambient)

        self.beerSensor.init()
        self.fridgeSensor.init()
        self.ambientSensor.init()

        self.updateTemperatures()
        self.reset()

        # Do not allow heating/cooling directly after reset.
        # A failing script + CRON + Arduino uno (which resets on serial
        # connect) could damage the compressor
        # For test purposes, set these to -3600 to eliminate waiting
        # after reset
        self.lastHeatTime = ticks.seconds()
        self.lastCoolTime = ticks.seconds()

        self.integralUpdateCounter = 0
Ejemplo n.º 4
0
    def blinkLoop(self,
                  changed,  # function called to update the value
                  show,  # function called to show the current value
                  hide,  # function called to blank out the current value
                  pushed):  # function to handle selection

        # @return {@code true} if a value was selected. {@code false} on timeout.
        lastChangeTime = ticks.seconds()
        blinkTimer = 0

        while (ticks.timeSince(lastChangeTime) < MENU_TIMEOUT):  # time out at 10 seconds
            if (self.encoder.changed):
                lastChangeTime = ticks.seconds()
                blinkTimer = 0
                changed()
                display.update()

            if (blinkTimer == 0):
                show()
                display.update()

            elif (blinkTimer == 128):
                hide()
                display.update()

            if (self.encoder.pushed):
                # rotaryEncoder.resetPushed()
                show()
                display.update()
                while self.encoder.pushed:
                    pass
                pushed()
                return True

            blinkTimer += 1
            blinkTimer &= 0xff  # blink timer is an 8-bit value
            time.sleep(0.003)  # wait.millis(3)	# delay for blinking

        return False
Ejemplo n.º 5
0
def printAllTemperatures():
    """Print all temperatures on the LCD."""

    global flags

    # alternate between beer and room temp
    if (flags & LCD_FLAG_ALTERNATE_ROOM):
    #   bool displayRoom = ((ticks.seconds()&0x08)==0) && !BREWPI_SIMULATE && tempControl.ambientSensor->isConnected()
        displayRoom = (((int(ticks.seconds())&0x04)==0)
                and (tempControl.ambientSensor.deviceID is not None or tempControl.ambientSensor.topic is not None))
        if (displayRoom ^ ((flags & LCD_FLAG_DISPLAY_ROOM)!=0)):    # transition
            flags = (flags | LCD_FLAG_DISPLAY_ROOM) if displayRoom else (flags & ~LCD_FLAG_DISPLAY_ROOM)
            printStationaryText()

    printBeerTemp()
    printBeerSet()
    printFridgeTemp()
    printFridgeSet()
Ejemplo n.º 6
0
def printAllTemperatures():
    """Print all temperatures on the LCD."""

    global flags

    # alternate between beer and room temp
    if (flags & LCD_FLAG_ALTERNATE_ROOM):
    #   bool displayRoom = ((ticks.seconds()&0x08)==0) && !BREWPI_SIMULATE && tempControl.ambientSensor->isConnected()
        displayRoom = (((int(ticks.seconds())&0x04)==0)
                and tempControl.ambientSensor.deviceID is not None)
        if (displayRoom ^ ((flags & LCD_FLAG_DISPLAY_ROOM)!=0)):    # transition
            flags = (flags | LCD_FLAG_DISPLAY_ROOM) if displayRoom else (flags & ~LCD_FLAG_DISPLAY_ROOM)
            printStationaryText()

    printBeerTemp()
    printBeerSet()
    printFridgeTemp()
    printFridgeSet()
Ejemplo n.º 7
0
    def updateState(self):

        print("Update state. Mode %s, state %s" %
              ({v: k for k, v in MODES.items()}[self.cs.mode],
               {v: k for k, v in STATES.items()}[self.state]))

        stayIdle = False
        newDoorOpen = self.door.isOpen

        if (newDoorOpen != self.doorOpen):
            self.doorOpen = newDoorOpen
            print("Fridge door %s" % ('opened' if self.doorOpen else 'closed'))
            self.piLink.printFridgeAnnotation("Fridge door %s" %
                                              ("opened" if self.doorOpen  else "closed"))

        if (self.cs.mode == MODES['MODE_OFF']):
            self.state = STATES['STATE_OFF']
            stayIdle = True

        # stay idle when one of the required sensors is disconnected,
        # or the fridge setting is INVALID_TEMP
        # if(isDisabledOrInvalid(cs.fridgeSetting) ||
        # !fridgeSensor->isConnected() ||
        # (!beerSensor->isConnected() && tempControl.modeIsBeer())):
        #	self.state = 'IDLE'
        #	stayIdle = True

        # Stay idle if the fridge sensor isn't connected
        # TODO - Make sure this didn't break beer settings/profiles
        elif not self.cs.fridgeSetting or not self.fridgeSensor.temperature:
            self.state = STATES['IDLE']
            stayIdle = True
        elif not self.beerSensor.temperature and (self.cs.mode == MODES['MODE_BEER_CONSTANT'] or self.cs.mode == MODES['MODE_BEER_PROFILE']):
            self.state = STATES['IDLE']
            stayIdle = True

        sinceIdle = self.timeSinceIdle()
        sinceCooling = self.timeSinceCooling()
        sinceHeating = self.timeSinceHeating()
        fridgeFast = self.fridgeSensor.readFastFiltered()
        beerFast = self.beerSensor.readFastFiltered()
        secs = ticks.seconds()

        if self.state in (STATES['IDLE'], STATES['STATE_OFF'],
                          STATES['WAITING_TO_COOL'], STATES['WAITING_TO_HEAT'],
                          STATES['WAITING_FOR_PEAK_DETECT']):
            self.lastIdleTime = secs
            if not stayIdle:
                # set waitTime to zero. It will be set to the maximum
                # required waitTime below when wait is in effect.
                # if(stayIdle):
                #	break
                self.resetWaitTime()
                if (fridgeFast > (self.cs.fridgeSetting + self.cc.idleRangeHigh)):  # fridge temperature is too high
                    self.updateWaitTime(MIN_SWITCH_TIME, sinceHeating)
                    if (self.cs.mode == MODES['MODE_FRIDGE_CONSTANT']):
                        self.updateWaitTime(MIN_COOL_OFF_TIME_FRIDGE_CONSTANT, sinceCooling)
                    else:
                        if (beerFast < (
                            self.cs.beerSetting + 0.03125)):  # + 16) ):	# If beer is already under target, stay/go to idle. 1/2 sensor bit idle zone
                            self.state = STATES['IDLE']  # beer is already colder than setting, stay in or go to idle
                        # break # FIXME: We need to skip the next if statement
                        else:
                            self.updateWaitTime(MIN_COOL_OFF_TIME, sinceCooling)
                    if (self.cooler != None):  # FIXME was &defaultActuator):
                        if (self.getWaitTime() > 0):
                            self.state = STATES['WAITING_TO_COOL']
                        else:
                            self.state = STATES['COOLING']
                elif (fridgeFast < (self.cs.fridgeSetting + self.cc.idleRangeLow)):  # fridge temperature is too low
                    print("Fridge temperature is too low")
                    self.updateWaitTime(MIN_SWITCH_TIME, sinceCooling)
                    self.updateWaitTime(MIN_HEAT_OFF_TIME, sinceHeating)
                    if (self.cs.mode != MODES['MODE_FRIDGE_CONSTANT']):
                        if (beerFast > (
                            self.cs.beerSetting - 0.03125)):  # - 16)){ // If beer is already over target, stay/go to idle. 1/2 sensor bit idle zone
                            self.state = STATES['IDLE']  # beer is already warmer than setting, stay in or go to idle
                        # break # FIXME: We need to skip the next if statement
                    # if(self.heater != &defaultActuator or (self.lightAsHeater and (self.light != &defaultActuator))):
                    # FIXME what is &defaultActuator ?
                    if ((self.heater != None or
                             (self.cc.lightAsHeater and (self.light != None)))):
                        if (self.getWaitTime() > 0):
                            self.state = STATES['WAITING_TO_HEAT']
                        else:
                            self.state = STATES['HEATING']
                else:
                    self.state = STATES['IDLE']  # within IDLE range, always go to IDLE
                # break

            if (self.state == STATES['HEATING']
                or self.state == STATES['COOLING']):
                # If peak detect is not finished, but the fridge wants to switch to heat/cool
                # Wait for peak detection and show on display
                if self.doNegPeakDetect:
                    self.updateWaitTime(COOL_PEAK_DETECT_TIME, sinceCooling)
                    self.state = STATES['WAITING_FOR_PEAK_DETECT']
                elif self.doPosPeakDetect:
                    self.updateWaitTime(HEAT_PEAK_DETECT_TIME, sinceHeating)
                    self.state = STATES['WAITING_FOR_PEAK_DETECT']

        elif self.state in (STATES['COOLING'], STATES['COOLING_MIN_TIME']):
            self.doNegPeakDetect = True
            self.lastCoolTime = secs
            self.updateEstimatedPeak(self.cc.maxCoolTimeForEstimate, self.cs.coolEstimator, sinceIdle)
            self.state = STATES['COOLING']  # set to cooling here, so the display of COOLING/COOLING_MIN_TIME is correct
            # stop cooling when estimated fridge temp peak lands on target or if beer is already too cold (1/2 sensor bit idle zone)
            if (self.cv.estimatedPeak <= self.cs.fridgeSetting
                or (self.cs.mode != MODES['MODE_FRIDGE_CONSTANT']
                    and beerFast < (self.cs.beerSetting - 0.03125))):
                if (sinceIdle > MIN_COOL_ON_TIME):
                    self.cv.negPeakEstimate = self.cv.estimatedPeak  # remember estimated peak when I switch to IDLE, to adjust estimator later
                    self.state = STATES['IDLE']
                # break
                else:
                    self.state = STATES['COOLING_MIN_TIME']
                # break

        elif self.state in (STATES['HEATING'], STATES['HEATING_MIN_TIME']):
            self.doPosPeakDetect = True
            self.lastHeatTime = secs
            self.updateEstimatedPeak(self.cc.maxHeatTimeForEstimate, self.cs.heatEstimator, sinceIdle)
            self.state = STATES[
                'HEATING']  # reset to heating here, so the display of HEATING/HEATING_MIN_TIME is correct
            # stop heating when estimated fridge temp peak lands on target or if beer is already too warm (1/2 sensor bit idle zone)
            if (self.cv.estimatedPeak >= self.cs.fridgeSetting
                or (self.cs.mode != MODES['MODE_FRIDGE_CONSTANT']
                    and beerFast > (self.cs.beerSetting + 0.03125))):
                if (sinceIdle > MIN_HEAT_ON_TIME):
                    self.cv.posPeakEstimate = self.cv.estimatedPeak  # remember estimated peak when I switch to IDLE, to adjust estimator later
                    self.state = STATES['IDLE']
                # break
                else:
                    self.state = STATES['HEATING_MIN_TIME']
                # break

        elif self.state in (STATES['DOOR_OPEN']):
            pass  # do nothing
        else:
            logging.debug("Unknown state in updatePID: %s" % self.state)
Ejemplo n.º 8
0
    def updateState(self):

        print("Update state. Mode %s, state %s" %
              ({v: k
                for k, v in MODES.items()
                }[self.cs.mode], {v: k
                                  for k, v in STATES.items()}[self.state]))

        stayIdle = False
        newDoorOpen = self.door.isOpen

        if (newDoorOpen != self.doorOpen):
            self.doorOpen = newDoorOpen
            print("Fridge door %s" % ('opened' if self.doorOpen else 'closed'))
            self.piLink.printFridgeAnnotation(
                "Fridge door %s" % ("opened" if self.doorOpen else "closed"))

        if (self.cs.mode == MODES['MODE_OFF']):
            self.state = STATES['STATE_OFF']
            stayIdle = True

        # stay idle when one of the required sensors is disconnected,
        # or the fridge setting is INVALID_TEMP
        # if(isDisabledOrInvalid(cs.fridgeSetting) ||
        # !fridgeSensor->isConnected() ||
        # (!beerSensor->isConnected() && tempControl.modeIsBeer())):
        #	self.state = 'IDLE'
        #	stayIdle = True

        # Stay idle if the fridge sensor isn't connected
        # TODO - Make sure this didn't break beer settings/profiles
        elif not self.cs.fridgeSetting or not self.fridgeSensor.temperature:
            self.state = STATES['IDLE']
            stayIdle = True
        elif not self.beerSensor.temperature and (
                self.cs.mode == MODES['MODE_BEER_CONSTANT']
                or self.cs.mode == MODES['MODE_BEER_PROFILE']):
            self.state = STATES['IDLE']
            stayIdle = True

        sinceIdle = self.timeSinceIdle()
        sinceCooling = self.timeSinceCooling()
        sinceHeating = self.timeSinceHeating()
        fridgeFast = self.fridgeSensor.readFastFiltered()
        beerFast = self.beerSensor.readFastFiltered()
        secs = ticks.seconds()

        if self.state in (STATES['IDLE'], STATES['STATE_OFF'],
                          STATES['WAITING_TO_COOL'], STATES['WAITING_TO_HEAT'],
                          STATES['WAITING_FOR_PEAK_DETECT']):
            self.lastIdleTime = secs
            if not stayIdle:
                # set waitTime to zero. It will be set to the maximum
                # required waitTime below when wait is in effect.
                # if(stayIdle):
                #	break
                self.resetWaitTime()
                if (fridgeFast >
                    (self.cs.fridgeSetting +
                     self.cc.idleRangeHigh)):  # fridge temperature is too high
                    self.updateWaitTime(MIN_SWITCH_TIME, sinceHeating)
                    if (self.cs.mode == MODES['MODE_FRIDGE_CONSTANT']):
                        self.updateWaitTime(MIN_COOL_OFF_TIME_FRIDGE_CONSTANT,
                                            sinceCooling)
                    else:
                        if (
                                beerFast < (self.cs.beerSetting + 0.03125)
                        ):  # + 16) ):	# If beer is already under target, stay/go to idle. 1/2 sensor bit idle zone
                            self.state = STATES[
                                'IDLE']  # beer is already colder than setting, stay in or go to idle
                        # break # FIXME: We need to skip the next if statement
                        else:
                            self.updateWaitTime(MIN_COOL_OFF_TIME,
                                                sinceCooling)
                    if (self.cooler != None):  # FIXME was &defaultActuator):
                        if (self.getWaitTime() > 0):
                            self.state = STATES['WAITING_TO_COOL']
                        else:
                            self.state = STATES['COOLING']
                elif (fridgeFast <
                      (self.cs.fridgeSetting +
                       self.cc.idleRangeLow)):  # fridge temperature is too low
                    print("Fridge temperature is too low")
                    self.updateWaitTime(MIN_SWITCH_TIME, sinceCooling)
                    self.updateWaitTime(MIN_HEAT_OFF_TIME, sinceHeating)
                    if (self.cs.mode != MODES['MODE_FRIDGE_CONSTANT']):
                        if (
                                beerFast > (self.cs.beerSetting - 0.03125)
                        ):  # - 16)){ // If beer is already over target, stay/go to idle. 1/2 sensor bit idle zone
                            self.state = STATES[
                                'IDLE']  # beer is already warmer than setting, stay in or go to idle
                        # break # FIXME: We need to skip the next if statement
                    # if(self.heater != &defaultActuator or (self.lightAsHeater and (self.light != &defaultActuator))):
                    # FIXME what is &defaultActuator ?
                    if ((self.heater != None
                         or (self.cc.lightAsHeater and (self.light != None)))):
                        if (self.getWaitTime() > 0):
                            self.state = STATES['WAITING_TO_HEAT']
                        else:
                            self.state = STATES['HEATING']
                else:
                    self.state = STATES[
                        'IDLE']  # within IDLE range, always go to IDLE
                # break

            if (self.state == STATES['HEATING']
                    or self.state == STATES['COOLING']):
                # If peak detect is not finished, but the fridge wants to switch to heat/cool
                # Wait for peak detection and show on display
                if self.doNegPeakDetect:
                    self.updateWaitTime(COOL_PEAK_DETECT_TIME, sinceCooling)
                    self.state = STATES['WAITING_FOR_PEAK_DETECT']
                elif self.doPosPeakDetect:
                    self.updateWaitTime(HEAT_PEAK_DETECT_TIME, sinceHeating)
                    self.state = STATES['WAITING_FOR_PEAK_DETECT']

        elif self.state in (STATES['COOLING'], STATES['COOLING_MIN_TIME']):
            self.doNegPeakDetect = True
            self.lastCoolTime = secs
            self.updateEstimatedPeak(self.cc.maxCoolTimeForEstimate,
                                     self.cs.coolEstimator, sinceIdle)
            self.state = STATES[
                'COOLING']  # set to cooling here, so the display of COOLING/COOLING_MIN_TIME is correct
            # stop cooling when estimated fridge temp peak lands on target or if beer is already too cold (1/2 sensor bit idle zone)
            if (self.cv.estimatedPeak <= self.cs.fridgeSetting or
                (self.cs.mode != MODES['MODE_FRIDGE_CONSTANT'] and beerFast <
                 (self.cs.beerSetting - 0.03125))):
                if (sinceIdle > MIN_COOL_ON_TIME):
                    self.cv.negPeakEstimate = self.cv.estimatedPeak  # remember estimated peak when I switch to IDLE, to adjust estimator later
                    self.state = STATES['IDLE']
                # break
                else:
                    self.state = STATES['COOLING_MIN_TIME']
                # break

        elif self.state in (STATES['HEATING'], STATES['HEATING_MIN_TIME']):
            self.doPosPeakDetect = True
            self.lastHeatTime = secs
            self.updateEstimatedPeak(self.cc.maxHeatTimeForEstimate,
                                     self.cs.heatEstimator, sinceIdle)
            self.state = STATES[
                'HEATING']  # reset to heating here, so the display of HEATING/HEATING_MIN_TIME is correct
            # stop heating when estimated fridge temp peak lands on target or if beer is already too warm (1/2 sensor bit idle zone)
            if (self.cv.estimatedPeak >= self.cs.fridgeSetting or
                (self.cs.mode != MODES['MODE_FRIDGE_CONSTANT'] and beerFast >
                 (self.cs.beerSetting + 0.03125))):
                if (sinceIdle > MIN_HEAT_ON_TIME):
                    self.cv.posPeakEstimate = self.cv.estimatedPeak  # remember estimated peak when I switch to IDLE, to adjust estimator later
                    self.state = STATES['IDLE']
                # break
                else:
                    self.state = STATES['HEATING_MIN_TIME']
                # break

        elif self.state in (STATES['DOOR_OPEN']):
            pass  # do nothing
        else:
            logging.debug("Unknown state in updatePID: %s" % self.state)