Example #1
0
    def new_history_entry(self, rain=0):
        """Create a new history entry"""
        values = {}
        n = now()
        for t, ml in self.meters.items():
            sum_it = False
            sum_val = 0
            sum_f = 0
            for m in ml:
                f = m.weight
                v = m.get_value()
                if m.last_time is None:
                    f *= 0.01
                else:
                    s = (n - m.last_time).total_seconds()
                    if s > METER_MAXTIME:
                        f *= 0.01
                    elif s > METER_TIME:
                        f *= METER_TIME / s
                if v is not None:
                    sum_val += f * v
                    sum_f += f
                if m.sum_it: sum_it = True
            if sum_f:
                if not sum_it:
                    sum_val /= sum_f
                values[t] = sum_val

        print("Values:", values, file=sys.stderr)
        h = History(site=self.s, time=now(), **values)
        h.save()
        return h
Example #2
0
	def new_history_entry(self,rain=0):
		"""Create a new history entry"""
		values = {}
		n = now()
		for t,ml in self.meters.items():
			sum_it = False
			sum_val = 0
			sum_f = 0
			for m in ml:
				f = m.weight
				v = m.get_value()
				if m.last_time is None:
					f *= 0.01
				else:
					s = (n - m.last_time).total_seconds()
					if s > METER_MAXTIME:
						f *= 0.01
					elif s > METER_TIME:
						f *= METER_TIME/s
				if v is not None:
					sum_val += f*v
					sum_f += f
				if m.sum_it: sum_it = True
			if sum_f:
				if not sum_it:
					sum_val /= sum_f
				values[t] = sum_val
		
		print("Values:",values, file=sys.stderr)
		h = History(site=self.s,time=now(),**values)
		h.save()
		return h
Example #3
0
    def has_rain(self):
        """Some monitor told us that it started raining"""
        r, self.rain_timer = self.rain_timer, gevent.spawn_later(
            self.s.db_rain_delay, connwrap, self.no_rain)
        if r:
            r.kill()
            return
        self.log("Started raining")
        self.rain = True

        #for v in self.s.valves.all():
        vo = Valve.objects.filter(controller__site=self.s, runoff__gt=0)
        for v in vo.all():
            valve = SchedValve(v)
            if valve.locked:
                continue
            try:
                valve._off(1)
            except NotConnected:
                pass
            except Exception:
                self.log_error(v)
        Schedule.objects.filter(valve__in=vo,
                                start__gte=now() - timedelta(1),
                                seen=False).delete()
        self.run_main_task()
Example #4
0
	def _on(self,sched=None,duration=None):
		print >>sys.stderr,"Open",self.v.var
		self.site.delay_on()
		if self.controller.has_max_on():
			print >>sys.stderr,"… but too many:", " ".join(str(v) for v in self.controller.c.valves.all() if SchedValve(v).on)
			if sched:
				sched.update(seen = False)
			self.on = False
			self.log("NOT running for %s: too many"%(duration,))
			raise TooManyOn(self)
		if duration is None and sched is not None:
			duration = sched.duration
		if duration is None:
			self.log("Run (indefinitely)")
			self.site.send_command("set","output","on",*(self.v.var.split()))
		else:
			self.log("Run for %s"%(duration,))
			if not isinstance(duration,(int,long)):
				duration = duration.total_seconds()
			self.site.send_command("set","output","on",*(self.v.var.split()), sub=(("for",duration),("async",)))
		if sched is not None:
			if self.v.verbose:
				self.log("Opened for %s"%(sched,))
			self.sched = sched
			if not sched.seen:
				sched.update(start=now(), seen = True)
				sched.refresh()
			#Save(sched)
		else:
			if self.v.verbose:
				self.log("Opened for %s"%(duration,))
