Skip to content

PTU300¤

Vaisala PTU300 series barometer.

Supports models PTU300, PTU301, PTU303, PTU307 and PTU30T.

PTU300 (Serial) ¤

PTU300(equipment: Equipment)

              flowchart LR
              msl.equipment_resources.vaisala.ptu300.PTU300[PTU300]
              msl.equipment.interfaces.serial.Serial[Serial]
              msl.equipment.interfaces.message_based.MessageBased[MessageBased]
              msl.equipment.schema.Interface[Interface]

                              msl.equipment.interfaces.serial.Serial --> msl.equipment_resources.vaisala.ptu300.PTU300
                                msl.equipment.interfaces.message_based.MessageBased --> msl.equipment.interfaces.serial.Serial
                                msl.equipment.schema.Interface --> msl.equipment.interfaces.message_based.MessageBased
                




              click msl.equipment_resources.vaisala.ptu300.PTU300 href "" "msl.equipment_resources.vaisala.ptu300.PTU300"
              click msl.equipment.interfaces.serial.Serial href "" "msl.equipment.interfaces.serial.Serial"
              click msl.equipment.interfaces.message_based.MessageBased href "" "msl.equipment.interfaces.message_based.MessageBased"
              click msl.equipment.schema.Interface href "" "msl.equipment.schema.Interface"
            

Vaisala PTU300 series barometer.

The device manual is available here.

The default settings for the RS232 connection are:

  • Baud rate: 4800
  • Data bits: 7
  • Parity: EVEN

Regular-expression patterns that are used to select this Resource when connect() is called.

manufacturer=r"Vaisala"
model=r"^PTU30[0137T]$"
flags=IGNORECASE

Warning

Ensure the device is in STOP or SEND mode before initiating communication.

Parameters:

Name Type Description Default
equipment Equipment

An Equipment instance.

required
Source code in packages/resources/src/msl/equipment_resources/vaisala/ptu300.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
def __init__(self, equipment: Equipment) -> None:
    """Vaisala PTU300 series barometer.

    The device manual is available [here](https://docs.vaisala.com/v/u/M210796EN-J/en-US){:target="_blank"}.

    The default settings for the RS232 connection are:

    * Baud rate: 4800
    * Data bits: 7
    * Parity: EVEN

    Regular-expression patterns that are used to select this Resource when
    [connect()][msl.equipment.schema.Equipment.connect] is called.
    ```python
    manufacturer=r"Vaisala"
    model=r"^PTU30[0137T]$"
    flags=IGNORECASE
    ```

    !!! warning
        Ensure the device is in `STOP` or `SEND` mode before initiating communication.

    Args:
        equipment: An [Equipment][] instance.
    """
    assert equipment.connection is not None  # noqa: S101
    equipment.connection.properties.setdefault("baud_rate", 4800)
    equipment.connection.properties.setdefault("data_bits", DataBits.SEVEN)
    equipment.connection.properties.setdefault("parity", Parity.EVEN)
    super().__init__(equipment)

    self.rstrip: bool = True

    self._units: dict[str, str] = {}
    self._pressure_modules: set[str] = set()
    self._info: dict[str, str] = self._device_info()

    # Get the device ID (serial) number and check it agrees with the equipment record.
    # Could use `reply = self.query("*9900SN")` but the serial number is also in device_info
    sn = self._info["Serial number"]
    if sn != equipment.serial:
        msg = f"Inconsistent serial number: expected {equipment.serial} but received {sn}"
        raise MSLConnectionError(self, msg)

device_info property ¤

device_info: dict[str, str]

Returns a dictionary of information about the Vaisala device.

units property ¤

units: dict[str, str]

A dictionary of measured quantities and their associated units.

The units are set by set_units.

check_for_errors ¤

check_for_errors() -> None

Raise an error, if present.

Source code in packages/resources/src/msl/equipment_resources/vaisala/ptu300.py
92
93
94
95
96
97
98
99
def check_for_errors(self) -> None:
    """Raise an error, if present."""
    err = self.query("ERRS")  # List present transmitter errors
    # a PASS or FAIL line is returned from PTB330 modules first
    if err in {"PASS", "FAIL"}:
        err = self.read()
    if err and err != "No errors":
        raise MSLConnectionError(self, err)

get_format ¤

get_format() -> str

Get the currently active formatter string.

Returns:

Type Description
str

The formatter string.

Source code in packages/resources/src/msl/equipment_resources/vaisala/ptu300.py
106
107
108
109
110
111
112
113
def get_format(self) -> str:
    """Get the currently active formatter string.

    Returns:
        The formatter string.
    """
    # The hash symbol "#" is used to set the format, but then appears as a backslash "\\" on the device.
    return self.query("FORM ?")[len("Output format  :") :].replace("\\", "#")

get_reading_str ¤

get_reading_str() -> str

Output the reading once.

Returns:

Type Description
str

A string that follows the format set by set_format.

Source code in packages/resources/src/msl/equipment_resources/vaisala/ptu300.py
115
116
117
118
119
120
121
122
def get_reading_str(self) -> str:
    """Output the reading once.

    Returns:
        A string that follows the format set by
            [set_format][msl.equipment_resources.vaisala.ptu300.PTU300.set_format].
    """
    return self.query("SEND")

set_format ¤

set_format(fmt: str) -> None

Set the format of data output to follow the pattern in the format string.

