User Tools

Site Tools


inhabitat:kaunas:day04

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
inhabitat:kaunas:day04 [2026/05/29 06:48] – [Context] harley.larainhabitat:kaunas:day04 [2026/05/29 08:45] (current) harley.lara
Line 20: Line 20:
 For this evaluation, you will repeat the same IoT stack, but with a different sensor: the **DS18B20 digital temperature sensor**. For this evaluation, you will repeat the same IoT stack, but with a different sensor: the **DS18B20 digital temperature sensor**.
  
-The goal is not to test memorization. You are allowed to use the provided schematic, diagrams, starter code, previous workshop notes, library documentation, and examples.+The goal is not to test memorization. You are allowed to use the provided schematic, diagrams, starter code, previous workshop notes, and examples.
  
 The goal is to demonstrate that you understand how the parts of the IoT stack connect and that you can adapt the workflow to a new sensor. The goal is to demonstrate that you understand how the parts of the IoT stack connect and that you can adapt the workflow to a new sensor.
- 
---- 
  
 ====== Evaluation Task ====== ====== Evaluation Task ======
Line 38: Line 36:
 At the end of the evaluation, your system should: At the end of the evaluation, your system should:
  
-* Read temperature data from the DS18B20 sensor. +  * Read temperature data from the DS18B20 sensor. 
-* Apply simple logic to the temperature value. +  * Apply simple logic to the temperature value. 
-* Turn an LED on or off based on a temperature condition. +  * Turn an LED on or off based on a temperature condition. 
-* Connect the ESP32 to WiFi. +  * Connect the ESP32 to WiFi. 
-* Publish temperature readings to an MQTT topic. +  * Publish temperature readings to an MQTT topic. 
-* Subscribe to the MQTT topic in Node-RED. +  * Subscribe to the MQTT topic in Node-RED. 
-* Convert or validate the incoming value in Node-RED. +  * Convert or validate the incoming value in Node-RED. 
-* Store the temperature measurement in InfluxDB. +  * Store the temperature measurement in InfluxDB. 
-* Connect Grafana to InfluxDB. +  * Connect Grafana to InfluxDB. 
-* Create a Grafana dashboard showing the temperature data.+  * Create a Grafana dashboard showing the temperature data. 
  
---- 
  
 ====== Provided Resources ====== ====== Provided Resources ======
Line 55: Line 53:
 You may use the following resources during the evaluation: You may use the following resources during the evaluation:
  
-* DS18B20 wiring schematic +  * DS18B20 wiring schematic 
-* ESP32 pinout diagram +  * ESP32 pinout diagram 
-* MQTT topic structure example +  * MQTT topic structure example 
-* Node-RED flow reference diagram +  * Node-RED flow reference diagram 
-* InfluxDB configuration notes +  * InfluxDB configuration notes 
-* Grafana dashboard setup notes +  * Grafana dashboard setup notes 
-* Starter Arduino code +  * Starter Arduino code 
-* Previous workshop code +  * Previous workshop code 
-Library documentation and examples +  The workshop examples 
-* Internet search for syntax, library usage, and troubleshooting+  * Internet search for syntax, library usage, and troubleshooting
  
 You are expected to understand and adapt the materials, not reproduce them from memory. You are expected to understand and adapt the materials, not reproduce them from memory.
  
---- 
  
 ====== Starter Code ====== ====== Starter Code ======
Line 74: Line 71:
 The starter code gives you the basic structure of the program. The starter code gives you the basic structure of the program.
  
-It does not contain the complete solution. You must complete the missing parts and adapt the code to your own MQTT topic, pin choices, threshold value, and setup.+**It does not contain the complete solution.** You must complete the missing parts and adapt the code to your own MQTT topic, pin choices, threshold value, and setup.
  
 <code cpp> <code cpp>
 +
 #include <WiFi.h> #include <WiFi.h>
 #include <PubSubClient.h> #include <PubSubClient.h>
Line 83: Line 81:
  
 // TODO: Add WiFi credentials // TODO: Add WiFi credentials
-const char* ssid = "YOUR_WIFI_NAME"; +const char* SSID = "YOUR_WIFI_NAME"; 
-const char* password = "YOUR_WIFI_PASSWORD";+const char* PASSWORD = "YOUR_WIFI_PASSWORD";
  
 // TODO: Add MQTT broker address // TODO: Add MQTT broker address