Example #5
0
    def _range(self, start, end, forced=False, add=0):
        if start is None:
            start = now()
        r = []

        if forced:
            # If this pass considers force-open times, only this matters
            r.append(self._forced_range(start, end))
        else:
            # Apply groups' times
            r.append(self._group_range(start, end))
            r.append(self._group_xrange(start, end))

            # First step finished.
            r = [range_intersection(*r)]
            # Now add any group "allowed" one-shots.
            for g in self.groups.all():
                r.append(g._allowed_range(start, end))
            r = [range_union(*r)]

            # Now add any group "not-allowed" one-shots.
            for g in self.groups.all():
                r.append(g._not_blocked_range(start, end))

            # Also apply my own exclusion times
            r.append(self._not_blocked_range(start, end))

        # Exclude times when this valve is already scheduled
        r.append(self._not_scheduled(start, end))

        # Only consider times when the controller can open the valve and
        # there's enough water for it to run
        r.append(self.controller._range(start, end, add=add))
        r.append(self.feed._range(start, end, self.flow, add=add))
        return range_intersection(*r)
Example #6
0
	def _range(self,start,end, forced=False, add=0):
		if start is None:
			start = now()
		r = []

		if forced:
			# If this pass considers force-open times, only this matters
			r.append(self._forced_range(start,end))
		else:
			# Apply groups' times 
			r.append(self._group_range(start,end))
			r.append(self._group_xrange(start,end))

			# First step finished.
			r = [range_intersection(*r)]
			# Now add any group "allowed" one-shots.
			for g in self.groups.all():
				r.append(g._allowed_range(start,end))
			r = [range_union(*r)]

			# Now add any group "not-allowed" one-shots.
			for g in self.groups.all():
				r.append(g._not_blocked_range(start,end))

			# Also apply my own exclusion times
			r.append(self._not_blocked_range(start,end))

		# Exclude times when this valve is already scheduled
		r.append(self._not_scheduled(start,end))

		# Only consider times when the controller can open the valve and
		# there's enough water for it to run
		r.append(self.controller._range(start,end,add=add))
		r.append(self.feed._range(start,end,self.flow,add=add))
		return range_intersection(*r)
Example #7
0
	def run_main_task(self, kill=True):
		"""Run the calculation loop."""
		res = None
		if not self._running.acquire(blocking=False):
			return self._run_result.get()
		try:
			self._run_result = AsyncResult()
			if kill:
				self._run.kill()
			n = now()
			ts = (n-self._run_last).total_seconds()
			if ts < 5:
				try:
					res = self.s.history.order_by("-time")[0]
				except IndexError:
					return None
				else:
					return res
			self._run_last = n

			res = self.main_task()
			return res
		finally:
			self._run = gevent.spawn_later((self._run_last+self._run_delay-n).total_seconds(), connwrap,self.run_main_task, kill=False)
			r,self._run_result = self._run_result,None
			self._running.release()
			r.set(res)
Example #8
0
    def run_main_task(self, kill=True):
        """Run the calculation loop."""
        res = None
        if not self._running.acquire(blocking=False):
            return self._run_result.get()
        try:
            self._run_result = AsyncResult()
            if kill:
                self._run.kill()
            n = now()
            ts = (n - self._run_last).total_seconds()
            if ts < 5:
                try:
                    res = self.s.history.order_by("-time")[0]
                except IndexError:
                    return None
                else:
                    return res
            self._run_last = n

            res = self.main_task()
            return res
        finally:
            self._run = gevent.spawn_later(
                (self._run_last + self._run_delay - n).total_seconds(),
                connwrap,
                self.run_main_task,
                kill=False)
            r, self._run_result = self._run_result, None
            self._running.release()
            r.set(res)
Example #9
0
	def stop(self):
		n=now()
		sec = (n-self.start).total_seconds()
		if sec > 3:
			self.res = sec
		else:
			self.feed.log("Flush broken: sec %s"%(sec,))
		self._unlock()
Example #10
0
 def stop(self):
     n = now()
     sec = (n - self.start).total_seconds()
     if sec > 3:
         self.res = sec
     else:
         self.feed.log("Flush broken: sec %s" % (sec, ))
     self._unlock()
Example #11
0
	def monitor_value(self,event=None,**k):
		"""monitor value NUMBER name…"""
		self.refresh()
		self.last_time = now()
		try:
			val = float(event[2])
			self.add_value(val)
		except Exception:
			print_exc()
