def curve(t, acc_t, fast_t, dec_t, slow_t, fast, slow):
    """Returns a speed value between 0 and fast for a given t
       t is the time (a float in seconds), from zero at which point acceleration starts
       typically t would be incrementing in real time as the door is opening/closing
       acc_t is the acceleration time, after which the 'fast' speed is reached
       fast_t is the time spent at the fast speed
       dec_t is the time spent decelarating from fast to slow
       slow_t is the time then spent running at 'slow' speed.
       after acc_t + fast_t + dec_t + slow_t, 0.0 is returned

       fast is the fast speed, provide a float
       slow is the slow speed, provide a float, this is the slow door speed which typically
       would take the door to a limit stop switch."""

    assert fast > slow > 0.0

    duration = acc_t + fast_t + dec_t

    full_duration = duration + slow_t

    if t >= full_duration:
        return 0.0
    if t >= duration:
        return slow

    if t >= acc_t and t <= acc_t + fast_t:
        # during fast time, fast should be returned
        return fast

    # this list must have nine elements describing an acceleration curve from 0.0 to 1.0
    c = [0.0, 0.05, 0.15, 0.3, 0.5, 0.7, 0.85, 0.95, 1.0]

    # increase from 0.0 to fast during acceleration
    if t <= acc_t:
        # first calculate an increase from 0.0 to 1.0
        # scale acc_t to match the list on the acceleration curve
        tacc = t * 8.0 / acc_t    # when acc_t = 8, tacc = t
        lowindex = int(tacc)
        highindex = lowindex + 1
        diff = c[highindex] - c[lowindex]
        y = diff*tacc + c[lowindex] - diff* lowindex
        if y < 0.0:
            y = 0.0
        # scale 1.0 to be fast
        speed = y * fast
        return round(speed, 3)


    # for the deceleration, treat time in the negative direction
    # so rather than a decrease from 1.0 to 0.0, it again looks like
    # an increase from 0.0 to 1.0

    s = duration - t
    if s >= dec_t:
        return fast
    # scale dec_t to match the list on the acceleration curve
    sdec = s * 8.0 / dec_t
    lowindex = int(sdec)
    highindex = lowindex + 1
    diff = c[highindex] - c[lowindex]
    y = diff*sdec + c[lowindex] - diff* lowindex
    if y < 0.0:
        y = 0.0
    # 1.0 should become 'fast' and 0.0 should become 'slow'
    speed = (fast - slow)*y + slow
    return round(speed, 3)