def RecordDrink(self, tap_name, ticks, volume_ml=None, username=None, pour_time=None, duration=0, auth_token=None, spilled=False, shout='', tick_time_series='', do_postprocess=True): tap = self._GetTapFromName(tap_name) if not tap: raise backend.BackendError("Tap unknown") if volume_ml is None: volume_ml = float(ticks) * tap.ml_per_tick user = None if username: user = self._GetUserObjFromUsername(username) elif self._site.settings.default_user: user = self._site.settings.default_user if not pour_time: pour_time = datetime.datetime.now() keg = None if tap.current_keg and tap.current_keg.status == 'online': keg = tap.current_keg if spilled: if not keg: self._logger.warning('Got spilled pour for tap missing keg; ignoring') return keg.spilled_ml += volume_ml keg.save() return if tick_time_series: try: # Validate the time series by parsing it; canonicalize it by generating # it again. If malformed, just junk it; it's non-essential information. tick_time_series = time_series.to_string(time_series.from_string(tick_time_series)) except ValueError, e: self._logger.warning('Time series invalid, ignoring. Error was: %s' % e) tick_time_series = ''
def testTimeSeries(self): s = " 0:12 45:6789 " expected = [ (0, 12), (45, 6789) ] self.assertEqual(expected, time_series.from_string(s)) self.assertEqual(s.strip(), time_series.to_string(expected))
def record_drink(self, tap, ticks, volume_ml=None, username=None, pour_time=None, duration=0, shout='', tick_time_series='', photo=None, spilled=False): """Records a new drink against a given tap. The tap must have a Keg assigned to it (KegTap.current_keg), and the keg must be active. Args: tap: A KegTap or matching meter name. ticks: The number of ticks observed by the flow sensor for this drink. volume_ml: The volume, in milliliters, of the pour. If specifed, this value is saved as the Drink's actual value. If not specified, a volume is computed based on `ticks` and the meter's `ticks_per_ml` setting. username: The username with which to associate this Drink, or None for an anonymous Drink. pour_time: The datetime of the drink. If not supplied, the current date and time will be used. duration: Number of seconds it took to pour this Drink. This is optional information not critical to the record. shout: A short comment left by the user about this Drink. Optional. tick_time_series: Vector of flow update data, used for diagnostic purposes. spilled: If drink is recorded as spill, the volume is added to spilled_ml and the "drink" is not saved as an event. Returns: The newly-created Drink instance. """ tap = self._get_tap(tap) if not tap.is_active or not tap.current_keg: raise exceptions.BackendError("No active keg at this tap") keg = tap.current_keg if spilled: keg.spilled_ml += volume_ml keg.save(update_fields=['spilled_ml']) return None if volume_ml is None: meter = tap.current_meter() if not meter: raise exceptions.BackendError("Tap has no meter, can't compute volume") volume_ml = float(ticks) / meter.ticks_per_ml user = None if username: user = self.get_user(username) else: user = models.User.objects.get(username='******') if not pour_time: pour_time = timezone.now() if tick_time_series: try: # Validate the time series by parsing it; canonicalize it by generating # it again. If malformed, just junk it; it's non-essential information. tick_time_series = time_series.to_string(time_series.from_string(tick_time_series)) except ValueError as e: self._logger.warning('Time series invalid, ignoring. Error was: %s' % e) tick_time_series = '' d = models.Drink(ticks=ticks, keg=keg, user=user, volume_ml=volume_ml, time=pour_time, duration=duration, shout=shout, tick_time_series=tick_time_series) models.DrinkingSession.AssignSessionForDrink(d) d.save() keg.served_volume_ml += volume_ml keg.save(update_fields=['served_volume_ml']) if photo: pic = models.Picture.objects.create( image=photo, user=d.user, keg=d.keg, session=d.session ) d.picture = pic d.save() events = models.SystemEvent.build_events_for_drink(d) tasks.schedule_tasks(events) self.build_stats(d.id) signals.drink_recorded.send_robust(sender=self.__class__, drink=d) return d