Example #12
0
	def add_flow(self,val):
		self.nflow += 1
		if self.nflow == 2:
			self.start = now()
		if self.nflow > 2:
			self.flow += val
		if self.nflow == 9:
			self.stop()
		return False
Example #13
0
	def snapshot(self):
		n = now()
		if self.ts is not None and self.val is not None:
			w=(n-self.ts).total_seconds()
			if w > METER_TIME:
				w = METER_TIME # limit weight if the measurer dies
			self.avg += w*self.val
			self.nval += w
		self.ts = n
Example #14
0
 def snapshot(self):
     n = now()
     if self.ts is not None and self.val is not None:
         w = (n - self.ts).total_seconds()
         if w > METER_TIME:
             w = METER_TIME  # limit weight if the measurer dies
         self.avg += w * self.val
         self.nval += w
     self.ts = n
Example #15
0
 def add_flow(self, val):
     self.nflow += 1
     if self.nflow == 2:
         self.start = now()
     if self.nflow > 2:
         self.flow += val
     if self.nflow == 9:
         self.stop()
     return False
Example #16
0
 def current_history_entry(self, delta=15):
     # assure that the last history entry is reasonably current
     try:
         he = self.s.history.order_by("-time")[0]
     except IndexError:
         pass
     else:
         if (now() - he.time).total_seconds() < delta:
             return he
     return self.new_history_entry()
Example #17
0
	def current_history_entry(self,delta=15):
		# assure that the last history entry is reasonably current
		try:
			he = self.s.history.order_by("-time")[0]
		except IndexError:
			pass
		else:
			if (now()-he.time).total_seconds() < delta:
				return he
		return self.new_history_entry()
Example #18
0
 def stop(self):
     n = now()
     sec = (n - self.start).total_seconds()
     if sec > 3:
         self.res = self.flow / sec
         self.feed.d.update(flow=self.res)
         self.feed.d.refresh()
     else:
         self.feed.log("Flow check broken: sec %s" % (sec, ))
     self._unlock()
Example #19
0
	def stop(self):
		n=now()
		sec = (n-self.start).total_seconds()
		if sec > 3:
			self.res = self.flow/sec
			self.feed.d.update(flow = self.res)
			self.feed.d.refresh()
		else:
			self.feed.log("Flow check broken: sec %s"%(sec,))
		self._unlock()
Example #20
0
	def monitor_value(self,value_delta=None,value=None,**kv):
		"""monitor update name…"""
		self.refresh()
		self.last_time = now()
		try:
			if value_delta is not None:
				self.add_value(value_delta)
			else:
				self.add_value(value)
		except Exception:
			print_exc()
Example #21
0
 def monitor_value(self, value_delta=None, value=None, **kv):
     """monitor update name…"""
     self.refresh()
     self.last_time = now()
     try:
         if value_delta is not None:
             self.add_value(value_delta)
         else:
             self.add_value(value)
     except Exception:
         print_exc()
Example #22
0
    def new_level_entry(self, flow=0):
        self.site.current_history_entry()
        n = now()
        self.v.refresh()
        hts = None
        try:
            lv = self.v.levels.order_by("-time")[0]
        except IndexError:
            ts = n - timedelta(1, 0)
        else:
            ts = lv.time
        sum_f = 0
        sum_r = 0
        for h in self.site.s.history.filter(time__gt=ts).order_by("time"):
            if self.v.verbose > 2:
                self.log("Env factor for %s: T=%s W=%s S=%s" %
                         (h, h.temp, h.wind, h.sun))
            f = self.env.env_factor(
                h,
                logger=self.log if self.v.verbose > 2 else None) * self.v.adj
            if self.v.verbose > 1:
                self.log("Env factor for %s is %s" % (h, f))
            sum_f += self.site.s.db_rate * self.v.do_shade(
                self.env.eg.factor * f) * (h.time - ts).total_seconds()
            sum_r += self.v.runoff * h.rain
            ts = h.time

        if self.v.verbose:
            self.log("Apply env %f, rain %r,, flow %f = %f" %
                     (sum_f, sum_r, flow, flow / self.v.area))

        if self.v.time == ts:
            return
        if self.v.level < 0:
            level = 0
        else:
            level = F('level')
        level += sum_f
        if (flow > 0 or sum_r > 0) and self.v.level > self.v.max_level:
            level = self.v.max_level
        level -= flow / self.v.area + sum_r
        #if level < 0:
        #	self.log("Level %s ?!?"%(self.v.level,))
        self.v.update(time=ts, level=level)
        self.v.refresh()

        lv = Level(valve=self.v, time=ts, level=self.v.level, flow=flow)
        lv.save()

        if self.on and not (self.sched and self.sched.forced
                            ) and self.v.level <= self.v.stop_level:
            self._off(5)