-const char* mqtt_server = "YOUR_MQTT_BROKER_IP";+const char* MQTT_HOST = "YOUR_MQTT_BROKER_IP"
 +const int MQTT_PORT = 1234;
  
 // TODO: Define MQTT topic // TODO: Define MQTT topic
-const char* mqtt_topic = "workshop/student-name/temperature";+const char* MQTT_TOPIC = "workshop/student-name/temperature";
  
 // TODO: Define pins // TODO: Define pins
Line 96: Line 95:
 #define LED_PIN 2 #define LED_PIN 2
  
-WiFiClient espClient+WiFiClient wifi
-PubSubClient client(espClient);+PubSubClient mqtt(wifi);
  
 OneWire oneWire(ONE_WIRE_BUS); OneWire oneWire(ONE_WIRE_BUS);
-DallasTemperature sensors(&oneWire);+DallasTemperature temp_sensor(&oneWire);
  
 void setup_wifi() { void setup_wifi() {
-// TODO: Connect to WiFi+  // TODO: Connect to WiFi
  
-// TODO: Print connection status+  // TODO: Print connection status
  
-// TODO: Print assigned IP address+  // TODO: Print assigned IP address
 } }
  
 void reconnect_mqtt() { void reconnect_mqtt() {
-// TODO: Check MQTT connection+  // TODO: Check MQTT connection
  
-// TODO: Reconnect if disconnected+  // TODO: Reconnect if disconnected
  
-// TODO: Print MQTT connection status+  // TODO: Print MQTT connection status
 } }
  
 void setup() { void setup() {
-Serial.begin(115200);+  Serial.begin(115200);
  
-pinMode(LED_PIN, OUTPUT);+  pinMode(LED_PIN, OUTPUT);
  
-sensors.begin();+  temp_sensor.begin();
  
-setup_wifi();+  setup_wifi();
  
-client.setServer(mqtt_server1883);+  mqtt.setServer(MQTT_HOSTMQTT_PORT);
 } }
  
 void loop() { void loop() {
-if (!client.connected()) { +  if (!mqtt.connected()) { 
-reconnect_mqtt(); +    reconnect_mqtt(); 
-}+  }
  
-client.loop();+  mqtt.loop();
  
-// TODO: Request temperature from DS18B20+  // Request temperature from DS18B20 
 +  temp_sensor.requestTemperatures();
  
-// TODO: Read temperature in Celsius+  // Read temperature in Celsius 
 +  float temperatureC = temp_sensor.getTempCByIndex(0);
  
-// TODO: Check whether the reading is valid+  // Check whether the reading is valid 
 +  if (temperatureC == DEVICE_DISCONNECTED_C) { 
 +    Serial.println("Error: DS18B20 sensor not detected or reading failed"); 
 +    delay(2000); 
 +    return; 
 +  }
  
-// TODO: Print temperature to Serial Monitor+  // TODO: Print temperature to Serial Monitor
  
-// TODO: Add LED threshold logic+  // TODO: Add LED threshold logic
  
-// TODO: Convert temperature value to MQTT payload+  // TODO: Convert temperature value to MQTT payload
  
-// TODO: Publish temperature to MQTT topic +  // TODO: Publish temperature to MQTT topic 
- + 
-delay(5000); +</code>
-</code>+
  
 ===== Starter Code Expectations ===== ===== Starter Code Expectations =====
Line 158: Line 163:
 Your final code should include: Your final code should include:
  
-* DS18B20 initialization +  * DS18B20 initialization 
-* Temperature reading in degrees Celsius +  * Temperature reading in degrees Celsius 
-* Basic error handling for invalid sensor readings +  * Basic error handling for invalid sensor readings 
-* LED control based on a temperature threshold +  * LED control based on a temperature threshold 
-* WiFi connection +  * WiFi connection 
-* MQTT broker connection +  * MQTT broker connection 
-* MQTT publishing +  * MQTT publishing 
-* Clear Serial Monitor output +  * Clear Serial Monitor output 
-* Basic comments explaining the main sections+  * Basic comments explaining the main sections
  
 --- ---
Line 174: Line 179:
 ===== Hardware ===== ===== Hardware =====
  
-* ESP32 development board +The is the list of component that you need in order to complete this evaluation: 
-* DS18B20 temperature sensor +  * ESP32 development board 
-* 4.7kΩ pull-up resistor +  * DS18B20 temperature sensor 
-* Breadboard and jumper wires +  * 4.7kΩ pull-up resistor 
-* LED +  * Breadboard and jumper wires 
-Current-limiting resistor for LED +  * LED (use the built-in LED) 
-* USB cable +  220Ω current-limiting resistor for LED 
-* Computer with Arduino IDE or equivalent editor+  * USB cable 
 +  * Computer with PlatformIO
  
 ===== Software and Services ===== ===== Software and Services =====
  
-Arduino IDE +  VS Code with PlatformIO extension 
-* Required Arduino libraries: +  * Required libraries, later on this page, you will be instructed to install them
- +    * OneWire 
-  * OneWire +    * DallasTemperature 
-  * DallasTemperature +    * PubSubClient 
-  * PubSubClient +    * WiFi library for ESP32, which is already included 
-  * WiFi library for ESP32 +  * MQTT broker 
-* MQTT broker +  * Node-RED 
-* Node-RED +  * InfluxDB 
-* InfluxDB +  * Grafana
-* Grafana +
- +
----+
  
 ====== Practical Milestones, Requirements, and Deliverables ====== ====== Practical Milestones, Requirements, and Deliverables ======
Line 205: Line 208:
 Each milestone should be demonstrated before moving to the next layer of the IoT stack. Each milestone should be demonstrated before moving to the next layer of the IoT stack.
  
-The first milestone focuses only on the physical construction of the circuit. Students should not start debugging code before the sensor, resistor, LED, and ESP32 are correctly connected on the breadboard. +The first milestone focuses only on the physical construction of the circuit. Students should not start debugging code before the sensor, resistors and ESP32 are correctly connected on the breadboard.
- +
---- +
 ===== Milestone 1: Physical Breadboard Connection of the DS18B20 and ESP32 ===== ===== Milestone 1: Physical Breadboard Connection of the DS18B20 and ESP32 =====
  
 ==== Required Behavior ==== ==== Required Behavior ====
 +{{ :inhabitat:kaunas:sensor-diagram.jpg?nolink&600 |}}
  
-The student must physically connect the **DS18B20 temperature sensor** to the **ESP32** using the breadboard. 
  
-The circuit must include the required **4.7kΩ pull-up resistor** between the DS18B20 data line and the power line.+1. The student must physically connect the **DS18B20 temperature sensor** to the **ESP32** using the breadboard.
  
-The student must also connect an LED with a suitable current-limiting resistor for later use in the conditional logic task.+2. The circuit must include the required **4.7kΩ pull-up resistor** between the DS18B20 data line and the power line.
  
 At this stage, the focus is only on correct physical wiring. At this stage, the focus is only on correct physical wiring.
Line 225: Line 225:
 ==== Required Deliverables ==== ==== Required Deliverables ====
  
-The student or group must show:+You must show:
  
-* ESP32 placed or connected correctly to the breadboard +  * ESP32 placed or connected correctly to the breadboard 
-* DS18B20 connected to the ESP32 +  * DS18B20 connected to the ESP32 
-* DS18B20 VCC connected to the correct voltage line +  * DS18B20 VCC connected to the correct voltage line 
-* DS18B20 GND connected to ground +  * DS18B20 GND connected to ground 
-* DS18B20 data pin connected to the selected ESP32 GPIO pin +  * DS18B20 data pin connected to the selected ESP32 GPIO pin 
-* 4.7kΩ pull-up resistor connected between VCC and the DS18B20 data line +  * 4.7kΩ pull-up resistor connected between VCC and the DS18B20 data line 
-* LED connected to an ESP32 GPIO pin +  * LED connected to an ESP32 GPIO pin 
-* LED current-limiting resistor connected correctly +  * LED current-limiting resistor connected correctly 
-* Shared ground between all components +  * Shared ground between all components 
-* Wiring that follows the provided schematic+  * Wiring that follows the provided schematic
  
 ==== Checkpoint Evidence ==== ==== Checkpoint Evidence ====
Line 242: Line 242:
 The student demonstrates that: The student demonstrates that:
  
-* They can identify the DS18B20 pins: VCC, GND, and DATA +  * They can identify the DS18B20 pins: VCC, GND, and DATA 
-* They can identify the ESP32 GPIO pin used for the DS18B20 data line +  * They can identify the ESP32 GPIO pin used for the DS18B20 data line 
-* They can explain the purpose of the 4.7kΩ pull-up resistor +  * They can explain the purpose of the 4.7kΩ pull-up resistor 
-* They can identify the GPIO pin used for the LED +  * They can identify the GPIO pin used for the LED 
-* The breadboard wiring is organized enough to be inspected +  * The breadboard wiring is organized enough to be inspected 
-* The circuit matches the provided schematic before code is uploaded+  * The circuit matches the provided schematic before code is uploaded
  
 ==== Instructor Check ==== ==== Instructor Check ====
Line 253: Line 253:
 Before the student continues, the instructor should confirm: Before the student continues, the instructor should confirm:
  
-* No power and ground lines are reversed +  * No power and ground lines are reversed 
-* The DS18B20 data line is not connected directly to VCC or GND +  * The DS18B20 data line is not connected directly to VCC or GND 
-* The pull-up resistor is placed correctly +  * The pull-up resistor is placed correctly 
-* The LED has a current-limiting resistor +  * The LED has a current-limiting resistor 
-* The ESP32, sensor, and LED share a common ground+  * The ESP32, sensor, and LED share a common ground 
  
---- 
  
 ===== Milestone 2: DS18B20 Sensor Reading ===== ===== Milestone 2: DS18B20 Sensor Reading =====
Line 279: Line 279:
 The student or group must show: The student or group must show:
  
-* Arduino code that initializes the DS18B20 +  * Arduino code that initializes the DS18B20 
-* Required DS18B20 libraries included +  * Required DS18B20 libraries included 
-* Correct GPIO pin configured for the DS18B20 data line +  * Correct GPIO pin configured for the DS18B20 data line 
-* Temperature reading requested from the sensor +  * Temperature reading requested from the sensor 
-* Temperature value printed to the Serial Monitor +  * Temperature value printed to the Serial Monitor
-* Basic handling of invalid or missing sensor readings+
  
 ==== Checkpoint Evidence ==== ==== Checkpoint Evidence ====
Line 290: Line 289:
 The student demonstrates that: The student demonstrates that:
  
-* Temperature values appear in the Serial Monitor +  * Temperature values appear in the Serial Monitor 
-* The values are realistic +  * The values are realistic 
-* The code uses the same ESP32 GPIO pin as the physical circuit +  * The code uses the same ESP32 GPIO pin as the physical circuit 
-* The student can explain the difference between connecting the sensor and reading the sensor in code +  * The student can explain the difference between connecting the sensor and reading the sensor in code 
-* The student can identify whether a problem is likely caused by wiring or code+  * The student can identify whether a problem is likely caused by wiring or code
  
---- 
  
 ===== Milestone 3: Conditional Logic and LED Control ===== ===== Milestone 3: Conditional Logic and LED Control =====
Line 317: Line 315:
 The student or group must show: The student or group must show:
  
-* LED connected to the ESP32 +  * LED connected to the ESP32 
-* LED GPIO pin correctly defined in the Arduino code +  * LED GPIO pin correctly defined in the Arduino code 
-* Temperature threshold implemented in the Arduino code +  * Temperature threshold implemented in the Arduino code 
-* LED turning on or off according to the condition +  * LED turning on or off according to the condition 
-* Clear explanation of the chosen threshold+  * Clear explanation of the chosen threshold
  
 ==== Checkpoint Evidence ==== ==== Checkpoint Evidence ====
Line 327: Line 325:
 The student demonstrates that: The student demonstrates that:
  
-* The LED responds to the temperature condition +  * The LED responds to the temperature condition 
-* The condition is based on the DS18B20 reading +  * The condition is based on the DS18B20 reading 
-* The threshold value is visible in the code +  * The threshold value is visible in the code 
-* The student can explain why the LED turns on or off +  * The student can explain why the LED turns on or off 
-* The student can distinguish between a sensor-reading issue and an LED-control issue+  * The student can distinguish between a sensor-reading issue and an LED-control issue
  
---- 
  
 ===== Milestone 4: WiFi Connection and IP Address ===== ===== Milestone 4: WiFi Connection and IP Address =====
Line 354: Line 351:
 The student or group must show: The student or group must show:
  
-* WiFi credentials added to the Arduino code +  * WiFi credentials added to the Arduino code 
-* ESP32 successfully connected to WiFi +  * ESP32 successfully connected to WiFi 
-* IP address printed in the Serial Monitor +  * IP address printed in the Serial Monitor 
-* Basic connection status messages +  * Basic connection status messages 
-* Code structure that separates WiFi setup from the main loop+  * Code structure that separates WiFi setup from the main loop
  
 ==== Checkpoint Evidence ==== ==== Checkpoint Evidence ====
Line 364: Line 361:
 The student demonstrates that: The student demonstrates that:
  
-* The ESP32 receives an IP address +  * The ESP32 receives an IP address 
-* The Serial Monitor confirms WiFi connection +  * The Serial Monitor confirms WiFi connection 
-* The student can explain why WiFi is needed before MQTT can work +  * The student can explain why WiFi is needed before MQTT can work 
-* The student can identify whether the ESP32 is connected to the network+  * The student can identify whether the ESP32 is connected to the network
  
 --- ---
Line 395: Line 392:
 The student or group must show: The student or group must show:
  
-* MQTT broker address configured in the Arduino code +  * MQTT broker address configured in the Arduino code 
-* MQTT topic configured in the Arduino code +  * MQTT topic configured in the Arduino code 
-* ESP32 connected to the MQTT broker +  * ESP32 connected to the MQTT broker 
-* Temperature values published to MQTT +  * Temperature values published to MQTT 
-* Serial Monitor output showing MQTT publishing activity +  * Serial Monitor output showing MQTT publishing activity 
-* Payload format suitable for Node-RED processing+  * Payload format suitable for Node-RED processing
  
 ==== Checkpoint Evidence ==== ==== Checkpoint Evidence ====
Line 406: Line 403:
 The student demonstrates that: The student demonstrates that:
  
-* The ESP32 connects to the MQTT broker +  * The ESP32 connects to the MQTT broker 
-* Temperature values are published repeatedly +  * Temperature values are published repeatedly 
-* The MQTT topic is clear and unique to the student or group +  * The MQTT topic is clear and unique to the student or group 
-* The MQTT payload contains only the value or a clearly structured value +  * The MQTT payload contains only the value or a clearly structured value 
-* The student can explain the difference between WiFi connection and MQTT connection+  * The student can explain the difference between WiFi connection and MQTT connection
  
---- 
  
 ===== Milestone 6: Node-RED MQTT Subscription and Value Processing ===== ===== Milestone 6: Node-RED MQTT Subscription and Value Processing =====
Line 422: Line 418:
 The flow must: The flow must:
  
-* Subscribe to the MQTT topic. +  * Subscribe to the MQTT topic. 
-* Receive the temperature value. +  * Receive the temperature value. 
-* Convert the incoming payload into a number if needed. +  * Convert the incoming payload into a number if needed. 
-* Optionally check that the value is valid. +  * Optionally check that the value is valid. 
-* Prepare the value for writing into InfluxDB.+  * Prepare the value for writing into InfluxDB.
  
 Recommended nodes: Recommended nodes:
  
-* MQTT input node +  * MQTT input node 
-* Debug node +  * Debug node 
-* Function node or Change node for value conversion +  * Function node or Change node for value conversion 
-* InfluxDB output node+  * InfluxDB output node
  
 ==== Required Deliverables ==== ==== Required Deliverables ====
Line 439: Line 435:
 The student or group must show: The student or group must show:
  
-* Node-RED MQTT input node subscribed to the correct topic +  * Node-RED MQTT input node subscribed to the correct topic 
-* Debug output showing the incoming MQTT payload +  * Debug output showing the incoming MQTT payload 
-* Node-RED logic that converts the payload into a number +  * Node-RED logic that converts the payload into a number 
-* Processed value ready for InfluxDB +  * Processed value ready for InfluxDB 
-* Organized and readable Node-RED flow+  * Organized and readable Node-RED flow
  
 ==== Checkpoint Evidence ==== ==== Checkpoint Evidence ====
Line 449: Line 445:
 The student demonstrates that: The student demonstrates that:
  
-* MQTT messages from the ESP32 are visible in Node-RED +  * MQTT messages from the ESP32 are visible in Node-RED 
-* The payload is converted from a string to a number if necessary +  * The payload is converted from a string to a number if necessary 
-* The debug panel shows the processed value +  * The debug panel shows the processed value 
-* The student can explain the role of each node in the flow+  * The student can explain the role of each node in the flow
  
---- 
- 
-===== Milestone 7: InfluxDB Storage ===== 
- 
-==== Required Behavior ==== 
- 
-The processed temperature reading must be stored in InfluxDB. 
- 
-Suggested measurement name: 
- 
-<code> 
-temperature 
-</code> 
- 
-Suggested field: 
- 
-<code> 
-value 
-</code> 
- 
-Optional tags: 
- 
-<code> 
-student 
-device 
-location 
-</code> 
- 
-Example stored data model: 
- 
-<code> 
-measurement: temperature 
-field: value 
-tag: device = esp32 
-</code> 
- 
-==== Required Deliverables ==== 
- 
-The student or group must show: 
- 
-* Node-RED configured to write to InfluxDB 
-* Correct InfluxDB database, bucket, or measurement configuration 
-* Temperature value stored successfully 
-* Clear measurement and field names 
-* Data structure suitable for Grafana visualization 
- 
-==== Checkpoint Evidence ==== 
- 
-The student demonstrates that: 
- 
-* Node-RED sends the processed temperature value to InfluxDB 
-* InfluxDB receives new data points 
-* The measurement and field names are identifiable 
-* The student can explain what data is being stored 
- 
---- 
  
-===== Milestone 8: Grafana Dashboard =====+===== Milestone 7: Grafana Dashboard =====
  
 ==== Required Behavior ==== ==== Required Behavior ====
Line 531: Line 471:
 The student or group must show: The student or group must show:
  
-* InfluxDB configured as a Grafana datasource +  * InfluxDB configured as a Grafana datasource 
-* Query that retrieves the temperature data +  * Query that retrieves the temperature data 
-* Dashboard panel displaying temperature over time +  * Dashboard panel displaying temperature over time 
-* Clear panel title +  * Clear panel title 
-* Correct or appropriate unit, such as degrees Celsius+  * Correct or appropriate unit, such as degrees Celsius
  
 ==== Checkpoint Evidence ==== ==== Checkpoint Evidence ====
Line 541: Line 481:
 The student demonstrates that: The student demonstrates that:
  
-* Grafana can access the InfluxDB datasource +  * Grafana can access the InfluxDB datasource 
-* Temperature values appear in a dashboard panel +  * Temperature values appear in a dashboard panel 
-* The graph updates over time +  * The graph updates over time 
-* The student can explain how Grafana receives the data indirectly through InfluxDB+  * The student can explain how Grafana receives the data indirectly through InfluxDB
  
---- +===== Milestone 8: Final System Explanation =====
- +
-===== Milestone 9: Final System Explanation =====+
  
 ==== Required Behavior ==== ==== Required Behavior ====
Line 564: Line 502:
 The student or group must explain: The student or group must explain:
  
-* What the DS18B20 measures +  * What the DS18B20 measures 
-* How the DS18B20 is physically connected to the ESP32 +  * How the DS18B20 is physically connected to the ESP32 
-* What the ESP32 does +  * What the ESP32 does 
-* Why WiFi is needed +  * Why WiFi is needed 
-* What MQTT is used for +  * What MQTT is used for 
-* What Node-RED does +  * What Node-RED does 
-* Why the data is stored in InfluxDB +  * Why the data is stored in InfluxDB 
-* What Grafana displays+  * What Grafana displays
  
 ==== Checkpoint Evidence ==== ==== Checkpoint Evidence ====
Line 577: Line 515:
 The student demonstrates that: The student demonstrates that:
  
-* They can describe the system from sensor to dashboard +  * They can describe the system from sensor to dashboard 
-* They can identify where a problem is happening in the stack +  * They can identify where a problem is happening in the stack 
-* They can distinguish between hardware, firmware, network, MQTT, Node-RED, database, and dashboard issues +  * They can distinguish between hardware, firmware, network, MQTT, Node-RED, database, and dashboard issues 
-* They can explain at least one troubleshooting step they used +  * They can explain at least one troubleshooting step they used
- +
----+
  
inhabitat/kaunas/day04.1780030113.txt.gz · Last modified: 2026/05/29 06:48 by harley.lara