Beispiel #1
0
 def send_decision(self, queue, consumption):
     sellbuy = "buys" if consumption > 0 else "sells"
     cprint(
         self,
         f"[{self.id}] It is I (home {self.id}) who {sellbuy} {abs(consumption)}J to market"
     )
     queue.send(message=str(consumption),
                type=comm_utils.market_transfer_id(self.id))
Beispiel #2
0
    def send_energy(self, queue, destination, count):

        cprint(
            self,
            f"[{self.id}] It is I (home {self.id}) who sends {count}J to home {destination} at slot {comm_utils.energy_transfer_id(destination)}"
        )
        comm_utils.send_energy(queue=queue,
                               amount=count,
                               destination=destination)
        self.policy.given += count
Beispiel #3
0
    def special_weather_things(self, infos):
        if infos is None:
            return

        print(f"[{self.id}] {infos}")
        if infos["Temperature"] < 0:
            cprint(
                self,
                f"[{self.id}] Temperature => consumption : {self.policy.consumption} -> {self.policy.consumption * 2}"
            )
            self.policy.consumption *= 2
def always_sell_excess_behaviour(owner, marketQ, homesQ):
    balance = owner.policy.current_balance()

    if balance >= 0:
        cprint(owner, f"[{owner.id}][always_sell] => i have a positive balance of {balance}, imma sell")
        return True, balance
    else:
        cprint(owner, f"[{owner.id}][always_sell] => in need of {-balance} energy, requesting it")
        comm_utils.request_energy(owner=owner, queue=homesQ, amount=-balance)

    # if balance isnt positive we can still try to get energy from others
    return False, owner.policy.current_balance()
Beispiel #5
0
def fulfill_some_request_sub_behaviour(owner, queue, block=False):
    cprint(owner,
           f"[{owner.id}][fulfill_requests] -> tryna fulfill some requests")
    message, id = comm_utils.get_some_energy_request(queue=queue, block=block)

    # check for energy requests
    if None not in (message, id):
        asked = float(message)
        sent = min(asked, owner.policy.current_balance()
                   )  # give the max we can without being in deficit
        cprint(
            owner,
            f"[{owner.id}][fulfill_requests] => {id - 1} asked for {asked} energy, imma give u {sent} bro"
        )
        if sent > 0:  # asked > 0 so if sent < 0 it means we are in deficit and we dont wanna get more debts
            owner.send_energy(
                queue=queue,
                destination=comm_utils.inverse_energy_request_id(id),
                count=sent)
    else:
        # cprint(owner, f"[{owner.id}][fulfill_requests] => aint no requests for me to fulfill imma keep my energy")
        pass
Beispiel #6
0
    def run(self):
        cprint(self, f"[{self.id}] hi from house #{self.id}")

        # open needed queues
        market_queue = sysv_ipc.MessageQueue(key=self.market_queue_key)
        homes_queue = sysv_ipc.MessageQueue(key=self.homes_queue_key)

        last_market_infos = None
        while True:
            # TODO          maybe migrate home from thread to process and multithread home so that
            # TODO-bis      exchanges and communication are done in parallel

            self.special_weather_things(
                infos=last_market_infos
            )  # special actions to take in regards to current market state

            # trading energy with homes until market asks us for an decision
            result, infos = self.policy.execute(
                owner=self, comm=(market_queue, homes_queue))  # blocking op
            # result is how much the home wants to buy/sell, if result > 0 we sell or else we buy

            if result is None:  # just in case
                result = self.policy.last_decision
            if infos is not None:
                try:
                    last_market_infos = json.loads(infos)
                except Exception:
                    pass

            # tell the market how much we want
            self.send_decision(
                queue=market_queue, consumption=-result
            )  # blocking # take opposite of decision bc for market negative consumption is selling
            self.policy.reset(
            )  # reset production / consumption / given energy / received energy state for next tick

            sleep(self.interval)
Beispiel #7
0
def sell_if_no_takers_behaviour(owner, marketQ, homesQ):
    balance = owner.policy.current_balance()

    if balance == 0:
        cprint(
            owner,
            f"[{owner.id}][no_takers->sell] => i have exactly 0 energy left, i'm done"
        )
        return True, balance
    elif balance > 0:  # if we have a surplus of energy we sell it
        cprint(
            owner,
            f"[{owner.id}][no_takers->sell] => i have {balance} excess, i'm tryna give sum"
        )
        fulfill_some_request_sub_behaviour(owner, homesQ, block=False)
    else:  # when in need of energy
        cprint(
            owner,
            f"[{owner.id}][no_takers->sell] => im thirsty for energy, gimme {-balance} pls"
        )
        comm_utils.request_energy(owner=owner, queue=homesQ,
                                  amount=-balance)  # -balance bc balance < 0

    return False, owner.policy.current_balance()
Beispiel #8
0
    def execute(self, owner, comm):

        marketQ = comm[0]
        homesQ = comm[1]

        # timeout system
        decision = None
        market_msg = None
        start = time.time()
        while (time.time() - start) < owner.slot_timeout:
            if market_msg is None:  # if market hasn't contacted us yet
                # check if we have a msg from market
                market_msg = comm_utils.get_last_message(
                    queue=marketQ,
                    type_id=comm_utils.market_request_id(owner.id))
                # we store the last time we checked and we didn't have a message, this reset the timeout
                if market_msg is None:
                    start = time.time()
                    cprint(
                        owner,
                        f"[{owner.id}][policy] -> still no msg... {market_msg}"
                    )
                else:
                    cprint(
                        owner,
                        f"[{owner.id}][policy] -> msg from market !!!! {market_msg} starting slot timeout"
                    )

            # accept energy transfers
            if owner.policy.has_pending_request:
                comm_utils.accept_energy_transfers_if_any(owner=owner,
                                                          queue=homesQ)

            # heuristic/behaviour returns (done, value)
            decision = self.behaviour(owner, marketQ=marketQ, homesQ=homesQ)
            if decision[0]:  # if done
                self.last_decision = decision[1]
                cprint(owner, f"[{owner.id}][policy] => i'm done!")
                break

            # sleep the required interval or less to answer the market's request in time
            time_left = abs(owner.slot_timeout - (time.time() - start))
            time.sleep(
                owner.interval if owner.interval < time_left else time_left)

        cprint(owner, f"[{owner.id}][policy] -> bitch i'm out")
        # just in case
        if self.has_pending_request:
            comm_utils.cancel_request(
                owner=owner, queue=homesQ
            )  # protects ourselves from receiving new energy transfers
            comm_utils.accept_energy_transfers_if_any(owner=owner,
                                                      queue=homesQ)

        # if we're done without being contacted by market we wait for it
        if market_msg is None:
            cprint(
                owner,
                f"[{owner.id}][policy] waiting on mailbox {comm_utils.market_request_id(owner.id)}"
            )
            market_msg = comm_utils.get_last_message(
                queue=marketQ,
                type_id=comm_utils.market_request_id(owner.id),
                block=True)  # blocking
            cprint(owner,
                   f"[{owner.id}][policy] -> market told me '{market_msg}'")

        return decision[1], market_msg