Example #23
0
    def _on(self, caller, sched=None, duration=None):
        print("Open", caller, self.v.var, file=sys.stderr)
        self.site.delay_on()
        if duration is None and sched is not None:
            duration = sched.duration
        if self.controller.has_max_on():
            print("… but too many:",
                  ", ".join(
                      str(v) for v in self.controller.c.valves.all()
                      if SchedValve(v).on),
                  file=sys.stderr)
            if sched:
                sched.update(seen=False)
            self.log("NOT running %s for %s: too many" % (
                self.v,
                duration,
            ))
            raise TooManyOn(self)
        if duration is None:
            self.log("Run (indefinitely)")
            self.site.send_command("set", "output", "on",
                                   *(self.v.var.split()))
        else:
            self.log("Run for %s" % (duration, ))
            if not isinstance(duration, six.integer_types):
                duration = duration.total_seconds()
            try:
                self.site.send_command("set",
                                       "output",
                                       "on",
                                       *(self.v.var.split()),
                                       sub=(("for", duration), ("async", )))
            except Exception:
                # Something broke. Try to turn this thing off.
                self.log(format_exc())

                self.site.send_command("set", "output", "off",
                                       *(self.v.var.split()))
                raise RuntimeError("Could not start (logged)")

        if sched is not None:
            if self.v.verbose:
                self.log("Opened for %s" % (sched, ))
            self.sched = sched
            if not sched.seen:
                sched.update(start=now(), seen=True)
                sched.refresh()
            #Save(sched)
        else:
            if self.v.verbose:
                self.log("Opened for %s" % (duration, ))
Example #24
0
	def sync_history(self):
		n=now()
		try:
			lv = self.v.levels.order_by("-time")[0]
		except IndexError:
			pass
		else:
			if self.v.time > lv.time:
				self.log("Timestamp downdate: %s %s" % (self.v.time,lv.time))
				self.v.update(time = lv.time)
				self.v.refresh()
				#Save(self.v)
		if (n-self.v.time).total_seconds() > 3500:
			self.new_level_entry()
Example #25
0
 def sync_history(self):
     n = now()
     try:
         lv = self.v.levels.order_by("-time")[0]
     except IndexError:
         pass
     else:
         if self.v.time > lv.time:
             self.log("Timestamp downdate: %s %s" % (self.v.time, lv.time))
             self.v.update(time=lv.time)
             self.v.refresh()
             #Save(self.v)
     if (n - self.v.time).total_seconds() >= 295:
         flow, self.flow = self.flow, 0
         self.new_level_entry(flow)
Example #26
0
	def run_every(self,delay):
		"""Initiate running the calculation and scheduling loop every @delay seconds."""

		if self._run_delay is not None:
			self._run_delay = delay # just update
			return
		self._run_delay = delay
		self._run_last = now()
		self._running = Semaphore()
		self._run_result = None
		sd = self._run_delay.total_seconds()/10
		if sd < 66: sd = 66
		self._run = gevent.spawn_later(sd, connwrap,self.run_main_task, kill=False)
		if self._sched is not None:
			self._sched.kill()
		self._sched = gevent.spawn_later(2, connwrap,self.run_sched_task, kill=False, reason="run_every")
