diff --git a/README.md b/README.md index 694f0e6..0607082 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,13 @@ Turns a Raspberry Pi into an inexpensive, web-enabled kiln controller. * no limit to runtime - fire for days if you want * view status from multiple devices at once - computer, tablet etc * real-time firing cost estimate - * NIST-linearized conversion for accurate K type thermocouple readings + * real-time heating rate displayed in degrees per hour * supports PID parameters you tune to your kiln * monitors temperature in kiln after schedule has ended * api for starting and stopping at any point in a schedule * accurate simulation * support for shifting schedule when kiln cannot heat quickly enough + * support for skipping first part of profile to match current kiln temperature * prevents integral wind-up when temperatures not near the set point * automatic restarts if there is a power outage or other event * support for a watcher to page you via slack if you kiln is out of whack diff --git a/lib/oven.py b/lib/oven.py index fb2826c..245c662 100644 --- a/lib/oven.py +++ b/lib/oven.py @@ -327,6 +327,8 @@ class Oven(threading.Thread): self.totaltime = 0 self.target = 0 self.heat = 0 + self.heat_rate = 0 + self.heat_rate_temps = [] self.pid = PID(ki=config.pid_ki, kd=config.pid_kd, kp=config.pid_kp) @staticmethod @@ -339,6 +341,24 @@ class Oven(threading.Thread): startat = 0 return startat + def set_heat_rate(self,runtime,temp): + '''heat rate is the heating rate in degrees/hour + ''' + # arbitrary number of samples + # the time this covers changes based on a few things + numtemps = 60 + self.heat_rate_temps.append((runtime,temp)) + + # drop old temps off the list + if len(self.heat_rate_temps) > numtemps: + self.heat_rate_temps = self.heat_rate_temps[-1*numtemps:] + time2 = self.heat_rate_temps[-1][0] + time1 = self.heat_rate_temps[0][0] + temp2 = self.heat_rate_temps[-1][1] + temp1 = self.heat_rate_temps[0][1] + if time2 > time1: + self.heat_rate = ((temp2 - temp1) / (time2 - time1))*3600 + def run_profile(self, profile, startat=0, allow_seek=True): log.debug('run_profile run on thread' + threading.current_thread().name) runtime = startat * 60 @@ -426,6 +446,8 @@ class Oven(threading.Thread): temp = 0 pass + self.set_heat_rate(self.runtime,temp) + state = { 'cost': self.cost, 'runtime': self.runtime, @@ -433,6 +455,7 @@ class Oven(threading.Thread): 'target': self.target, 'state': self.state, 'heat': self.heat, + 'heat_rate': self.heat_rate, 'totaltime': self.totaltime, 'kwh_rate': config.kwh_rate, 'currency_type': config.currency_type, diff --git a/public/assets/js/picoreflow.js b/public/assets/js/picoreflow.js index b5338ce..7d38a92 100644 --- a/public/assets/js/picoreflow.js +++ b/public/assets/js/picoreflow.js @@ -575,6 +575,10 @@ $(document).ready(function() } $('#act_temp').html(parseInt(x.temperature)); + heat_rate = parseInt(x.heat_rate) + if (heat_rate > 9999) { heat_rate = 9999; } + if (heat_rate < -9999) { heat_rate = -9999; } + $('#heat_rate').html(heat_rate); $('#heat').html('
') if (x.cool > 0.5) { $('#cool').addClass("ds-led-cool-active"); } else { $('#cool').removeClass("ds-led-cool-active"); } if (x.air > 0.5) { $('#air').addClass("ds-led-air-active"); } else { $('#air').removeClass("ds-led-air-active"); } @@ -608,6 +612,7 @@ $(document).ready(function() $('#act_temp_scale').html('º'+temp_scale_display); $('#target_temp_scale').html('º'+temp_scale_display); + $('#heat_rate_temp_scale').html('º'+temp_scale_display); switch(time_scale_profile){ case "s": diff --git a/public/index.html b/public/index.html index b37b682..cc72819 100644 --- a/public/index.html +++ b/public/index.html @@ -29,6 +29,7 @@