For example, in the format string 4.3 P " " 3.3 T " " 3.3 RH " " SN " " #r #n, x.y is the number of digits and decimal places of the values; P, T, RH, and SN are placeholders for pressure, temperature, relative humidity, and serial number values; and " ", #r, and #n represent a string constant, carriage-return, and line-feed respectively. Additional allowed modifiers include ERR for error flags, U5 for unit field and (optional) length, TIME for time as [hh:mm:ss], and DATE for date as [yyyy-mm-dd]. For more options, refer to the manual.

Parameters:

Name Type Description Default
fmt str

String representing desired output format.

required
Source code in packages/resources/src/msl/equipment_resources/vaisala/ptu300.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
def set_format(self, fmt: str) -> None:
    """Set the format of data output to follow the pattern in the format string.

    For example, in the format string `4.3 P " " 3.3 T " " 3.3 RH " " SN " " #r #n`, `x.y` is the number
    of digits and decimal places of the values; `P`, `T`, `RH`, and `SN` are placeholders for pressure,
    temperature, relative humidity, and serial number values; and `" "`, `#r`, and `#n` represent a string
    constant, carriage-return, and line-feed respectively. Additional allowed modifiers include `ERR` for
    error flags, `U5` for unit field and (optional) length, `TIME` for time as [hh:mm:ss], and `DATE` for
    date as [yyyy-mm-dd]. For more options, refer to the manual.

    Args:
        fmt: String representing desired output format.
    """
    reply = self.query(f"FORM {fmt}")
    if reply.startswith("Output format  :"):  # format is returned by some devices when set
        form = reply[len("Output format  :") :].replace("\\", "#")
    elif "ok" in reply.lower():  # if OK is returned then we need to ask for the format
        form = self.get_format()
    else:  # this is not expected so raise an error
        msg = f"Unexpected reply={reply!r}"
        raise MSLConnectionError(self, msg)

    if form.upper().replace(" ", "") != fmt.upper().replace(" ", ""):
        # the format was not set as specified
        self.check_for_errors()
        msg = f"Could not set format of output. \nExpected: {fmt} \nReceived: {form}."
        raise MSLConnectionError(self, msg)

    self._info["Output format"] = form

set_units ¤

set_units(desired_units: dict[str, str]) -> None

Set unit of specified quantity.

Note that only one pressure unit is used at a time for the PTU300 series.

Parameters:

Name Type Description Default
desired_units dict[str, str]

Dictionary of quantity (as keys) and their unit (as values) as specified in the instrument manual on pages 24 and 106.

These may include the following (available options depend on the barometer components):

  • Pressure quantity: P, P3h, P1, P2, QNH, QFE, HCP, ...
  • Pressure unit: hPa, psi, inHg, torr, bar, mbar, mmHg, kPa, Pa, mmH2O, inH2O
  • Temperature quantity: T
  • Temperature unit: 'C, 'F (C and F are also supported but are returned as 'C or 'F)
  • Humidity quantity: RH
  • Humidity unit: %RH
required
Source code in packages/resources/src/msl/equipment_resources/vaisala/ptu300.py
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
def set_units(self, desired_units: dict[str, str]) -> None:  # noqa: C901, PLR0912
    """Set unit of specified quantity.

    Note that only one pressure unit is used at a time for the PTU300 series.

    Args:
        desired_units: Dictionary of *quantity* (as keys) and their *unit* (as values)
            as specified in the instrument manual on pages 24 and 106.

            These may include the following (available options depend on the barometer components):

            * Pressure *quantity*: P, P3h, P1, P2, QNH, QFE, HCP, ...
            * Pressure *unit*: hPa, psi, inHg, torr, bar, mbar, mmHg, kPa, Pa, mmH2O, inH2O
            * Temperature *quantity*: T
            * Temperature *unit*: 'C, 'F (C and F are also supported but are returned as 'C or 'F)
            * Humidity *quantity*: RH
            * Humidity *unit*: %RH
    """
    p_units: list[str] = []
    allowed_units = [  # for pressure
        "hPa",
        "psia",
        "inHg",
        "torr",
        "bara",
        "barg",
        "psig",
        "mbar",
        "mmHg",
        "kPa",
        "Pa",
        "mmH2O",
        "inH2O",
    ]
    old_units = self.query("UNIT")
    if "Output units" not in old_units:  # confirming device is of type PTU300
        msg = "Check correct device connected"
        raise MSLConnectionError(self, msg)

    for quantity, unit in desired_units.items():
        if quantity == "RH":  # only option is %RH
            self._units["RH"] = "%RH"

        elif "T" in quantity:  # options are 'C, 'F
            if "F" in unit:  # Temperature and humidity setting is done via metric or 'non metric'
                r_m = self.query("UNIT N")
                if "non" not in r_m:
                    msg = "Error when setting non-metric unit for temperature"
                    raise MSLConnectionError(self, msg)
                self._units["T"] = "'F"
            elif "C" in unit:
                r_m = self.query("UNIT M")
                self._units["T"] = "'C"
            else:
                msg = f"Unit {unit} is not supported by this device. Please use 'C or 'F."
                raise MSLConnectionError(self, msg)

            if "metric" not in r_m:
                self._units["T"] = ""
                self.check_for_errors()

        elif unit in allowed_units:  # assume this is a pressure quantity based on the unit
            if p_units and unit not in p_units:
                msg = "Only one pressure unit can be set for this barometer"
                raise MSLConnectionError(self, msg)

            r_p = self.query(f"UNIT P {unit}")
            if not r_p.endswith(unit):
                self.check_for_errors()
            self._units[quantity] = unit
            p_units.append(unit)

        else:  # quantity is not pressure, temperature or humidity, so ask user to set the unit manually
            msg = f"{unit} is not able to be set for {quantity}. Please set this unit manually."
            raise MSLConnectionError(self, msg)