Example #27
0
	def new_level_entry(self,flow=0):
		self.site.current_history_entry()
		n=now()
		self.v.refresh()
		hts = None
		try:
			lv = self.v.levels.order_by("-time")[0]
		except IndexError:
			ts = n-timedelta(1,0)
		else:
			ts = lv.time
		sum_f = 0
		sum_r = 0
		for h in self.site.s.history.filter(time__gt=ts).order_by("time"):
			if self.v.verbose>2:
				self.log("Env factor for %s: T=%s W=%s S=%s"%(h,h.temp,h.wind,h.sun))
			f = self.env.env_factor(h, logger=self.log if self.v.verbose>2 else None)*self.v.adj
			if self.v.verbose>1:
				self.log("Env factor for %s is %s"%(h,f))
			sum_f += self.site.s.db_rate * self.v.do_shade(self.env.eg.factor*f) * (h.time-ts).total_seconds()
			sum_r += self.v.runoff*h.rain
			ts=h.time

		if self.v.verbose:
			self.log("Apply env %f, rain %r,, flow %f = %f" % (sum_f,sum_r,flow,flow/self.v.area))

		if self.v.time == ts:
			return
		if self.v.level < 0:
			level = 0
		else:
			level = F('level')
		level += sum_f
		if (flow > 0 or sum_r > 0) and self.v.level > self.v.max_level:
			level = self.v.max_level
		level -= flow/self.v.area+sum_r
		#if level < 0:
		#	self.log("Level %s ?!?"%(self.v.level,))
		self.v.update(time=ts, level=level)
		self.v.refresh()

		lv = Level(valve=self.v,time=ts,level=self.v.level,flow=flow)
		lv.save()

		if self.on and not (self.sched and self.sched.forced) and self.v.level <= self.v.stop_level:
			self._off(5)
Example #28
0
    def _on(self, caller, sched=None, duration=None):
        print("Open", caller, self.v.var, file=sys.stderr)
        self.site.delay_on()
        if duration is None and sched is not None:
            duration = sched.duration
        if self.controller.has_max_on():
            print(
                "… but too many:",
                ", ".join(str(v) for v in self.controller.c.valves.all() if SchedValve(v).on),
                file=sys.stderr,
            )
            if sched:
                sched.update(seen=False)
            self.log("NOT running %s for %s: too many" % (self.v, duration))
            raise TooManyOn(self)
        if duration is None:
            self.log("Run (indefinitely)")
            self.site.send_command("set", "output", "on", *(self.v.var.split()))
        else:
            self.log("Run for %s" % (duration,))
            if not isinstance(duration, six.integer_types):
                duration = duration.total_seconds()
            try:
                self.site.send_command(
                    "set", "output", "on", *(self.v.var.split()), sub=(("for", duration), ("async",))
                )
            except Exception:
                # Something broke. Try to turn this thing off.
                self.log(format_exc())

                self.site.send_command("set", "output", "off", *(self.v.var.split()))
                raise RuntimeError("Could not start (logged)")

        if sched is not None:
            if self.v.verbose:
                self.log("Opened for %s" % (sched,))
            self.sched = sched
            if not sched.seen:
                sched.update(start=now(), seen=True)
                sched.refresh()
                # Save(sched)
        else:
            if self.v.verbose:
                self.log("Opened for %s" % (duration,))
Example #29
0
    def watch_state(self, value=None, **kv):
        """output change NAME ::value ON"""
        on = (str(value).lower() in ("1", "true", "on"))
        if self._flow_check is not None:
            # TODO
            self.on = on
            self._flow_check.state(on)
            return
        if self.locked:
            self.on = on
            return
        try:
            if on != self.on:
                n = now()
                print("Report %s" % ("ON" if on else "OFF"),
                      self.v.var,
                      self.sched,
                      file=sys.stderr)
                if self.sched is not None and not on:
                    self.sched.update(
                        db_duration=(n - self.sched.start).total_seconds())
                    self.sched.refresh()
                    self.sched_ts = self.sched.end
                    self.sched = None
                flow, self.flow = self.flow, 0
                # If nothing happened, calculate.
                if not on:
                    duration = n - self.on_ts
                    maxflow = self.v.flow * duration.total_seconds()
                    if (not flow or not self.v.feed.var) or flow > 2 * maxflow:
                        flow = maxflow
                self.new_level_entry(flow)
                if not on:
                    if self.v.level > self.v.stop_level + (
                            self.v.start_level - self.v.stop_level) / 5:
                        self.v.update(priority=True)
                    self.log("Done for %s, level is now %s" %
                             (duration, self.v.level))
                self.on = on
                self.on_ts = n

        except Exception:
            print_exc()
