def publish_status(self, target, temp, heater_percent, cooler_percent): if (datetime.now() - self._last_published).seconds < self._frequency: # Don't Dweet until the defined frequency has passed. return try: response = dweepy.dweet_for( self._thing_name, { 'temperature': temp, 'target': target, 'heater': heater_percent, 'cooler': cooler_percent, } ) except Exception as err: raise OutputError( 'Error publishing to Dweet API: {0}'.format(err)) if response['this'] != 'succeeded': print response raise OutputError( 'Error publishing to Dweet API: {0}'.format(response['this'])) else: self._last_published = datetime.now()
def publish_status(self, target, temp, heater_percent, cooler_percent): # Load status history from JSON try: with open(self._out_file, 'r') as fh: status_history = json.loads(fh.read()) except (IOError, ValueError): # No existing file or invalid JSON so start with no datapoints status_history = [] # Get timestamp in epoch seconds timestamp = int(time.time()) # Create new status status = [target, temp, heater_percent, cooler_percent, timestamp] # Add new status to previous data status_history.append(status) # Drop datapoints if limit exceeded if self._datapoint_limit != 0: while len(status_history) > self._datapoint_limit: # Discard oldest status datapoint log('Datapoint limit exceeded - dropping earliest datapoint: ' '{0!r}'.format(status_history[0])) status_history.pop(0) # Write status history JSON to file new_json = json.dumps(status_history) try: with open(self._out_file, 'w+') as fh: fh.write(new_json) except (IOError, ValueError) as err: raise OutputError(err)
def __init__(self, units='celsius', out_file='braubuddy.png', out_format='png', chart_title='Braubuddy', chart_mins=10080, x_label_mins=60): if out_format not in FORMATS.keys(): raise OutputError('ImageFileOutput format must be in {0}'.format( FORMATS.keys())) self._outputter = FORMATS[out_format] self._out_file = expanduser(out_file) self._past_seconds = chart_mins * 60 self._x_label_seconds = x_label_mins * 60 self._datapoints = [] # Chart config. Many of these values are hard coded to sensible # defaults to avoid overwhelming the user with kwargs. self._chart_config = pygal.Config() self._chart_config.title = chart_title self._chart_config.show_dots = False self._chart_config.show_minor_x_labels = False self._chart_config.x_label_rotation = 20 self._chart_config.y_label_rotation = 20 self._chart_config.y_title = 'Temperature' self._chart_config.label_font_size = 10 self._chart_config.legend_font_size = 10 self._chart_config.tooltip_font_size = 10 self._chart_config.tooltip_border_radius = 10 self._chart_config.interpolate = 'cubic' self._chart_config.print_values = False super(ImageFileOutput, self).__init__(units)
def publish_status(self, target, temp, heater_percent, cooler_percent): try: self._api.send_dict({ 'target_temp': target, 'actual_temp': temp, 'heater_percent': heater_percent, 'cooler_percent': cooler_percent, }) except Exception as err: raise OutputError( 'Error publishing to Graphite API: {0}'.format(err))
def publish_status(self, target, temp, heater_percent, cooler_percent): queue = self._api.new_queue() queue.add('target_temperature', target, source=self._source) queue.add('actual_temperature', temp, source=self._source) queue.add('heater_percent', heater_percent, source=self._source) queue.add('cooler_percent', cooler_percent, source=self._source) try: queue.submit() except Exception as err: raise OutputError( 'Error publishing to Librato API: {0}'.format(err))
def _get_credentials(self, creds_file): """ Get Twitter credentials from file if one exists. Otherwise request credentials via oauth. """ if not os.path.exists(creds_file): print 'Authorising with Twitter...' try: twitter.oauth_dance(APP, TCK, TCS, creds_file) except twitter.TwitterHTTPError as err: raise OutputError(err) oauth_token, oauth_secret = twitter.read_token_file(creds_file) return twitter.Twitter( auth=twitter.OAuth(oauth_token, oauth_secret, TCK, TCS))
def publish_status(self, target, temp, heater_percent, cooler_percent): if (datetime.now() - self._last_published).seconds < self._frequency: # Don't Tweet until the defined frequency has passed. return message = self._message.format(units=self.units, temp=temp, target=target, heat=heater_percent, cool=cooler_percent) if len(message) > 140: log.error('TwitterAPIOutput message exceeds 140 ' 'characters: {0}'.format(message)) try: self._api.statuses.update(status=message) self._last_published = datetime.now() except Exception as err: raise OutputError( 'Error publishing to Twitter API: {0}'.format(err))
def publish_status(self, target, temp, heater_percent, cooler_percent): # Get timestamp in epoch seconds timestamp = int(time.time()) # Append new status status = [target, temp, heater_percent, cooler_percent, timestamp] self._datapoints.append(status) # Drop datapoints older than required for chart earliest = timestamp - self._past_seconds self._datapoints = [d for d in self._datapoints if d[4] >= earliest] # Divine polling frequency using the difference between timestamps of # the most recent 2 datapoints. Use this to set an appropriate x label # interval. if len(self._datapoints) >= 2: freq_seconds = self._datapoints[-1][4] - self._datapoints[-2][4] if freq_seconds > 0: self._chart_config.x_labels_major_every = ( self._x_label_seconds / freq_seconds) # Draw chart chart = pygal.Line(self._chart_config) chart.x_labels = [ datetime.fromtimestamp(d[4]).strftime('%b-%d %H:%M:%S') for d in self._datapoints ] chart.add('Target', [d[0] for d in self._datapoints]) chart.add('Actual', [d[1] for d in self._datapoints]) # TODO: Add heating and cooling as bars once pygal supports bars and # lines on a single chart. #chart.add('Heating', [d[2] for d in self._datapoints], secondary=True) #chart.add('Cooling', [d[3] for d in self._datapoints], secondary=True) try: getattr(chart, self._outputter)(filename=self._out_file) except IOError as err: raise OutputError(err)
def publish_status(self, target, temp, heater_percent, cooler_percent): target_str = target temp_str = temp heater_str = heater_percent cooler_str = cooler_percent # Add units if required if self._show_units: target_str = '{0}{1}'.format(target_str, self.units) temp_str = '{0}{1}'.format(temp_str, self.units) heater_str = '{0}%'.format(heater_str) cooler_str = '{0}%'.format(cooler_str) # Add labels if required if self._show_labels: target_str = 'Target:{0}'.format(target_str) temp_str = 'Temperature:{0}'.format(temp_str) heater_str = 'Heater:{0}'.format(heater_str) cooler_str = 'Cooler:{0}'.format(cooler_str) # Generate output line line = '{1}{0}{2}{0}{3}{0}{4}\n'.format( self._separator, target_str, temp_str, heater_str, cooler_str ) # Add timestamp if required if self._show_timestamp: timestamp = datetime.now().strftime(self._timestamp_format) line = '{0}{1}{2}'.format(timestamp, self._separator, line) try: fh = open(self._out_file, 'a+') fh.write(line) fh.close() except IOError, err: raise OutputError(err)