def metars(source, key="xml"): """Parse METAR information retrieved from https://aviationweather.gov/metar. Parameters ---------- source: :ref:`Record generator <record-generators>` returning records containing XML data, required key: :ref:`Record key <record-keys>`, optional Yields ------ records: dict Records will contain METAR data extracted from XML. """ for record in source: response = record[key] for data in response.findall("data"): for metar in sorted(data.findall("METAR"), key=lambda x: x.find("observation_time").text): output = dict() for element in metar.findall("raw_text"): add_field(output, "raw", element.text) for element in metar.findall("station_id"): add_field(output, "station-id", element.text) for element in metar.findall("observation_time"): add_field(output, "observation-time", arrow.get(element.text)) for element in metar.findall("latitude"): add_field(output, "latitude", quantity(float(element.text), units.degrees)) for element in metar.findall("longitude"): add_field(output, "longitude", quantity(float(element.text), units.degrees)) for element in metar.findall("temp_c"): add_field(output, "temperature", quantity(float(element.text), units.degC)) for element in metar.findall("depoint_c"): add_field(output, "dewpoint", quantity(float(element.text), units.degC)) for element in metar.findall("wind_dir_degrees"): add_field(output, "wind-direction", quantity(float(element.text), units.degrees)) for element in metar.findall("wind_speed_kt"): add_field( output, "wind-speed", quantity(float(element.text), units.nautical_miles_per_hour)) for element in metar.findall("visibility_statute_mi"): add_field(output, "visibility", quantity(float(element.text), units.mile)) for element in metar.findall("altim_in_hg"): add_field(output, "altimeter", quantity(float(element.text), units.inHg)) for element in metar.findall("flight_category"): add_field(output, "flight-category", element.text) for element in metar.findall("elevation_m"): add_field(output, "elevation", quantity(float(element.text), units.meters)) yield output
def ios(rate=quantity(1, units.second)): """Retrieve motion information from an iOS device. This component requires the `motion` module provided by Pythonista. Parameters ---------- rate: time quantity, required Rate at which motion data will be retrieved. Yields ------ records: dict Records will contain information including the current acceleration due to gravity and the user, along with device attitude. """ import time import motion # pylint: disable=import-error rate = rate.to(units.seconds).magnitude motion.start_updates() try: while True: gravity = quantity(motion.get_gravity(), units.meters * units.seconds * units.seconds) acceleration = quantity(motion.get_user_acceleration(), units.meters * units.seconds * units.seconds) attitude = quantity(motion.get_attitude(), units.radians) record = dict() add_field(record, ("gravity", "x"), gravity[0]) add_field(record, ("gravity", "y"), gravity[1]) add_field(record, ("gravity", "z"), gravity[2]) add_field(record, ("acceleration", "x"), acceleration[0]) add_field(record, ("acceleration", "y"), acceleration[1]) add_field(record, ("acceleration", "z"), acceleration[2]) add_field(record, ("attitude", "roll"), attitude[0]) add_field(record, ("attitude", "pitch"), attitude[1]) add_field(record, ("attitude", "yaw"), attitude[2]) yield record time.sleep(rate) except GeneratorExit: motion.stop_updates()
def metronome(rate=pipecat.quantity(1.0, pipecat.units.seconds)): """Generate an empty record at fixed time intervals using the host clock. Typically, you would use functions such as :func:`pipecat.utility.add_field` or :func:`pipecat.utility.add_timestamp` to populate the (otherwise empty) records. Examples -------- If you want to know what time it is, at 5-minute intervals: >>> pipe = pipecat.device.clock.metronome(pipecat.quantity(5, pipecat.units.minutes)) >>> pipe = pipecat.utility.add_timestamp(pipe) >>> for record in pipe: ... print record Parameters ---------- rate: time quantity, required The amount of time to wait between records. Yields ------ record: dict Empty record returned at fixed time intervals. """ delay = rate.to(pipecat.units.seconds).magnitude last_time = time.time() while True: yield dict() next_time = last_time + delay time.sleep(next_time - time.time()) last_time = next_time
def __getitem__(self, key): values = self._columns[key] if isinstance(values[0], pipecat.quantity): values = pipecat.quantity( numpy.array([value.magnitude for value in values]), values[0].units) else: values = numpy.array(values) return values
def obd(connection, commands=None, rate=quantity(5, units.second)): """Retrieve OBD-II data from an automobile. This component requires the `Python-OBD` module (http://python-obd.readthedocs.io). Parameters ---------- connection: :class:`obd.OBD` instance, required. rate: time quantity, required Rate at which data will be retrieved. Yields ------ record: dict Records will contain OBD-II data retrieved from an automobile computer. """ # Caller must supply an obd.OBD instance that's already connected. if not (isinstance(connection, obdii.OBD) and connection.is_connected()): raise ValueError("A valid obd.OBD connection is required.") # Get the set of available commands. if commands is None: commands = [] for command in connection.supported_commands: try: if command.mode not in [1]: continue if command.pid in [0x00, 0x01, 0x02, 0x20, 0x40, 0x41]: continue commands.append(command) except: # pylint: disable=bare-except pass rate = rate.to(units.seconds).magnitude while True: record = dict() for command in commands: sys.stdout.flush() try: response = connection.query(command) name = command.name.lower().replace("_", "-") add_field(record, name, response.value) except: # pylint: disable=bare-except pass yield record time.sleep(rate)
def icharger208b(source): """Parse data from an iCharger 208B battery charger. Parses data events emitted by the charger during charge, discharge, etc. Likely works with other models from iCharger, but this is untested. Consider :ref:`contributing` to let us know. This model battery charger comes with a USB cable that provides serial-over-USB communication with the host computer. To connect with the charger, you'll need to open a handle to the appropriate serial port, the name of which will vary between platforms and based on the number of devices currently connected, and feed lines of text to the parser. Examples -------- Open a serial port on a Mac OSX computer using `pySerial <http://pyserial.readthedocs.io>`_, read lines from the serial port, parse them into records, and print them to stdout: >>> pipe = serial.serial_for_url("/dev/cu.SLAB_USBtoUART", baudrate=128000) >>> pipe = pipecat.utility.readline(pipe) >>> pipe = pipecat.device.charger.icharger208b(pipe) >>> for record in pipe: ... print record Parameters ---------- source: :ref:`Record generator <record-generators>` returning records containing a "string" field. Yields ------ records: dict Records will contain information including the charge mode, supply voltage, battery voltage, battery current, internal and external charger temperature, and the total charged added-to / removed-from the battery. """ modes = { 1: "charge", 2: "discharge", 3: "monitor", 4: "wait", 5: "motor", 6: "finished", 7: "error", 8: "trickle-LIxx", 9: "trickle-NIxx", 10: "foam-cut", 11: "info", 12: "discharge-external", } for record in source: raw = record["string"].strip().split(";") record = dict() add_field(record, ("charger", "mode"), modes[int(raw[1])]) add_field(record, ("charger", "supply"), quantity(float(raw[3]) / 1000, units.volts)) add_field(record, ("battery", "voltage"), quantity(float(raw[4]) / 1000, units.volts)) add_field(record, ("battery", "cell1", "voltage"), quantity(float(raw[6]) / 1000, units.volts)) add_field(record, ("battery", "cell2", "voltage"), quantity(float(raw[7]) / 1000, units.volts)) add_field(record, ("battery", "cell3", "voltage"), quantity(float(raw[8]) / 1000, units.volts)) add_field(record, ("battery", "cell4", "voltage"), quantity(float(raw[9]) / 1000, units.volts)) add_field(record, ("battery", "cell5", "voltage"), quantity(float(raw[10]) / 1000, units.volts)) add_field(record, ("battery", "cell6", "voltage"), quantity(float(raw[11]) / 1000, units.volts)) add_field(record, ("battery", "cell7", "voltage"), quantity(float(raw[12]) / 1000, units.volts)) add_field(record, ("battery", "cell8", "voltage"), quantity(float(raw[13]) / 1000, units.volts)) add_field(record, ("battery", "current"), quantity(float(raw[5]) * 10, units.milliamps)) add_field(record, ("charger", "temperature", "internal"), quantity(float(raw[14]) / 10, units.degC)) add_field(record, ("charger", "temperature", "external"), quantity(float(raw[15]) / 10, units.degC)) add_field(record, ("battery", "charge"), quantity(float(raw[16]), units.milliamps * units.hours)) yield record