Example #30
0
    def run_every(self, delay):
        """Initiate running the calculation and scheduling loop every @delay seconds."""

        if self._run_delay is not None:
            self._run_delay = delay  # just update
            return
        self._run_delay = delay
        self._run_last = now()
        self._running = Semaphore()
        self._run_result = None
        sd = self._run_delay.total_seconds() / 10
        if sd < 66: sd = 66
        self._run = gevent.spawn_later(sd,
                                       connwrap,
                                       self.run_main_task,
                                       kill=False)
        if self._sched is not None:
            self._sched.kill()
        self._sched = gevent.spawn_later(2,
                                         connwrap,
                                         self.run_sched_task,
                                         kill=False,
                                         reason="run_every")
Example #31
0
	def has_rain(self):
		"""Some monitor told us that it started raining"""
		r,self.rain_timer = self.rain_timer,gevent.spawn_later(self.s.db_rain_delay,connwrap,self.no_rain)
		if r:
			r.kill()
			return
		self.log("Started raining")
		self.rain = True

		#for v in self.s.valves.all():
		vo = Valve.objects.filter(controller__site=self.s, runoff__gt=0)
		for v in vo.all():
			valve = SchedValve(v)
			if valve.locked:
				continue
			try:
				valve._off(1)
			except NotConnected:
				pass
			except Exception:
				self.log_error(v)
		Schedule.objects.filter(valve__in=vo, start__gte=now()-timedelta(1),seen=False).delete()
		self.run_main_task()
Example #32
0
	def watch_state(self,value=None,**kv):
		"""output change NAME ::value ON"""
		on = (str(value).lower() in ("1","true","on"))
		if self._flow_check is not None:
			# TODO
			self.on = on
			self._flow_check.state(on)
			return
		if self.locked:
			self.on = on
			return
		try:
			if on != self.on:
				n=now()
				print("Report %s" % ("ON" if on else "OFF"),self.v.var,self.sched, file=sys.stderr)
				if self.sched is not None and not on:
					self.sched.update(db_duration=(n-self.sched.start).total_seconds())
					self.sched.refresh()
					self.sched_ts = self.sched.end
					self.sched = None
				flow,self.flow = self.flow,0
				# If nothing happened, calculate.
				if not on:
					duration = n-self.on_ts
					maxflow = self.v.flow * duration.total_seconds()
					if (not flow or not self.v.feed.var) or flow > 2*maxflow:
						flow = maxflow
				self.new_level_entry(flow)
				if not on:
					if self.v.level > self.v.stop_level + (self.v.start_level-self.v.stop_level)/5:
						self.v.update(priority=True)
					self.log("Done for %s, level is now %s"%(duration,self.v.level))
				self.on = on
				self.on_ts = n

		except Exception:
			print_exc()
Example #33
0
	def queryset(self, request):
		qs = super(LevelInline, self).queryset(request)
		return qs.filter(time__gte = now()-timedelta(1,0)).order_by("-time")
Example #34
0
	def list_range(self):
		if self.days.count()+self.xdays.count()+self.overrides.filter(start__gt=now()).count() == 0:
			return u"‹no dates›"
		return super(Group,self).list_range()
Example #35
0
	def save(self,commit=True):
		if self.instance.id is None:
			self.instance.time = now()
			self.instance.valve = self.aux_data['valve']
		self.instance.forced = True
		return super(LevelForm,self).save(commit)
