circuitpython-fake-bme280 1.0.4__py3-none-any.whl → 1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,15 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: circuitpython-fake-bme280
3
- Version: 1.0.4
3
+ Version: 1.2
4
4
  Summary: BME280 Driver for CircuitPython used for testing functionality with no hardware attached
5
5
  Author-email: Adafruit Industries <circuitpython@adafruit.com>
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/brentru/CircuitPython_Fake_BME280
8
8
  Keywords: adafruit,blinka,circuitpython,micropython,fake_bme280,bme280,,test,,fake,,mock,,stub
9
9
  Classifier: Intended Audience :: Developers
10
10
  Classifier: Topic :: Software Development :: Libraries
11
11
  Classifier: Topic :: Software Development :: Embedded Systems
12
12
  Classifier: Topic :: System :: Hardware
13
- Classifier: License :: OSI Approved :: MIT License
14
13
  Classifier: Programming Language :: Python :: 3
15
14
  Description-Content-Type: text/x-rst
16
15
  License-File: LICENSE
@@ -19,6 +18,8 @@ Requires-Dist: adafruit-circuitpython-busdevice
19
18
  Requires-Dist: adafruit-circuitpython-register
20
19
  Requires-Dist: toml
21
20
  Provides-Extra: optional
21
+ Requires-Dist: python-dotenv; extra == "optional"
22
+ Dynamic: license-file
22
23
 
23
24
  Introduction
24
25
  ============
@@ -0,0 +1,9 @@
1
+ circuitpython_fake_bme280-1.2.dist-info/licenses/LICENSE,sha256=tXgkGXjihZP5R0fW0-IyViyV_rB8TXrzKdiLP4crJn0,1103
2
+ fake_bme280/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ fake_bme280/advanced.py,sha256=_Mx7ocLBxLe5OL80cYQDcyuKHLyQpPjUp01KEEFricw,8059
4
+ fake_bme280/basic.py,sha256=uSEr5wkVnJ8X_4Eq5PmalavBXvgNWj7HsC31PW_Uc-0,12502
5
+ fake_bme280/protocol.py,sha256=IeQ6cPpu9r7fvKwDkLHg2wLZ7QkOyCtyRjKGtIpW3ho,1017
6
+ circuitpython_fake_bme280-1.2.dist-info/METADATA,sha256=9mLS7tTmILM-xQge59UHNpfqB7bdSWzHbZN5gnr60Cw,4640
7
+ circuitpython_fake_bme280-1.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
8
+ circuitpython_fake_bme280-1.2.dist-info/top_level.txt,sha256=zYm6UwRd0tbyREvYLz0zQcP9NY4GvkMWQ19rZYbwO0Q,12
9
+ circuitpython_fake_bme280-1.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.1.0)
2
+ Generator: setuptools (82.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,269 @@
1
+ # SPDX-FileCopyrightText: 2017 ladyada for Adafruit Industries
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """
6
+ `fake_bme280.advanced`
7
+ =========================================================================================
8
+
9
+ CircuitPython driver from BME280 Temperature, Humidity and Barometric
10
+ Pressure sensor
11
+
12
+ NOTE: This is a mock. The settings exposed here are simply stored and read back.
13
+
14
+ * Author(s): ladyada, Jose David M.
15
+
16
+ Implementation Notes
17
+ --------------------
18
+
19
+ **Hardware:**
20
+
21
+ * `Adafruit BME280 Temperature, Humidity and Barometric Pressure sensor
22
+ <https://www.adafruit.com/product/2652>`_ (Product ID: 2652)
23
+
24
+
25
+ **Software and Dependencies:**
26
+
27
+ * Adafruit CircuitPython firmware for the supported boards:
28
+ https://circuitpython.org/downloads
29
+ """
30
+
31
+ from micropython import const
32
+
33
+ from fake_bme280.basic import Adafruit_BME280
34
+ from fake_bme280.protocol import I2C_Impl
35
+
36
+ try:
37
+ import typing # pylint: disable=unused-import
38
+
39
+ from busio import I2C
40
+ except ImportError:
41
+ pass
42
+
43
+ __version__ = "1.2"
44
+ __repo__ = "https://github.com/brentru/CircuitPython_Fake_BME280.git"
45
+
46
+ # I2C ADDRESS/BITS/SETTINGS
47
+ # -----------------------------------------------------------------------
48
+ _BME280_ADDRESS = const(0x77)
49
+
50
+ """iir_filter values"""
51
+ IIR_FILTER_DISABLE = const(0)
52
+ IIR_FILTER_X2 = const(0x01)
53
+ IIR_FILTER_X4 = const(0x02)
54
+ IIR_FILTER_X8 = const(0x03)
55
+ IIR_FILTER_X16 = const(0x04)
56
+
57
+ _BME280_IIR_FILTERS = (
58
+ IIR_FILTER_DISABLE,
59
+ IIR_FILTER_X2,
60
+ IIR_FILTER_X4,
61
+ IIR_FILTER_X8,
62
+ IIR_FILTER_X16,
63
+ )
64
+
65
+ """overscan values for temperature, pressure, and humidity"""
66
+ OVERSCAN_DISABLE = const(0x00)
67
+ OVERSCAN_X1 = const(0x01)
68
+ OVERSCAN_X2 = const(0x02)
69
+ OVERSCAN_X4 = const(0x03)
70
+ OVERSCAN_X8 = const(0x04)
71
+ OVERSCAN_X16 = const(0x05)
72
+
73
+ _BME280_OVERSCANS = {
74
+ OVERSCAN_DISABLE: 0,
75
+ OVERSCAN_X1: 1,
76
+ OVERSCAN_X2: 2,
77
+ OVERSCAN_X4: 4,
78
+ OVERSCAN_X8: 8,
79
+ OVERSCAN_X16: 16,
80
+ }
81
+
82
+ """mode values"""
83
+ MODE_SLEEP = const(0x00)
84
+ MODE_FORCE = const(0x01)
85
+ MODE_NORMAL = const(0x03)
86
+
87
+ _BME280_MODES = (MODE_SLEEP, MODE_FORCE, MODE_NORMAL)
88
+ """
89
+ standby timeconstant values
90
+ TC_X[_Y] where X=milliseconds and Y=tenths of a millisecond
91
+ """
92
+ STANDBY_TC_0_5 = const(0x00) # 0.5ms
93
+ STANDBY_TC_10 = const(0x06) # 10ms
94
+ STANDBY_TC_20 = const(0x07) # 20ms
95
+ STANDBY_TC_62_5 = const(0x01) # 62.5ms
96
+ STANDBY_TC_125 = const(0x02) # 125ms
97
+ STANDBY_TC_250 = const(0x03) # 250ms
98
+ STANDBY_TC_500 = const(0x04) # 500ms
99
+ STANDBY_TC_1000 = const(0x05) # 1000ms
100
+
101
+ _BME280_STANDBY_TCS = (
102
+ STANDBY_TC_0_5,
103
+ STANDBY_TC_10,
104
+ STANDBY_TC_20,
105
+ STANDBY_TC_62_5,
106
+ STANDBY_TC_125,
107
+ STANDBY_TC_250,
108
+ STANDBY_TC_500,
109
+ STANDBY_TC_1000,
110
+ )
111
+
112
+
113
+ class Adafruit_BME280_Advanced(Adafruit_BME280):
114
+ """Driver from BME280 Temperature, Humidity and Barometric Pressure sensor
115
+
116
+ .. note::
117
+ This is a mock. The settings exposed here are simply stored and read
118
+ back - nothing is written to a real device.
119
+
120
+ """
121
+
122
+ @property
123
+ def standby_period(self) -> int:
124
+ """
125
+ Control the inactive period when in Normal mode
126
+ Allowed standby periods are the constants STANDBY_TC_*
127
+ """
128
+ return self._t_standby
129
+
130
+ @standby_period.setter
131
+ def standby_period(self, value: int) -> None:
132
+ if not value in _BME280_STANDBY_TCS:
133
+ raise ValueError(f"Standby Period '{value}' not supported")
134
+ self._t_standby = value
135
+
136
+ @property
137
+ def overscan_humidity(self) -> int:
138
+ """
139
+ Humidity Oversampling
140
+ Allowed values are the constants OVERSCAN_*
141
+ """
142
+ return self._overscan_humidity
143
+
144
+ @overscan_humidity.setter
145
+ def overscan_humidity(self, value: int) -> None:
146
+ if not value in _BME280_OVERSCANS:
147
+ raise ValueError(f"Overscan value '{value}' not supported")
148
+ self._overscan_humidity = value
149
+
150
+ @property
151
+ def overscan_temperature(self) -> int:
152
+ """
153
+ Temperature Oversampling
154
+ Allowed values are the constants OVERSCAN_*
155
+ """
156
+ return self._overscan_temperature
157
+
158
+ @overscan_temperature.setter
159
+ def overscan_temperature(self, value: int) -> None:
160
+ if not value in _BME280_OVERSCANS:
161
+ raise ValueError(f"Overscan value '{value}' not supported")
162
+ self._overscan_temperature = value
163
+
164
+ @property
165
+ def overscan_pressure(self) -> int:
166
+ """
167
+ Pressure Oversampling
168
+ Allowed values are the constants OVERSCAN_*
169
+ """
170
+ return self._overscan_pressure
171
+
172
+ @overscan_pressure.setter
173
+ def overscan_pressure(self, value: int) -> None:
174
+ if not value in _BME280_OVERSCANS:
175
+ raise ValueError(f"Overscan value '{value}' not supported")
176
+ self._overscan_pressure = value
177
+
178
+ @property
179
+ def iir_filter(self) -> int:
180
+ """
181
+ Controls the time constant of the IIR filter
182
+ Allowed values are the constants IIR_FILTER_*
183
+ """
184
+ return self._iir_filter
185
+
186
+ @iir_filter.setter
187
+ def iir_filter(self, value: int) -> None:
188
+ if not value in _BME280_IIR_FILTERS:
189
+ raise ValueError(f"IIR Filter '{value}' not supported")
190
+ self._iir_filter = value
191
+
192
+ @property
193
+ def measurement_time_typical(self) -> float:
194
+ """Typical time in milliseconds required to complete a measurement in normal mode"""
195
+ meas_time_ms = 1.0
196
+ if self.overscan_temperature != OVERSCAN_DISABLE:
197
+ meas_time_ms += 2 * _BME280_OVERSCANS.get(self.overscan_temperature)
198
+ if self.overscan_pressure != OVERSCAN_DISABLE:
199
+ meas_time_ms += 2 * _BME280_OVERSCANS.get(self.overscan_pressure) + 0.5
200
+ if self.overscan_humidity != OVERSCAN_DISABLE:
201
+ meas_time_ms += 2 * _BME280_OVERSCANS.get(self.overscan_humidity) + 0.5
202
+ return meas_time_ms
203
+
204
+ @property
205
+ def measurement_time_max(self) -> float:
206
+ """Maximum time in milliseconds required to complete a measurement in normal mode"""
207
+ meas_time_ms = 1.25
208
+ if self.overscan_temperature != OVERSCAN_DISABLE:
209
+ meas_time_ms += 2.3 * _BME280_OVERSCANS.get(self.overscan_temperature)
210
+ if self.overscan_pressure != OVERSCAN_DISABLE:
211
+ meas_time_ms += 2.3 * _BME280_OVERSCANS.get(self.overscan_pressure) + 0.575
212
+ if self.overscan_humidity != OVERSCAN_DISABLE:
213
+ meas_time_ms += 2.3 * _BME280_OVERSCANS.get(self.overscan_humidity) + 0.575
214
+ return meas_time_ms
215
+
216
+
217
+ class Adafruit_BME280_I2C(Adafruit_BME280_Advanced):
218
+ """Driver for BME280 connected over I2C
219
+
220
+ :param ~busio.I2C i2c: The I2C bus the BME280 is connected to.
221
+ :param int address: I2C device address. Defaults to :const:`0x77`.
222
+ but another address can be passed in as an argument
223
+
224
+ .. note::
225
+ The operational range of the BMP280 is 300-1100 hPa.
226
+ Pressure measurements outside this range may not be as accurate.
227
+
228
+ **Quickstart: Importing and using the BME280**
229
+
230
+ Here is an example of using the :class:`Adafruit_BME280_I2C`.
231
+ First you will need to import the libraries to use the sensor
232
+
233
+ .. code-block:: python
234
+
235
+ import board
236
+ import fake_bme280.advanced as adafruit_bme280
237
+
238
+ Once this is done you can define your `board.I2C` object and define your sensor object
239
+
240
+ .. code-block:: python
241
+
242
+ i2c = board.I2C() # uses board.SCL and board.SDA
243
+ bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c)
244
+
245
+ You need to setup the pressure at sea level
246
+
247
+ .. code-block:: python
248
+
249
+ bme280.sea_level_pressure = 1013.25
250
+
251
+ Now you have access to the :attr:`temperature`, :attr:`relative_humidity`
252
+ :attr:`pressure` and :attr:`altitude` attributes
253
+
254
+ .. code-block:: python
255
+
256
+ temperature = bme280.temperature
257
+ relative_humidity = bme280.relative_humidity
258
+ pressure = bme280.pressure
259
+ altitude = bme280.altitude
260
+
261
+ """
262
+
263
+ def __init__(
264
+ self,
265
+ i2c: I2C,
266
+ address: int = _BME280_ADDRESS,
267
+ use_openweather: bool = True,
268
+ ) -> None:
269
+ super().__init__(I2C_Impl(i2c, address), use_openweather=use_openweather)
fake_bme280/basic.py CHANGED
@@ -25,15 +25,27 @@ Implementation Notes
25
25
  * Adafruit CircuitPython firmware for the supported boards:
26
26
  https://circuitpython.org/downloads
27
27
  """
28
+
28
29
  import math
30
+ import os
31
+ import random
29
32
  import socket as pool
30
33
  import ssl
31
34
  import typing # pylint: disable=unused-import
32
- import toml
33
35
  from micropython import const
34
36
  import adafruit_requests
35
37
  from fake_bme280.protocol import I2C_Impl, SPI_Impl
36
38
 
39
+ try:
40
+ import toml
41
+ except ImportError:
42
+ toml = None
43
+
44
+ try:
45
+ import dotenv
46
+ except ImportError:
47
+ dotenv = None
48
+
37
49
  try:
38
50
  from busio import I2C, SPI
39
51
  from digitalio import DigitalInOut
@@ -75,21 +87,62 @@ _BME280_REGISTER_CONFIG = const(0xF5)
75
87
  _BME280_REGISTER_TEMPDATA = const(0xFA)
76
88
  _BME280_REGISTER_HUMIDDATA = const(0xFD)
77
89
 
78
- # Load the settings.toml file
79
- toml_config = toml.load("settings.toml")
80
-
81
- # OpenWeatherMap API
82
- # GET weather data for a specific location
83
- DATA_SOURCE = (
84
- "http://api.openweathermap.org/data/2.5/weather?q="
85
- + toml_config["openweather_location"]
86
- + "&units="
87
- + toml_config["openweather_units"]
88
- + "&mode=json"
89
- + "&appid="
90
- + toml_config["openweather_token"]
90
+ _OPENWEATHER_KEYS = (
91
+ "openweather_location",
92
+ "openweather_units",
93
+ "openweather_token",
91
94
  )
92
95
 
96
+ _SETTINGS_TOML_PATH = "settings.toml"
97
+
98
+
99
+ def _load_openweather_settings() -> dict:
100
+ """Return OpenWeatherMap settings, trying settings.toml, then .env
101
+ (python-dotenv), then os.getenv, per key in that order. Raises
102
+ ``RuntimeError`` if settings.toml is malformed or any key is missing."""
103
+ toml_values = {}
104
+ if toml is not None:
105
+ try:
106
+ toml_values = toml.load(_SETTINGS_TOML_PATH)
107
+ except FileNotFoundError:
108
+ pass
109
+ except toml.TomlDecodeError as err:
110
+ raise RuntimeError(
111
+ "Could not parse %s: %s" % (_SETTINGS_TOML_PATH, err)
112
+ ) from err
113
+
114
+ dotenv_values = dotenv.dotenv_values() if dotenv is not None else {}
115
+
116
+ settings = {}
117
+ for key in _OPENWEATHER_KEYS:
118
+ value = toml_values.get(key) or dotenv_values.get(key) or os.getenv(key)
119
+ if value:
120
+ settings[key] = value
121
+
122
+ missing = [k for k in _OPENWEATHER_KEYS if k not in settings]
123
+ if missing:
124
+ raise RuntimeError(
125
+ "fake_bme280 is missing required OpenWeatherMap setting(s): "
126
+ + ", ".join(missing)
127
+ + ". Provide them via settings.toml, a .env file (python-dotenv), "
128
+ "or environment variables. Or construct the sensor with "
129
+ "use_openweather=False for random fake readings (no network)."
130
+ )
131
+ return settings
132
+
133
+
134
+ def _build_openweather_url() -> str:
135
+ """Build the OpenWeatherMap API URL from the loaded settings."""
136
+ config = _load_openweather_settings()
137
+ return (
138
+ "http://api.openweathermap.org/data/2.5/weather?q="
139
+ + config["openweather_location"]
140
+ + "&units="
141
+ + config["openweather_units"]
142
+ + "&mode=json&appid="
143
+ + config["openweather_token"]
144
+ )
145
+
93
146
 
94
147
  class Adafruit_BME280:
95
148
  """Driver from BME280 Temperature, Humidity and Barometric Pressure sensor
@@ -101,11 +154,21 @@ class Adafruit_BME280:
101
154
  """
102
155
 
103
156
  # pylint: disable=too-many-instance-attributes
104
- def __init__(self, bus_implementation: typing.Union[I2C_Impl, SPI_Impl]) -> None:
105
- """Mock a BME280 sensor object that was found on an I2C bus."""
106
- # Check device ID.
157
+ def __init__(
158
+ self,
159
+ bus_implementation: typing.Union[I2C_Impl, SPI_Impl],
160
+ use_openweather: bool = True,
161
+ ) -> None:
162
+ """Mock a BME280 sensor object that was found on an I2C bus.
163
+
164
+ :param bus_implementation: I2C or SPI implementation wrapper.
165
+ :param bool use_openweather: When ``True`` (default), read settings
166
+ from the environment (``settings.toml`` on CircuitPython,
167
+ environment variables on CPython) and fetch live data from the
168
+ OpenWeatherMap API. When ``False``, return random plausible
169
+ readings with no network access and no configuration required.
170
+ """
107
171
  self._bus_implementation = bus_implementation
108
- # Set some reasonable defaults.
109
172
  self._iir_filter = IIR_FILTER_DISABLE
110
173
  self.overscan_humidity = OVERSCAN_X1
111
174
  self.overscan_temperature = OVERSCAN_X1
@@ -115,23 +178,42 @@ class Adafruit_BME280:
115
178
  self.sea_level_pressure = 1013.25
116
179
  """Pressure in hectoPascals at sea level. Used to calibrate `altitude`."""
117
180
  self._t_fine = None
118
- # Configure a CPython adafruit_requests session
119
- self.requests = adafruit_requests.Session(pool, ssl.create_default_context())
120
- self._current_forcast = None
121
- # Test call get_forecast
122
- self.get_forecast()
181
+ self._use_openweather = use_openweather
182
+ self._current_forecast = None
183
+ self._data_source = None
184
+ self.requests = None
185
+ if use_openweather:
186
+ self._data_source = _build_openweather_url()
187
+ self.requests = adafruit_requests.Session(
188
+ pool, ssl.create_default_context()
189
+ )
190
+ self.get_forecast()
191
+ else:
192
+ self._current_forecast = self._random_forecast()
193
+
194
+ @staticmethod
195
+ def _random_forecast() -> dict:
196
+ """Generate a plausible BME280-shaped reading."""
197
+ return {
198
+ "main": {
199
+ "temp": round(random.uniform(18.0, 28.0), 2),
200
+ "pressure": round(random.uniform(1000.0, 1025.0), 2),
201
+ "humidity": round(random.uniform(30.0, 70.0), 2),
202
+ }
203
+ }
123
204
 
124
205
  def get_forecast(self):
125
- """Fetch weather from OpenWeatherMap API"""
126
- # print("Fetching json from", DATA_SOURCE)
127
- response = self.requests.get(DATA_SOURCE)
128
- self._current_forcast = response.json()
129
- # print(self._current_forcast)
206
+ """Fetch weather from OpenWeatherMap (or generate fake data)."""
207
+ if not self._use_openweather:
208
+ self._current_forecast = self._random_forecast()
209
+ return
210
+ response = self.requests.get(self._data_source)
211
+ self._current_forecast = response.json()
130
212
 
131
213
  def _read_temperature(self) -> None:
132
214
  # Get the OpenWeather temperature and store it in _t_fine
133
215
  self.get_forecast()
134
- self._t_fine = self._current_forcast["main"]["temp"]
216
+ self._t_fine = self._current_forecast["main"]["temp"]
135
217
 
136
218
  @property
137
219
  def mode(self) -> int:
@@ -177,7 +259,7 @@ class Adafruit_BME280:
177
259
  The compensated pressure in hectoPascals.
178
260
  """
179
261
  self._read_temperature()
180
- return self._current_forcast["main"]["pressure"]
262
+ return self._current_forecast["main"]["pressure"]
181
263
 
182
264
  @property
183
265
  def relative_humidity(self) -> float:
@@ -192,7 +274,7 @@ class Adafruit_BME280:
192
274
  The relative humidity in RH %
193
275
  """
194
276
  self._read_temperature()
195
- humidity = self._current_forcast["main"]["humidity"]
277
+ humidity = self._current_forecast["main"]["humidity"]
196
278
  if humidity > 100:
197
279
  return 100
198
280
  if humidity < 0:
@@ -253,8 +335,13 @@ class Adafruit_BME280_I2C(Adafruit_BME280):
253
335
 
254
336
  """
255
337
 
256
- def __init__(self, i2c: I2C, address: int = 0x77) -> None: # BME280_ADDRESS
257
- super().__init__(I2C_Impl(i2c, address))
338
+ def __init__(
339
+ self,
340
+ i2c: I2C,
341
+ address: int = 0x77, # BME280_ADDRESS
342
+ use_openweather: bool = True,
343
+ ) -> None:
344
+ super().__init__(I2C_Impl(i2c, address), use_openweather=use_openweather)
258
345
 
259
346
 
260
347
  class Adafruit_BME280_SPI(Adafruit_BME280):
@@ -305,5 +392,11 @@ class Adafruit_BME280_SPI(Adafruit_BME280):
305
392
 
306
393
  """
307
394
 
308
- def __init__(self, spi: SPI, cs: DigitalInOut, baudrate: int = 100000) -> None:
309
- super().__init__(SPI_Impl(spi, cs, baudrate))
395
+ def __init__(
396
+ self,
397
+ spi: SPI,
398
+ cs: DigitalInOut,
399
+ baudrate: int = 100000,
400
+ use_openweather: bool = True,
401
+ ) -> None:
402
+ super().__init__(SPI_Impl(spi, cs, baudrate), use_openweather=use_openweather)
@@ -1,8 +0,0 @@
1
- fake_bme280/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- fake_bme280/basic.py,sha256=fmvOe6RBgJjfO4rG34Wdm0V9W3LKAymMbsLcwU1Z2JE,9578
3
- fake_bme280/protocol.py,sha256=IeQ6cPpu9r7fvKwDkLHg2wLZ7QkOyCtyRjKGtIpW3ho,1017
4
- circuitpython_fake_bme280-1.0.4.dist-info/LICENSE,sha256=tXgkGXjihZP5R0fW0-IyViyV_rB8TXrzKdiLP4crJn0,1103
5
- circuitpython_fake_bme280-1.0.4.dist-info/METADATA,sha256=Gss3h67gXetF0KN0bmP8sAzndjp0NsDOUZTYWmbPua4,4610
6
- circuitpython_fake_bme280-1.0.4.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
7
- circuitpython_fake_bme280-1.0.4.dist-info/top_level.txt,sha256=zYm6UwRd0tbyREvYLz0zQcP9NY4GvkMWQ19rZYbwO0Q,12
8
- circuitpython_fake_bme280-1.0.4.dist-info/RECORD,,