1 | # Some common objects for RPC communication
|
---|
2 |
|
---|
3 | #------------------------------------------------------------------------------
|
---|
4 |
|
---|
5 | from . import const
|
---|
6 | from .gates import lhbpGates
|
---|
7 |
|
---|
8 | #------------------------------------------------------------------------------
|
---|
9 |
|
---|
10 | class Plane(object):
|
---|
11 | """Information about an airplane in the fleet."""
|
---|
12 | _jsonAttributes = ["tailNumber", "aircraftType",
|
---|
13 | "dow", "dowNumCabinCrew", "maxPassengers",
|
---|
14 | "fuselageLength", "wingSpan"]
|
---|
15 |
|
---|
16 | @staticmethod
|
---|
17 | def str2status(letter):
|
---|
18 | """Convert the given letter into a plane status."""
|
---|
19 | return const.PLANE_HOME if letter=="H" else \
|
---|
20 | const.PLANE_AWAY if letter=="A" else \
|
---|
21 | const.PLANE_PARKING if letter=="P" else \
|
---|
22 | const.PLANE_UNKNOWN
|
---|
23 |
|
---|
24 | @staticmethod
|
---|
25 | def status2str(status):
|
---|
26 | """Convert the given status into the corresponding letter code."""
|
---|
27 | return "H" if status==const.PLANE_HOME else \
|
---|
28 | "A" if status==const.PLANE_AWAY else \
|
---|
29 | "P" if status==const.PLANE_PARKING else ""
|
---|
30 |
|
---|
31 | @staticmethod
|
---|
32 | def fromJSON(data):
|
---|
33 | """Create a Plane object from the given JSON data."""
|
---|
34 | plane = Plane()
|
---|
35 |
|
---|
36 | for attributeName in Plane._jsonAttributes:
|
---|
37 | setattr(plane, attributeName, data[attributeName])
|
---|
38 | plane.status = const.PLANE_AWAY
|
---|
39 | plane.gateNumber = "-"
|
---|
40 |
|
---|
41 | return plane
|
---|
42 |
|
---|
43 | @property
|
---|
44 | def hasStairs(self):
|
---|
45 | """Indicate if the plane has its own stairs."""
|
---|
46 | return self.aircraftType in [const.AIRCRAFT_YK40,
|
---|
47 | const.AIRCRAFT_CRJ2,
|
---|
48 | const.AIRCRAFT_F70,
|
---|
49 | const.AIRCRAFT_DH8D]
|
---|
50 |
|
---|
51 | def toJSON(self):
|
---|
52 | """Create a JSON representation of the Plane object from the given JSON data."""
|
---|
53 | data = {}
|
---|
54 | for attributeName in Plane._jsonAttributes:
|
---|
55 | data[attributeName] = getattr(self, attributeName)
|
---|
56 | return data
|
---|
57 |
|
---|
58 | def _setStatus(self, letter):
|
---|
59 | """Set the status from the given letter."""
|
---|
60 | self.status = Plane.str2status(letter)
|
---|
61 |
|
---|
62 | def __repr__(self):
|
---|
63 | """Get the representation of the plane object."""
|
---|
64 | s = "<Plane: %s %s" % (self.tailNumber,
|
---|
65 | "home" if self.status==const.PLANE_HOME else \
|
---|
66 | "away" if self.status==const.PLANE_AWAY else \
|
---|
67 | "parking" if self.status==const.PLANE_PARKING \
|
---|
68 | else "unknown")
|
---|
69 | if self.gateNumber is not None:
|
---|
70 | s += " (gate " + self.gateNumber + ")"
|
---|
71 | s += ">"
|
---|
72 | return s
|
---|
73 |
|
---|
74 | #------------------------------------------------------------------------------
|
---|
75 |
|
---|
76 | class Fleet(object):
|
---|
77 | """Information about the whole fleet."""
|
---|
78 | @staticmethod
|
---|
79 | def fromJSON(data):
|
---|
80 | """Load the fleet data from the given JSON file."""
|
---|
81 | fleet = Fleet()
|
---|
82 | for planeData in data:
|
---|
83 | fleet._addPlane(Plane.fromJSON(planeData))
|
---|
84 | return fleet
|
---|
85 |
|
---|
86 | def __init__(self):
|
---|
87 | """Construct the fleet information by reading the given file object."""
|
---|
88 | self._planes = {}
|
---|
89 |
|
---|
90 | def isGateConflicting(self, plane):
|
---|
91 | """Check if the gate of the given plane conflicts with another plane's
|
---|
92 | position."""
|
---|
93 | gate = lhbpGates.find(plane.gateNumber)
|
---|
94 | for p in self._planes.values():
|
---|
95 | if p.tailNumber!=plane.tailNumber and \
|
---|
96 | p.status==const.PLANE_HOME:
|
---|
97 | if p.gateNumber==plane.gateNumber:
|
---|
98 | return True
|
---|
99 | if gate is not None and not gate.isAvailable(plane,
|
---|
100 | lhbpGates,
|
---|
101 | [p.gateNumber]):
|
---|
102 | return True
|
---|
103 |
|
---|
104 | return False
|
---|
105 |
|
---|
106 | def getOccupiedGateNumbers(self):
|
---|
107 | """Get a set containing the numbers of the gates occupied by planes."""
|
---|
108 | gateNumbers = set()
|
---|
109 | for p in self._planes.values():
|
---|
110 | if p.status==const.PLANE_HOME and p.gateNumber:
|
---|
111 | gateNumbers.add(p.gateNumber)
|
---|
112 | return gateNumbers
|
---|
113 |
|
---|
114 | def iterAvailableLHBPGates(self, tailNumber):
|
---|
115 | """Iterate over the available gates at LHBP."""
|
---|
116 | occupiedGateNumbers = self.getOccupiedGateNumbers()
|
---|
117 | plane = self.__getitem__(tailNumber)
|
---|
118 | for gate in lhbpGates.gates:
|
---|
119 | if gate.isAvailable(plane, lhbpGates, occupiedGateNumbers):
|
---|
120 | yield gate
|
---|
121 |
|
---|
122 | def updatePlane(self, tailNumber, status, gateNumber = None):
|
---|
123 | """Update the status of the given plane."""
|
---|
124 | if tailNumber in self._planes:
|
---|
125 | plane = self._planes[tailNumber]
|
---|
126 | plane.status = status
|
---|
127 | plane.gateNumber = gateNumber
|
---|
128 |
|
---|
129 | def toJSON(self):
|
---|
130 | """Convert the fleet into a JSON data."""
|
---|
131 | return [plane.toJSON() for plane in self._planes.values()]
|
---|
132 |
|
---|
133 | def _addPlane(self, plane):
|
---|
134 | """Add the given plane to the fleet."""
|
---|
135 | self._planes[plane.tailNumber] = plane
|
---|
136 |
|
---|
137 | def __iter__(self):
|
---|
138 | """Get an iterator over the planes."""
|
---|
139 | for plane in self._planes.values():
|
---|
140 | yield plane
|
---|
141 |
|
---|
142 | def __getitem__(self, tailNumber):
|
---|
143 | """Get the plane with the given tail number.
|
---|
144 |
|
---|
145 | If the plane is not in the fleet, None is returned."""
|
---|
146 | return self._planes[tailNumber] if tailNumber in self._planes else None
|
---|
147 |
|
---|
148 | def __repr__(self):
|
---|
149 | """Get the representation of the fleet object."""
|
---|
150 | return self._planes.__repr__()
|
---|