示例#1
0
def test_generate_instruction_candidates(asset: AssetFactory, boa: BOAFactory) -> None:
    """Since each sub-function is tested more thoroughly and directly
    this is only tested in a high-level way."""
    states = KeyStore(
        keys=get_keys(AssetState),
        objects={
            AssetStateFactory(
                asset=asset,
                start=boa.start - timedelta(hours=1),
                end=boa.end + timedelta(hours=1),
                available=True,
                charge=200,
            )
        }
    )
    instructions = KeyStore(
        keys=get_keys(Instruction),
        objects=[],
    )

    output = generate_instruction_candidates(
        boa=boa,
        states=states,
        instructions=instructions,
        execution_time=datetime(2000, 1, 1),
    )

    assert len(output) == 21
示例#2
0
def get_prior_instruction_fixtures(asset: Asset) -> Dict:
    """Fixtures associated with the test_get_prior_instruction tests."""

    past_2 = InstructionFactory(asset=asset, end=datetime(1999, 12, 31, 0))
    past_1 = InstructionFactory(asset=asset, end=datetime(1999, 12, 31, 12))
    future_1 = InstructionFactory(asset=asset, end=datetime(2000, 1, 1, 12))
    future_2 = InstructionFactory(asset=asset, end=datetime(2000, 1, 2))
    other_1 = InstructionFactory()
    other_2 = InstructionFactory()

    return {
        # 1: Single asset, instruction before time exists
        1: {
            "asset":
            asset,
            "time":
            datetime(2000, 1, 1, 0, 0),
            "instructions":
            KeyStore(
                keys=get_keys(Instruction),
                objects=[past_2, past_1, future_1, future_2, other_1, other_2],
            ),
            "output":
            past_1
        },
        # 2: Single asset, instruction before time does not exist
        2: {
            "asset":
            asset,
            "time":
            datetime(2000, 1, 1, 0, 0),
            "instructions":
            KeyStore(
                keys=get_keys(Instruction),
                objects=[future_1, future_2, other_1, other_2],
            ),
            "output":
            None
        },
        # 3: Different asset only
        3: {
            "asset":
            asset,
            "time":
            datetime(2000, 1, 1, 0, 0),
            "instructions":
            KeyStore(
                keys=get_keys(Instruction),
                objects=[other_1, other_2],
            ),
            "output":
            None
        },
    }
示例#3
0
def test_key_store__get(key_store: KeyStore):
    output = key_store.get(name="One")
    assert len(output) == 1
    assert output[0].name == "One"
    assert key_store._cache[(
        "One",
        None,
    )] == output

    output = key_store.get(capacity=0)
    assert len(output) == 3
    assert len(key_store._cache) == 2
示例#4
0
def test_run_engine(assets: Tuple[Asset], ramp_rates: Dict,
                    asset_mw: Dict[str, int]) -> None:

    boa = BOAFactory(
        mw=10,
        offer__price_mw_hr=10,
        offer__bmu__assets=tuple(assets),
        start=datetime(2020, 1, 1, 1),
        end=datetime(2020, 1, 1, 4),
    )
    candidates = [
        Candidate(
            asset=asset,
            boa=boa,
            mw=mw,
        ) for asset in assets for mw in [0, 5, 10] if abs(mw) <= asset.capacity
    ]
    rates = KeyStore(
        keys=get_keys(Rate),
        objects=[
            RateFactory(asset=asset, **ramp_rates.get(asset.name, {}))
            for asset in assets
        ],
    )

    solution = run_engine(
        boa=boa,
        rates=rates,
        candidates=candidates,
    )

    assert len(solution.instructions) == len(asset_mw)

    for instruction in solution.instructions:
        assert asset_mw[instruction.asset.name] == instruction.mw
示例#5
0
def key_store() -> KeyStore:
    return KeyStore(keys=["name", "capacity"],
                    objects=[
                        AssetFactory(name="One", capacity=0),
                        AssetFactory(name="Two", capacity=0),
                        AssetFactory(name="Three", capacity=0),
                    ])
示例#6
0
def test_key_store__get_one_or_none(key_store: KeyStore):
    output = key_store.get_one_or_none(name="One")
    assert output is not None
    assert output.name == "One"
    assert key_store._cache[(
        "One",
        None,
    )] == [output]
示例#7
0
def balance_a_bmu(
    input_filepath: str,
    output_filepath: Optional[str] = None,
    do_visualise: bool = False,
) -> Solution:

    data = load_input_data(filepath=input_filepath)
    rates = KeyStore(keys=get_keys(Rate), objects=data.rates)

    # Pre-solve
    candidates = generate_instruction_candidates(
        boa=data.boa,
        states=KeyStore(keys=get_keys(AssetState), objects=data.states),
        instructions=KeyStore(keys=get_keys(Instruction),
                              objects=data.instructions),
        execution_time=data.parameters.execution_time,
    )

    # Engine
    solution = run_engine(
        boa=data.boa,
        rates=rates,
        candidates=candidates,
    )

    # Post-solve
    if output_filepath is not None:
        dump_solution(filepath=output_filepath, solution=solution)

    if do_visualise:
        visualise(
            boa=data.boa,
            rates=rates,
            candidates=KeyStore(keys=get_keys(Candidate), objects=candidates),
            instructions=KeyStore(keys=get_keys(Instruction),
                                  objects=solution.instructions),
        )

    return solution
