Skip to content

Instantly share code, notes, and snippets.

@richardpeng
Created April 20, 2023 03:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save richardpeng/938d98c545247b9b938dfb1f733ed7d9 to your computer and use it in GitHub Desktop.
Save richardpeng/938d98c545247b9b938dfb1f733ed7d9 to your computer and use it in GitHub Desktop.
class Supercooling {
static def delta(Integer temperature, BigDecimal slope, BigDecimal intercept) {
return slope * temperature + intercept
}
static def coolingTime(ArrayList<Integer> morningForecast, coolingRequired, coolSlope, coolIntercept) {
def coolingAmount = 0
def time = 0
def hour = 0
while (coolingAmount < coolingRequired) {
def fullHourCooling = -delta(morningForecast.reverse()[hour], coolSlope, coolIntercept)
def addTime = fullHourCooling + coolingAmount <= coolingRequired ? 1 : (coolingRequired - coolingAmount) / fullHourCooling
time += addTime
coolingAmount += fullHourCooling
hour += 1
}
return time
}
}
assert Supercooling.delta(80, 0.05, -6.0) == -2.00
assert Supercooling.coolingTime([20, 40, 60, 80], 8, 0.05, -6) == 2.75
// Parameters
def resistSlope = 0.0320
def resistIntercept = -1.8196
def coolSlope = 0.0727
def coolIntercept = -7.1936
def endingSetpoint = 74
// Dynamic
def currentIndoorTemp = 71
// Weather data fetched from weather.gov
// Example: https://api.weather.gov/gridpoints/DTX/43,32/forecast/hourly
def morningForecast = [69, 70, 73, 75]
def forecast = [82, 83, 85, 88]
// Expected increase in temperature while coasting during peak period
def peakDelta = forecast.collect { Supercooling.delta(it, resistSlope, resistIntercept) }.inject { acc, val -> acc + val }
// Expected change in temperature from now until peak period
def prePeakDelta = morningForecast.collect {Supercooling.delta(it, resistSlope, resistIntercept) }.inject { acc, val -> acc + val }
// Target temperature to end peak period at the desired endingSetpoint
def targetSetpoint = endingSetpoint - peakDelta
// Current temperature difference to get to targetSetpoint
def coolingAmount = [currentIndoorTemp - targetSetpoint, 0].max()
// Time it'll take to cool from current temperature to targetSetpoint, including adjustment for temperature increase from now until peak period
def coolingTime = Supercooling.coolingTime(morningForecast, coolingAmount + prePeakDelta, coolSlope, coolIntercept)
println([
peakDelta: peakDelta,
prePeakDelta: prePeakDelta,
targetSetpoint: targetSetpoint,
currentIndoorTemp: currentIndoorTemp,
coolingAmount: coolingAmount,
coolingTime: coolingTime
])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment