Esempio n. 1
0
  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 = ''
Esempio n. 2
0
  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))
Esempio n. 3
0
    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
Esempio n. 4
0
    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))