示例#8
0
def get_items_for_period(
        items: KeyStore,
        start: datetime,
        end: datetime,
        **kwargs
) -> List:
    """Given a keystore of items and a period return
    a list of the items that overlap the period."""
    return [
        item
        for item in items.get(**kwargs)
        if date_range_overlap(
            start_1=start, end_1=end,
            start_2=item.start, end_2=item.end,
        ) > 0
    ]
示例#9
0
def get_item_at_time(
        items: KeyStore,
        time: datetime,
        nullable: bool = False,
        **kwargs
) -> Optional:
    """Given a keystore of items and a time,
    return the item at that time if it exists,
    otherwise return none."""
    items_at_time = [
        item
        for item in items.get(**kwargs)
        if item.start <= time <= item.end
    ]

    if len(items_at_time) == 0 and nullable:
        return None

    elif len(items_at_time) != 1:
        raise RuntimeError(
            f"Only expected one item for {kwargs} at {time} got {items_at_time}"
        )

    return items_at_time[0]
示例#10
0
def asset_can_be_assigned_to_boa_fixtures(
        asset: AssetFactory,
        boa: BOAFactory,
        previous_instruction: InstructionFactory,
        current_instruction: InstructionFactory,
) -> Dict[int, Dict[str, Any]]:

    keys = get_keys(AssetState)
    state_available = AssetStateFactory(
        asset=asset,
        start=datetime(2000, 1, 1),
        end=datetime(2000, 2, 1),
        available=True,
    )

    return {
        # 1: Asset can be assigned, withOUT previous and current
        1: {
                "boa": boa,
                "states": KeyStore(
                    keys=keys,
                    objects=[state_available],
                ),
                "output": True,
        },
        # 2: Asset can be assigned, with previous and current
        2: {
            "boa": boa,
            "states": KeyStore(
                keys=keys,
                objects=[state_available],
            ),
            "current_instruction": current_instruction,
            "prior_instruction": previous_instruction,
            "output": True,
        },
        # 3: Asset does not respect availability
        3: {
            "boa": boa,
            "states": KeyStore(
                keys=keys,
                objects=[
                    state_available,
                    AssetStateFactory(
                        asset=asset,
                        start=datetime(2000, 1, 1),
                        end=datetime(2000, 2, 1),
                        available=False,
                    )
                ]
            ),
            "output": False,
        },
        # 4: Asset does not respect min zero time
        4: {
            "boa": boa,
            "states": KeyStore(
                keys=keys,
                objects=[state_available],
            ),
            "prior_instruction": InstructionFactory(end=datetime(2000, 1, 1, 9)),
            "output": False,
        },
        # 5: Asset does not respect min non-zero time withOUT current instr
        5: {
                "boa": BOAFactory(
                    start=datetime(2000, 1, 1, 0, 0),
                    end=datetime(2000, 1, 1, 0, 1),
                ),
                "states": KeyStore(
                    keys=keys,
                    objects=[state_available],
                ),
                "output": False,
        },
        # 6: Asset does not respect min non-zero time with current instr
        6: {
            "boa": BOAFactory(
                start=datetime(2000, 1, 1, 0, 1),
                end=datetime(2000, 1, 1, 0, 3),
            ),
            "states": KeyStore(
                keys=keys,
                objects=[state_available],
            ),
            "current_instruction": InstructionFactory(
                start=datetime(2000, 1, 1, 0, 0),
                end=datetime(2000, 1, 1, 0, 2),
            ),
            "output": False,
        },
    }
示例#11
0
                end=datetime(2000, 1, 2, 1),
                type="Fruit")
ITEM_THREE = Item(name="Carrot",
                  start=datetime(2000, 1, 1),
                  end=datetime(2000, 1, 1, 1),
                  type="Vegetable")
ITEM_FOUR = Item(name="Carrot",
                 start=datetime(2000, 1, 3),
                 end=datetime(2000, 1, 3, 1),
                 type="Vegetable")

TEST_KEY_STORE = KeyStore(
    keys=["name", "time", "type"],
    objects=[
        ITEM_ONE,
        ITEM_TWO,
        ITEM_THREE,
        ITEM_FOUR,
    ],
)


@pytest.mark.parametrize(
    "items, time, nullable, kwargs, expected_output",
    [
        # No items at time, nullable
        (
            TEST_KEY_STORE,
            datetime(2000, 1, 10),
            True,
            {},
示例#12
0
def test_key_store__get_one_or_none__none(key_store: KeyStore):
    output = key_store.get_one_or_none(name="Other")
    assert key_store._cache == {}
    assert output is None