diff options
| author | Mattias Andrée <maandree@kth.se> | 2016-07-06 19:38:52 +0200 | 
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2016-07-06 19:38:52 +0200 | 
| commit | c2ae4f7c534c854488d5b7f3bc9d432c31acf9d5 (patch) | |
| tree | 5a526c321b2e901d3d2bae8e7b9d16b1ba11d2d0 | |
| parent | Parse command line (diff) | |
| download | blue-c2ae4f7c534c854488d5b7f3bc9d432c31acf9d5.tar.gz blue-c2ae4f7c534c854488d5b7f3bc9d432c31acf9d5.tar.bz2 blue-c2ae4f7c534c854488d5b7f3bc9d432c31acf9d5.tar.xz | |
The rest of the program
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
| -rwxr-xr-x | blue.py | 159 | 
1 files changed, 148 insertions, 11 deletions
| @@ -8,27 +8,34 @@ import solar_python as sol  loc = None  stop_date = None  human = False +unix = False +local = False  noon = False +night = False  blue = False  gold = False  unblue = False  ungold = False  morning = []  evening = [] -deriv = [] +dderiv = [] +nderiv = [] +res = '1s'  ## Parse command line  argv0 = sys.argv[0] if len(sys.argv) > 0 else 'blue'  def usage(): -    opts = '[-e elev]* [-m elev]* [-d delev]* [-l lat:lon | -l loc] [-s year-month-day | -s -] [-bBgGhn]' +    opts  =  '[-d delev]* [-D delev]* [-e elev]* [-m elev]* [-h [-L] | -u | -L]' +    opts += ' [-l lat:lon | -l loc] [-s year-month-day | -s -] [-r num[h|m|s]]' +    opts += ' [-bBgGnN]'      print('Usage: %s %s' % (argv0, opts), file = sys.stderr)      sys.exit(1)  i, n = 1, len(sys.argv)  def getarg():      global i, j, n, m      if j < m: -        rc = arg[j] +        rc = arg[j:]          j = m          return rc      else: @@ -42,13 +49,15 @@ while i < n:      if arg == '--':          i += 1          break -    elif arg.startwith('-'): +    elif arg.startswith('-'):          j, m = 1, len(arg)          while j < m:              c = arg[j]              j += 1              if c == 'd': -                deriv.append(getarg()) +                dderiv.append(getarg()) +            elif c == 'D': +                nderiv.append(getarg())              elif c == 'e':                  evening.append(getarg())              elif c == 'm': @@ -57,6 +66,8 @@ while i < n:                  loc = getarg()              elif c == 's':                  stop_date = getarg() +            elif c == 'r': +                res = getarg()              elif c == 'b':                  blue = True              elif c == 'B': @@ -67,15 +78,34 @@ while i < n:                  ungold = True              elif c == 'h':                  human = True +            elif c == 'u': +                unix = True +            elif c == 'L': +                local = True              elif c == 'n':                  noon = True +            elif c == 'N': +                night = True              else:                  usage() -            j += 1          i += 1      else:          break -if i != n: +if i != n or (human and unix): +    usage() + + +## Parse resolution +if len(res) < 2: +    usage() +mul = {'s' : 1.0, 'm' : 60.0, 'h' : 60 * 60.0} +suffix = res[-1] +value = res[:-1] +if '.' in value: +    usage() +try: +    res = int(value) * mul[suffix] +except:      usage() @@ -83,7 +113,8 @@ if i != n:  try:      evening = [float(e) for e in evening]      morning = [float(e) for e in morning] -    deriv   = [float(e) for e in deriv] +    dderiv  = [float(e) for e in dderiv] +    nderiv  = [float(e) for e in nderiv]      for e in evening + morning:          if abs(e) > 90:              usage() @@ -91,7 +122,7 @@ except:      usage() -## Parse -bBgGn +## Parse -bBgGnN  if blue:      morning.append(sol.SOLAR_ELEVATION_RANGE_BLUE_HOUR[0])      evening.append(sol.SOLAR_ELEVATION_RANGE_BLUE_HOUR[1]) @@ -105,11 +136,13 @@ if ungold:      morning.append(sol.SOLAR_ELEVATION_RANGE_GOLDEN_HOUR[1])      evening.append(sol.SOLAR_ELEVATION_RANGE_GOLDEN_HOUR[0])  if noon: -    deriv.append(0.0) +    dderiv.append(0.0) +if night: +    nderiv.append(0.0)  ## Fallback options -if len(morning) == 0 and len(evening) == 0 and len(deriv) == 0: +if len(morning) == 0 and len(evening) == 0 and len(dderiv) == 0 and len(nderiv) == 0:      morning.append(sol.SOLAR_ELEVATION_RANGE_BLUE_HOUR[0])      evening.append(sol.SOLAR_ELEVATION_RANGE_BLUE_HOUR[1]) @@ -204,3 +237,107 @@ else:      stop_time += 24 * 60 * 60      stop_time -= (time.altzone if is_summer else time.timezone) + +def get_elev(elev, start, morning): +    end = start + 0.0099 +    while start < end: +        rc = sol.future_elevation(lat, lon, elev, start) +        if rc is None: +            return (None, end) +        else: +            start = rc + 1e-06 +            d  = sol.solar_elevation(lat, lon, rc + 3e-09) +            d -= sol.solar_elevation(lat, lon, rc) +            if d >= 0 if morning else d <= 0: +                return (sol.julian_centuries_to_epoch(rc), start) +    return (None, end) + +def get_deriv(delev, start, daytime): +    end = start + 0.0099 +    while start < end: +        rc = sol.future_elevation_derivative(lat, lon, delev, start) +        if rc is None: +            return (None, end) +        else: +            start = rc + 1e-06 +            elev = sol.solar_elevation(lat, lon, rc) +            if elev >= 0 if daytime else elev <= 0: +                return (sol.julian_centuries_to_epoch(rc), start) +    return (None, end) + +def get_morning(elev, start): +    return get_elev(elev, start, True) + +def get_evening(elev, start): +    return get_elev(elev, start, False) + +def get_day(delev, start): +    return get_deriv(delev, start, True) + +def get_night(delev, start): +    return get_deriv(delev, start, False) + +now = sol.epoch_to_julian_centuries(time.time()) +class State: +    def __init__(self, val, fun): +        self.start = now +        self.val = val +        self.fun = fun +    def next(self): +        (rc, self.start) = self.fun(self.val, self.start) +        return (rc, self.start) + +morning = [State(v, get_morning) for v in morning] +evening = [State(v, get_evening) for v in evening] +dderiv  = [State(v, get_day)     for v in dderiv] +nderiv  = [State(v, get_night)   for v in nderiv] +states  = morning + evening + dderiv + nderiv + + +# So we can stop of the pipe breaks (useful with -s -) +def print(msg): +    msg = (str(msg) + '\n').encode('utf-8') +    ptr, n = 0, len(msg) +    while ptr < n: +        ptr += os.write(1, msg[ptr:]) + +def parse_time(t, localtime, tzname): +    tm = time.localtime(t) if localtime else time.gmtime(t) +    if localtime and tm.tm_isdst < 0: +        tm = time.gmtime(t) +        localtime = False +    if not localtime: +        tz = 'UTC' if tzname else 'Z' +    else: +        tz = time.strftime('%Z' if tzname else '%z', tm) +    return (tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tz) + +jc_stop_time = sol.epoch_to_julian_centuries(stop_time) if stop_time is not None else None +months = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') +try: +    while len(states) > 0: +        n = len(states) +        i = 0 +        while i < n: +            (t, s) = states[i].next() +            if t is not None and (stop_time is None or t < stop_time): +                t = int(t / res + 0.5) * res +                if unix: +                    print(int(t)) +                else: +                    t = parse_time(t, local, human) +                    if human: +                        (y, m, d, H, M, S, z) = t +                        t = (y, m, months[m - 1], d, H, M, S, z) +                        print('%i-(%02i)%s-%02i %02i:%02i:%02i %s' % t) +                    else: +                        print('%i-%02i-%02iT%02i:%02i:%02i%s' % t) +            if jc_stop_time is not None and s >= jc_stop_time: +                del states[i] +                n -= 1 +            else: +                i += 1 +except KeyboardInterrupt as e: +    sys.exit(0) +except BrokenPipeError as e: +    sys.exit(0) | 
