2

I have a django model:

class Measurement(models.Model):
   """
   Saves the measurment data for every subdevice
   """
   node = models.ForeignKey('Node', related_name='measurements')
   value = models.CharField(_(u'Value'), max_length=255)
   begin = models.DateTimeField(editable=True)
   end = models.DateTimeField(editable=True)

Now value is either True/False or a number like 00123. Now what I want to do is to create a csv table:

Day, Time, node1, node2, node3
1, 00:00, 0, 1, 0
1, 00:05, 0, 1, 1
1, 00:10, 1, 0, 0
...
7, 24:00, 0, 0, 0

node is an appliance like a TV or a Desktop Light. the value (0/1) defines whether the appliance is turned on or not. The begin/end looks like this:

begin: 2012-12-01 00:00:00, end: 2012-12-01 08:32:33

Now what I want to know is how do I check the value for the time/date: 2012-12-01 at 00:30 ? Do I create a list containing the possible times:

times = [00:00, 00:05, ... 12:00, 12:05, ... 23:50, 23:55, 24:00]

iterate over it and ckeck if the item is in begin or end? How do I best accomplish this?

wagner-felix
  • 855
  • 3
  • 9
  • 19
  • 2
    If I understand your question correctly, you're trying to create a query to see if a date time falls within the start/end range? If that's correct, you can use __range: https://docs.djangoproject.com/en/dev/ref/models/querysets/#range – themanatuf Mar 12 '13 at 11:27
  • @themanatuf Hmm, not quite, what i want to query is what the value is on a specific time (at 08:00). So 7*24*12 (for 7 days, every 5 minues) queries. However that is already a starting point. – wagner-felix Mar 12 '13 at 11:35
  • There are can be several "begin-end" periods for one node per one day, aren't it? Other words: several instances of `Measurement` class for one node per one day? – Denis Nikanorov Mar 12 '13 at 13:15

1 Answers1

0

Iterating through the time intervals in a clean way is easy - you can write an iterator function like this:

def itertime(start, end, int_step):
    current_time = start
    step = datetime.timedelta(0, int_step)
    while current_time < end:
        yield current_time
        current_time += step

And use it in a for statement to get a tme measurement for each line of your CSV file:

for time in itertime(start_time, end_time, step=5 * 60):
     ...

Now, what you need is not that simple - it is tricky and have a feeling of "old time -have-to-think-about-it problems." But let me try to summarize the steps you have to achieve. I can't code it, or I'd be plainly working for you, thought Python invites that

Read all the measurements you want to take in account 
(use a simple query like Measurement.objects.filter(end__gte=begin_time,
     begin__lte=end_time) )
get all the nodes in your query
for each node:     
    - get the initial state of each node at "begin_time" and annotate it in
       a dictionary with the current state of each node
    - calculate a "next_change" time in each node - determine the time
        of next state change (either its begin, or its end, if the begin is in the past)
    - push then into a n ordered data structure, such as a list 
          maintained with Python's heapq based on this 
          next_state_change" time-stamp

Then start your CSV files, with headers and first value line (from the dictionary
         with the current state)
Loop through your time stamps along the snippet above, and for
               each timestamp:
      - pick measurements from your list until "nest_state_change" is
              after your timestamp. For each of them:
            - if "end" is in the future, annotate that as "next_state_change" and 
                  push it back on the heapq
            - update the device state on your nodes dictionary
      - write a new row to your CSV file

And that is about it. Check my answer here: heapq with custom compare predicate for a practical way to use Python's heapq

Community
  • 1
  • 1
jsbueno
  • 99,910
  • 10
  • 151
  • 209