Created
April 20, 2023 03:04
-
-
Save richardpeng/938d98c545247b9b938dfb1f733ed7d9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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