source: src/mlx/pirep.py@ 778:102c31aa3d55

Last change on this file since 778:102c31aa3d55 was 778:102c31aa3d55, checked in by István Váradi <ivaradi@…>, 8 years ago

Some other data is also sent with the PIREP (re #285)

File size: 8.5 KB
RevLine 
[401]1
2from util import utf2unicode
[298]3
4import const
5import cPickle as pickle
[743]6import datetime
7import time
[97]8
9#------------------------------------------------------------------------------
10
[298]11## @package mlx.pirep
12#
13# The PIREP module.
14#
15# This module defines only one class, \ref PIREP. It is used to extract and
16# store the information needed for a PIREP. The saved PIREPs are pickled
17# instances of this class.
[97]18
19#------------------------------------------------------------------------------
20
21class PIREP(object):
22 """A pilot's report of a flight."""
[743]23 _flightTypes = { const.FLIGHTTYPE_SCHEDULED : "SCHEDULED",
24 const.FLIGHTTYPE_OLDTIMER : "OT",
25 const.FLIGHTTYPE_VIP : "VIP",
26 const.FLIGHTTYPE_CHARTER : "CHARTER" }
27
[97]28 @staticmethod
29 def _formatLine(timeStr, line):
30 """Format the given time string and line as needed for the ACARS and
31 some other things."""
32 return "[" + timeStr + "]-[" + line + "]"
[151]33
34 @staticmethod
[743]35 def formatTimestampForRPC(t):
36 """Format the given timestamp for RPC."""
37 return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(t))
38
39 @staticmethod
[151]40 def load(path):
41 """Load a PIREP from the given path.
42
43 Returns the PIREP object, or None on error."""
44 try:
45 with open(path, "rb") as f:
[303]46 pirep = pickle.load(f)
47 if "numCrew" not in dir(pirep):
48 pirep.numCrew = pirep.bookedFlight.numCrew
49 if "numPassengers" not in dir(pirep):
50 pirep.numPassengers = pirep.bookedFlight.numPassengers
51 if "bagWeight" not in dir(pirep):
52 pirep.bagWeight = pirep.bookedFlight.bagWeight
53 if "mailWeight" not in dir(pirep):
54 pirep.mailWeight = pirep.bookedFlight.mailWeight
55 return pirep
[151]56 except Exception, e:
[401]57 print "Failed loading PIREP from %s: %s" % (path,
58 utf2unicode(str(e)))
[151]59 return None
[345]60
[262]61 def __init__(self, flight):
62 """Initialize the PIREP from the given flight."""
63 self.bookedFlight = flight.bookedFlight
[303]64
65 self.numCrew = flight.numCrew
66 self.numPassengers = flight.numPassengers
67 self.bagWeight = flight.bagWeight
[262]68 self.cargoWeight = flight.cargoWeight
[303]69 self.mailWeight = flight.mailWeight
[345]70
[262]71 self.filedCruiseAltitude = flight.filedCruiseAltitude
72 self.cruiseAltitude = flight.cruiseAltitude
73 self.route = flight.route
[97]74
[262]75 self.departureMETAR = flight.departureMETAR.upper()
76 self.arrivalMETAR = flight.arrivalMETAR.upper()
[97]77
[262]78 self.departureRunway = flight.departureRunway.upper()
79 self.sid = flight.sid.upper()
[97]80
[262]81 self.star = flight.star
82 self.transition = flight.transition
83 self.approachType = flight.approachType.upper()
84 self.arrivalRunway = flight.arrivalRunway.upper()
[97]85
[262]86 self.flightType = flight.flightType
87 self.online = flight.online
[97]88
[262]89 self.comments = flight.comments
90 self.flightDefects = flight.flightDefects
91 self.delayCodes = flight.delayCodes
[345]92
[97]93 self.blockTimeStart = flight.blockTimeStart
94 self.flightTimeStart = flight.flightTimeStart
95 self.flightTimeEnd = flight.flightTimeEnd
96 self.blockTimeEnd = flight.blockTimeEnd
97 self.flownDistance = flight.flownDistance
[102]98 self.fuelUsed = flight.startFuel - flight.endFuel
[97]99
[262]100 logger = flight.logger
[97]101 self.rating = logger.getRating()
102 self.logLines = logger.lines
103 self.faultLineIndexes = logger.faultLineIndexes
[345]104
[743]105 @property
[778]106 def flightDateText(self):
107 """Get the text version of the booked flight's departure time."""
108 return self.bookedFlight.departureTime.strftime("%Y-%m-%d")
109
110 @property
[743]111 def flightTypeText(self):
112 """Get the text representation of the flight type."""
113 return PIREP._flightTypes[self.flightType]
114
115 @property
116 def blockTimeStartText(self):
117 """Get the beginning of the block time in string format."""
118 return PIREP.formatTimestampForRPC(self.blockTimeStart)
119
120 @property
121 def flightTimeStartText(self):
122 """Get the beginning of the flight time in string format."""
123 return PIREP.formatTimestampForRPC(self.flightTimeStart)
124
125 @property
126 def flightTimeEndText(self):
127 """Get the end of the flight time in string format."""
128 return PIREP.formatTimestampForRPC(self.flightTimeEnd)
129
130 @property
131 def blockTimeEndText(self):
132 """Get the end of the block time in string format."""
133 return PIREP.formatTimestampForRPC(self.blockTimeEnd)
134
[97]135 def getACARSText(self):
136 """Get the ACARS text.
137
138 This is a specially formatted version of the log without the faults."""
139 text = "[MAVA LOGGER X LOG]-[%s]" % (const.VERSION,)
140 for index in range(0, len(self.logLines)):
141 if index not in self.faultLineIndexes:
142 (timeStr, line) = self.logLines[index]
143 if timeStr is not None:
144 text += PIREP._formatLine(timeStr, line)
145 return text
146
147 def getRatingText(self):
148 """Get the rating text.
149
150 This is a specially formatted version of the lines containing the
151 faults."""
152 text = ""
153 for index in self.faultLineIndexes:
154 (timeStr, line) = self.logLines[index]
155 if timeStr is not None:
156 text += PIREP._formatLine(timeStr, line)
[345]157 text += "\n"
[97]158
159 text += "\n[Flight Rating: %.1f]" % (max(0.0, self.rating),)
160
161 return text
[345]162
[97]163 def getTimeComment(self):
164 """Get the time comment.
165
166 This is basically a collection of the delay codes, if any."""
[99]167 if not self.delayCodes:
168 return "UTC"
169 else:
170 s = ""
171 for code in self.delayCodes:
172 if s: s += ", "
[437]173 s += code
[99]174 return s
[97]175
176 def getSTAR(self):
177 """Get the STAR and/or the transition."""
178 star = self.star if self.star is not None else ""
179 if self.transition is not None:
180 if star: star += ", "
181 star += self.transition
182 return star.upper()
[151]183
184 def save(self, path):
185 """Save the PIREP to the given file.
186
187 Returns whether the saving has succeeded."""
188 try:
189 with open(path, "wb") as f:
190 pickle.dump(self, f)
[393]191 return None
[151]192 except Exception, e:
[401]193 error = utf2unicode(str(e))
194 print u"Failed saving PIREP to %s: %s" % (path, error)
[393]195 return error
[743]196
197 def _serialize(self):
198 """Serialize the PIREP for JSON-RPC."""
199 attrs = {}
200 attrs["log"] = self.getACARSText()
[778]201 attrs["flightDate"] = self.flightDateText
202 attrs["callsign"] = self.bookedFlight.callsign
203 attrs["departureICAO"] = self.bookedFlight.departureICAO
204 attrs["arrivalICAO"] = self.bookedFlight.arrivalICAO
[743]205 attrs["numPassengers"] = self.numPassengers
206 attrs["numCrew"] = self.numCrew
207 attrs["cargoWeight"] = self.cargoWeight
208 attrs["bagWeight"] = self.bagWeight
209 attrs["mailWeight"] = self.mailWeight
210 attrs["flightType"] = self.flightTypeText
211 attrs["online"] = 1 if self.online else 0
212 attrs["blockTimeStart"] = self.blockTimeStartText
213 attrs["blockTimeEnd"] = self.blockTimeEndText
214 attrs["flightTimeStart"] = self.flightTimeStartText
215 attrs["flightTimeEnd"] = self.flightTimeEndText
216 attrs["timeComment"] = self.getTimeComment()
217 attrs["fuelUsed"] = self.fuelUsed
218 attrs["departureRunway"] = self.departureRunway
219 attrs["arrivalRunway"] = self.arrivalRunway
220 attrs["departureMETAR"] = self.departureMETAR
221 attrs["arrivalMETAR"] = self.arrivalMETAR
222 attrs["filedCruiseLevel"] = self.filedCruiseAltitude / 100.0
223 attrs["cruiseLevel"] = self.cruiseAltitude / 100.0
224 attrs["sid"] = self.sid
225 attrs["route"] = self.route
226 attrs["star"] = self.star
227 attrs["approachType"] = self.approachType
228 attrs["comments"] = self.comments
229 attrs["flightDefects"] = self.flightDefects
230 attrs["ratingText"] = self.getRatingText()
231 attrs["rating"] = max(0.0, self.rating)
232 attrs["flownDistance"] = self.flownDistance
233 # FIXME: it should be stored in the PIREP when it is sent later
[778]234 attrs["performDate"] = datetime.date.today().strftime("%Y-%m-%d")
[743]235
236 return ([], attrs)
Note: See TracBrowser for help on using the repository browser.