Example #36
0
	def _run_schedule(self):
		if self.sched_job is not None:
			self.sched_job.kill()
			self.sched_job = None
		if self.locked:
			if self.v.verbose:
				print("SCHED LOCKED2 %s" % (self.v.name,), file=sys.stderr)
			return
		n = now()

		try:
			if self.sched is not None:
				self.sched.refresh()
				if self.sched.end <= n:
					if self.v.verbose:
						print("Turn off: %s+%s <= %s" % (self.sched.start,self.sched.duration,n), file=sys.stderr)
					self._off(2)
					self.sched = None
				else:
					self.sched_job = gevent.spawn_later((self.sched.end-n).total_seconds(),connwrap,self.run_sched_task,reason="_run_schedule 1")
					if self.v.verbose:
						print("SCHED LATER %s: %s" % (self.v.name,humandelta(self.sched.end-n)), file=sys.stderr)
					return
		except ObjectDoesNotExist:
			pass # somebody deleted it *shrug*
		sched = None

		if self.sched_ts is None:
			try:
				sched = self.v.schedules.filter(start__lt=n).order_by("-start")[0]
			except IndexError:
				self.sched_ts = n-timedelta(1,0)
			else:
				self.sched_ts = sched.end
				if sched.end > n: # still running
					if self.v.verbose:
						print("SCHED RUNNING %s: %s" % (self.v.name,humandelta(sched.end-n)), file=sys.stderr)
					try:
						self._on(1,sched, sched.end-n)
					except TooManyOn:
						self.log("Could not schedule: too many open valves")
					except NotConnected:
						self.log("Could not schedule: connection to MoaT failed")
					return

		try:
			sched = self.v.schedules.filter(start__gte=self.sched_ts).order_by("start")[0]
		except IndexError:
			if self.v.verbose:
				print("SCHED EMPTY %s: %s" % (self.v.name,str_tz(self.sched_ts)), file=sys.stderr)
			self._off(3)
			return

		if sched.end <= n:
			if self.v.verbose:
				print("SCHED %s: sched %d done for %s" % (self.v.name,sched.id,humandelta(n-sched.end)), file=sys.stderr)
			self.sched_ts = None
			return
		if sched.start > n:
			if self.v.verbose:
				print("SCHED %s: sched %d in %s" % (self.v.name,sched.id,humandelta(sched.start-n)), file=sys.stderr)
			self._off(4)
			self.sched_job = gevent.spawn_later((sched.start-n).total_seconds(),connwrap,self.run_sched_task,reason="_run_schedule 2")
			return
		try:
			self._on(2,sched)
		except TooManyOn:
			self.log("Could not schedule: too many open valves")
		except NotConnected:
			self.log("Could not schedule: connection to MoaT failed")
Example #37
0
	def get_queryset(self, request):
		qs = super(ScheduleInline, self).queryset(request)
		return qs.filter(start__gte = now()-timedelta(0.5)).order_by("start")
Example #38
0
	def get_queryset(self, request):
		qs = super(LevelInline, self).queryset(request)
		return qs.filter(time__gte = now()-timedelta(1,0)).order_by("-time")
Example #39
0
	def get_queryset(self, request):
		qs = super(ValveOverrideInline, self).queryset(request)
		return qs.filter(start__gte = now()-timedelta(1,0)).order_by("-start")
Example #40
0
 def save(self, commit=True):
     if self.instance.id is None:
         self.instance.time = now()
         self.instance.valve = self.aux_data['valve']
     self.instance.forced = True
     return super(LevelForm, self).save(commit)
Example #41
0
	def queryset(self, request):
		qs = super(ValveOverrideInline, self).queryset(request)
		return qs.filter(start__gte = now()-timedelta(1,0)).order_by("-start")
Example #42
0
from django.core.management.base import BaseCommand, CommandError
from rainman.models import Site,Valve,Schedule,Controller,History,Level
from rainman.utils import now,str_tz
from rainman.logging import log
from datetime import datetime,time,timedelta
from django.db.models import F,Q
from django.utils.timezone import utc,get_current_timezone
from optparse import make_option
from time import sleep
from traceback import print_exc
import rpyc
import errno
import sys

n=now()
soon=n+timedelta(0,15*60)
later=n+timedelta(0,2*60*60)

