Ejemplo n.º 1
0
class Simulation:
    """Quasi wrapper class for our simulation"""

    def __init__(self, SpeedLimit=0.5, RandomChanges=10):
        """initialize our simulation"""
        print "Simulation.init()"
        self.translate = [
            1001,
            1002,
            1003,
            1004,
            1032,
            1034,
            1101,
            1102,
            1131,
            1201,
            1202,
            1232,
            1301,
            1302,
            1303,
            1331,
            1333,
            1401,
            1402,
            1403,
            1431,
            2000,
            2030,
            2100,
            2130,
            2201,
            2202,
            2203,
            2233,
            2301,
            2302,
            2332,
            2400,
            2401,
            2402,
            2403,
            2404,
            2405,
            2406,
            2407,
            2408,
            2409,
            2410,
            2411,
            2438,
            2501,
            2502,
            2503,
            2533,
            2600,
            2601,
            2602,
            2603,
            2604,
            2605,
            2606,
            2607,
            2608,
            2609,
            2610,
            2611,
            2612,
            2613,
            2614,
            2615,
            2616,
            2617,
            2618,
            2619,
            2620,
            2621,
            2630,
            2631,
            2634,
            2637,
            2638,
            2901,
            2902,
            3101,
            3102,
            3103,
            3104,
            3105,
            3133,
            3135,
            3201,
            3202,
            3203,
            3204,
            3205,
            3234,
            3301,
            3302,
            3303,
            3304,
            3305,
            3333,
            3401,
            3402,
            3403,
            3404,
            3405,
            3432,
            3433,
            3501,
            3531,
            3601,
            3631,
            3701,
            3731,
            3801,
            3802,
            3803,
            3804,
            3805,
            3806,
            3831,
            3835,
            3836,
            3891,
            3892,
            3893,
            3894,
            3895,
            3896,
            3897,
            3901,
            3902,
            3903,
            3904,
            3905,
            3906,
            3907,
            3908,
            3909,
            3910,
            3911,
            3912,
            3913,
            3914,
            3915,
            3916,
            3917,
            3918,
            3919,
            3920,
            3921,
            3922,
            3923,
            3924,
            3925,
            3926,
            3931,
            3932,
            3933,
            4001,
            4002,
            4003,
            4004,
            4005,
            4006,
            4007,
            4008,
            4009,
            4010,
            4031,
            4035,
            4039,
            4090,
            4091,
            4092,
            4093,
            4094,
            4095,
            4096,
            4097,
            4101,
            4102,
            4103,
            4104,
            4131,
            4132,
            4201,
            4202,
            4203,
            4204,
            4231,
            4232,
            5001,
            5002,
            5003,
            5004,
            5031,
            5032,
            6101,
            6102,
            6103,
            6104,
            6132,
            6201,
            6202,
            6203,
            6204,
            6205,
            6231,
            6235,
            6301,
            6302,
            6303,
            6304,
            6305,
            6333,
            6335,
            6401,
            6402,
            6403,
            6404,
            6433,
            6501,
            6502,
            6503,
            6504,
            6505,
            6506,
            6507,
            6508,
            6509,
            6510,
            6533,
            7001,
            7002,
            7031,
            7032,
            8001,
            8002,
            8003,
            8004,
            8005,
            8033,
            8034,
        ]

        self.SpeedLimit = SpeedLimit  # don't spam solver
        self.RandomChanges = RandomChanges  # only 1 in X chance of new random data

        # Setup sim from master file
        psse_raw = open(IMPORT_FILE)
        self.simCase = Case.load_psse(psse_raw)
        self.simSolver = NewtonPF(self.simCase)
        self.simSolver.solve()
        psse_raw.close()

        # Setup async actions
        self.asyncActions = GetAsyncActions()
        self.asyncActions.setDaemon(True)  # so ctrl-c works
        self.asyncActions.start()

    def bustoID(self, busNumber=0):
        """helper to translate Bus # to ID"""
        return self.translate[busNumber]

    def idtoBus(self, idNumber=0):
        """helper to translate ID to Bus #"""
        return self.translate.index(idNumber)

    def setBusQ(self, bus, Q):
        """helper to set bus Q value"""
        self.simCase.buses[self.idtoBus(bus)].q_demand = Q

    def setBusP(self, bus, P):
        """helper to set bus P value"""
        self.simCase.buses[self.idtoBus(bus)].p_demand = P

    def addRandomness(self):
        """change something sometimes"""
        if random.randint(0, self.RandomChanges) == 0:
            if random.randint(0, 1) == 0:
                # change a P
                # TODO change awkward syntax
                self.setBusP(self.bustoID(random.randint(1, len(self.simCase.buses)) - 1), random.random() * 100)
            else:
                # change a Q
                # TODO change awkward syntax
                self.setBusQ(self.bustoID(random.randint(1, len(self.simCase.buses)) - 1), random.random() * 10)

    def actionQueue(self):
        """loop over all available actions and set appropriate values."""
        while len(self.asyncActions.ActionQueue):
            action = self.asyncActions.ActionQueue.pop()  # grab next action
            print "Action:", action  # TODO remove debugging

            # Handle each action:
            if ("P" in action) and (action["P"] != 0):
                self.setBusP(action["Id"], action["P"])

            if ("Q" in action) and (action["Q"] != 0):
                self.setBusQ(action["Id"], action["Q"])

            # TODO handle toggling a branch
            # if ("Status" in action) and (action["Status"] == False):
            #  simCase.branches[branch].online = action["Status"]
            ## TODO add more actions maybe

    def Solve(self):
        """Solve the simulation
    TODO back off changed values
    """
        # Add some randomness to model for visual pleasure
        self.addRandomness()

        # Handle all things in queue
        self.actionQueue()

        # Solve the actual model
        a = time.time()
        self.simSolver.solve()
        b = time.time()
        if (b - a) < self.SpeedLimit:
            time.sleep(self.SpeedLimit)
        else:
            print "time to solve: %5.2fs" % (b - a)  # TODO remove debugging

    def Output(self):
        """provide array of key:value bus information"""
        out = []
        for i in range(len(self.simCase.buses)):
            out.append(
                {
                    "Id": self.bustoID(i),
                    "Angle": self.simCase.buses[i].v_angle,
                    "Mag": self.simCase.buses[i].v_magnitude,
                    #'Frq':self.simCase.simCase.buses[i],
                    "Status": True,
                }
            )
        # print out[0]
        return out