class Command(BaseCommand):
	args = '<valve>…'
	help = 'Generate a schedule'

	option_list = BaseCommand.option_list + (
			make_option('-s','--site',
				action='store',
				dest='site',
				default=None,
				help='Select the site to use'),
			make_option('-c','--controller',
				action='store',
Example #43
0
    def _run_schedule(self):
        if self.sched_job is not None:
            self.sched_job.kill()
            self.sched_job = None
        if self.locked:
            if self.v.verbose:
                print("SCHED LOCKED2 %s" % (self.v.name, ), file=sys.stderr)
            return
        n = now()

        try:
            if self.sched is not None:
                self.sched.refresh()
                if self.sched.end <= n:
                    if self.v.verbose:
                        print("Turn off: %s+%s <= %s" %
                              (self.sched.start, self.sched.duration, n),
                              file=sys.stderr)
                    self._off(2)
                    self.sched = None
                else:
                    self.sched_job = gevent.spawn_later(
                        (self.sched.end - n).total_seconds(),
                        connwrap,
                        self.run_sched_task,
                        reason="_run_schedule 1")
                    if self.v.verbose:
                        print("SCHED LATER %s: %s" %
                              (self.v.name, humandelta(self.sched.end - n)),
                              file=sys.stderr)
                    return
        except ObjectDoesNotExist:
            pass  # somebody deleted it *shrug*
        sched = None

        if self.sched_ts is None:
            try:
                sched = self.v.schedules.filter(
                    start__lt=n).order_by("-start")[0]
            except IndexError:
                self.sched_ts = n - timedelta(1, 0)
            else:
                self.sched_ts = sched.end
                if sched.end > n:  # still running
                    if self.v.verbose:
                        print("SCHED RUNNING %s: %s" %
                              (self.v.name, humandelta(sched.end - n)),
                              file=sys.stderr)
                    try:
                        self._on(1, sched, sched.end - n)
                    except TooManyOn:
                        self.log("Could not schedule: too many open valves")
                    except NotConnected:
                        self.log(
                            "Could not schedule: connection to MoaT failed")
                    return

        try:
            sched = self.v.schedules.filter(
                start__gte=self.sched_ts).order_by("start")[0]
        except IndexError:
            if self.v.verbose:
                print("SCHED EMPTY %s: %s" %
                      (self.v.name, str_tz(self.sched_ts)),
                      file=sys.stderr)
            self._off(3)
            return

        if sched.end <= n:
            if self.v.verbose:
                print("SCHED %s: sched %d done for %s" %
                      (self.v.name, sched.id, humandelta(n - sched.end)),
                      file=sys.stderr)
            self.sched_ts = None
            return
        if sched.start > n:
            if self.v.verbose:
                print("SCHED %s: sched %d in %s" %
                      (self.v.name, sched.id, humandelta(sched.start - n)),
                      file=sys.stderr)
            self._off(4)
            self.sched_job = gevent.spawn_later(
                (sched.start - n).total_seconds(),
                connwrap,
                self.run_sched_task,
                reason="_run_schedule 2")
            return
        try:
            self._on(2, sched)
        except TooManyOn:
            self.log("Could not schedule: too many open valves")
        except NotConnected:
            self.log("Could not schedule: connection to MoaT failed")
Example #44
0
	def queryset(self, request):
		qs = super(ScheduleInline, self).queryset(request)
		return qs.filter(start__gte = now()-timedelta(0.5)).order_by("start")
Example #45
0
from django.core.management.base import BaseCommand, CommandError
from rainman.models import Site,Valve,Schedule,Controller,History,Level
from rainman.utils import now,str_tz
from rainman.logging import log
from datetime import datetime,time,timedelta
from django.db.models import F,Q
from django.utils.timezone import utc,get_current_timezone
from optparse import make_option
from time import sleep
from traceback import print_exc
import rpyc
import errno
import sys

n=now()
soon=n+timedelta(0,15*60)
later=n+timedelta(0,2*60*60)

class Command(BaseCommand):
	args = '<valve>…'
	help = 'Generate a schedule'

	def add_arguments(self, parser):
		parser.add_argument('-s','--site',
				action='store',
				dest='site',
				default=None,
				help='Select the site to use')
		parser.add_argument('-c','--controller',
				action='store',