Hands-on: a rule-based comfort classifier
Module 3 — Processing with maths and physics · Slides: slides.md · Module overview · Course page
Complete s07_rule_classifier.py so it computes dew point and heat index, write a six-step ladder in classify(), colour the verdict on screen, and compare it with dsp.comfort_zone, while seeing the explainability strength and the limits that lead to ML.
Objectives
Section titled “Objectives”By the end of this lesson, you will:
- Fill the four blanks in practice/s07_rule_classifier.py until the verdict card changes word and colour with real temperature and humidity, producing at least three different classes.
- Adjust one threshold and explain how verdicts near that line change, and why your verdict may disagree with dsp.comfort_zone without being wrong.
- Explain the explainability strength of rules (the rule trace), and three limits of hand-written rules that motivate ML.
Before you start
Section titled “Before you start”You’ve been through lesson 3.3, and know a rule ladder must be ordered from severe to broad. If you’re using a board, prepare a way to change the air around the sensors: breathe on it, cup the board in your hand, or bring it near an air conditioner.
- Hardware: a TESAIoT Dev Kit board already flashed with BENTO’s MicroPython firmware, or the BENTO Emulator inside BENTO IDE — needs the SHT40 and DPS368 (present on the TESAIoT Dev Kit, absent on the Eva Kit); the emulator simulates the values and computes dsp with the real formulas.
- Prior lesson: lesson 3.3 — Derived metrics and rule-based classification: dew point, heat index and the rule ladder
Concepts
Section titled “Concepts”The loop has four steps: read raw values → convert to derived → decide with rules → draw the class. Reading raw values is already given (p, t = sensors.dps368.pressure_temperature() and h = sensors.sht40.humidity(), which returns a single %RH value). The four blanks are: (1) dp = dsp.dew_point(t, h) (2) hi = dsp.heat_index(t, h) (3) the rule ladder in classify(), checking danger (hi ≥ 41) → hot (hi ≥ 32) → humid (h ≥ 70) → cold (t < 20) → dry (h < 30) → comfortable, and (4) verdict.text(zone) with verdict.color(COLORS.get(zone, WHITE)). The starting values dp = 0.0 and hi = t keep the program from crashing before everything’s filled in. If you forget blank 3, classify() returns None, and the card stays empty and white.
The bottom section, already given, shows dsp.comfort_zone(t, h) for comparison. The verdicts may disagree, because the two rules define “comfortable” differently (ours uses heat index; the firmware’s uses raw temperature, with different threshold numbers). Neither set is completely “right” — a rule depends on the definition chosen, a limitation ML will later help with using real data.
The strongest thing about a rule ladder is that every decision can be traced back to which step fired. The full version has classify() return the reason too, such as why: feels-like 43 >= 41 — this is the explainability that safety and medical work require. But hand-set rules run into three walls: rules balloon out of control once there are many features, thresholds a human sets may not be the best ones for real data, and rules never adapt to new data on their own. The feeling that “if there were any more conditions than this, writing ifs just wouldn’t work anymore” is the real motivation behind ML, in module 5.
Worked example
Section titled “Worked example”s07_rule_classifier_full.py adds a rule trace (why), a flag for whether it matches dsp.comfort_zone, and hysteresis to stop the class flickering when a reading jitters right across a threshold. Open it once your practice file is done.
| File | What this file teaches |
|---|---|
| examples/s07_rule_classifier_full.py | Classifying weather with rules (full version) |
Practice
Section titled “Practice”The # TODO: comments are at lines 43 (the rule ladder in classify()), 91 (dew point), 94 (heat index), and 106–107 (showing it on screen with colour). Fill in one blank at a time and run it. If the class never changes, check your indentation and the ladder’s step order.
| Practice file | Topic |
|---|---|
| practice/s07_rule_classifier.py | Classifying weather with “rules” we write ourselves (the fill-in-the-code version) |
Solution
Section titled “Solution”Open the solution after trying on your own at least once, and read how to use the solutions first.
| Solution | Pairs with |
|---|---|
| solution/s07_rule_classifier.py | practice/s07_rule_classifier.py |
Check your understanding
Section titled “Check your understanding”The same questions are in quiz.yaml for automated checking.
-
Put the four steps of s07_rule_classifier.py’s loop in order (ordering · objective 1)
- a) Decide with rules: zone = classify(t, h, hi)
- b) Read raw values: dps368 and sht40
- c) Draw the class: verdict.text and verdict.color
- d) Convert to derived: dew_point and heat_index
Solution
b → d → a → c — read → convert → decide → draw is a mini pipeline for the whole classifier. Blanks 1–2 are the convert step, 3 is the decide step, 4 is the draw step.
-
You run it and the verdict card stays empty and white forever. What’s the most likely cause? (single choice · objective 1)
- a) The ladder in classify() hasn’t been filled in yet, so the function returns None, and COLORS.get(None, WHITE) gives white
- b) The SHT40 isn’t connected
- c) The heat index is too high
- d) The emulator doesn’t support ui.Seg7
Solution
a — a class not found in COLORS falls back to white. This symptom tells you the ladder isn’t working yet.
-
classify()’s verdict is comfortable, but dsp.comfort_zone answers acceptable. What should you conclude? (single choice · objective 2)
- a) classify() must be wrong
- b) dsp.comfort_zone must be wrong
- c) The two rules define comfort differently (different values and thresholds) — disagreeing doesn’t mean either is wrong
- d) The sensors are reading inconsistent values
Solution
c — ours decides from heat index; the firmware’s decides from raw temperature with its own ranges. A rule depends on the definition chosen.
-
Which of these are limits of hand-set rules that motivate moving to ML? (select every correct answer) (multiple choice · objective 3)
- a) Rules balloon out of control to write when there are dozens of features
- b) A threshold a human sets may not be the best one for real data
- c) Rules don’t adapt to new data on their own
- d) Rules can’t explain their own decision
Solution
a, b, c — explainability is a strength of rules, not a limitation. A rule trace can always say which step fired the decision.
The MVP for lessons 3.3–3.4: write your own classify() with a rule ladder, and have the board or emulator show a class that genuinely changes as temperature or humidity changes, using at least one derived value in the decision.
- All four blanks in the practice file are filled in, and it runs on the emulator or the board.
- Produce at least three classes (for example, breathing on it →
humid, cupping the board →hot, normal →comfortable), and note the method in your learning log. - Adjust one threshold (for example,
hi >= 32to>= 30), find a value that sits right across it, and explain how the verdict changes. - Point out which condition the
hotclass comes from, and why it useshiinstead oft.
Going further
Section titled “Going further”In the next module (Analysis), we start with signal filters — EMA, Median and Kalman — that smooth out jittery signals visibly to the eye.
Next lesson: lesson 4.1 — DSP filters: EMA, Median, Kalman and the radar range profile
Reflect
Section titled “Reflect”- If your verdict disagrees with
dsp.comfort_zone, how would you decide which one to trust? - What problem does hysteresis solve, and why is it more necessary with a real sensor than with a simulated value?
Review questions
Answer on your own first, then open the answer.
-
Order the four steps in the loop of s07_rule_classifier.py. (Objective 1)
- ตัดสินด้วยกฎ: zone = classify(t, h, hi)
- อ่านค่าดิบ: dps368 และ sht40
- วาดคลาส: verdict.text และ verdict.color
- แปลงเป็น derived: dew_point และ heat_index
Show answer
Correct order: B. อ่านค่าดิบ: dps368 และ sht40 → D. แปลงเป็น derived: dew_point และ heat_index → A. ตัดสินด้วยกฎ: zone = classify(t, h, hi) → C. วาดคลาส: verdict.text และ verdict.color
อ่าน → แปลง → ตัดสิน → วาด เป็น pipeline ย่อของ classifier ทั้งตัว ช่องเติม 1–2 คือก้าวแปลง 3 คือก้าวตัดสิน 4 คือก้าววาด
-
The verdict card is always empty and white. What is the most likely cause? (Objective 1)
- ยังไม่ได้เติมบันไดใน classify() ฟังก์ชันจึงคืน None และ COLORS.get(None, WHITE) ได้สีขาว
- SHT40 ไม่ได้ต่อ
- heat index สูงเกินไป
- Emulator ไม่รองรับ ui.Seg7
Show answer
Answer: A. ยังไม่ได้เติมบันไดใน classify() ฟังก์ชันจึงคืน None และ COLORS.get(None, WHITE) ได้สีขาว
คลาสที่ไม่อยู่ใน COLORS จะได้สีขาวเป็นค่าสำรอง อาการนี้บอกว่าบันไดยังไม่ทำงาน
-
classify() says comfortable but dsp.comfort_zone says acceptable. What should you conclude? (Objective 2)
- classify() ผิดแน่นอน
- dsp.comfort_zone ผิดแน่นอน
- สองกฎนิยามความสบายต่างกัน (ใช้ค่าและเส้นแบ่งต่างกัน) ไม่ตรงกันไม่ได้แปลว่าผิด
- เซนเซอร์อ่านค่าไม่ตรงกัน
Show answer
Answer: C. สองกฎนิยามความสบายต่างกัน (ใช้ค่าและเส้นแบ่งต่างกัน) ไม่ตรงกันไม่ได้แปลว่าผิด
ของเราตัดสินจาก heat index ส่วนของเฟิร์มแวร์ตัดสินจากอุณหภูมิดิบกับช่วงของตัวเอง กฎขึ้นกับนิยามที่เลือก
-
Which are limits of hand-written rules that lead us to ML? (select all that apply) (Objective 3)
- กฎบานจนเขียนไม่ไหวเมื่อมี feature หลายสิบตัว
- เส้นแบ่งที่มนุษย์ตั้งอาจไม่ใช่เส้นที่ดีที่สุดสำหรับข้อมูลจริง
- กฎไม่ปรับตามข้อมูลใหม่เอง
- กฎอธิบายคำตัดสินไม่ได้
Show answer
Answer: A. กฎบานจนเขียนไม่ไหวเมื่อมี feature หลายสิบตัว · B. เส้นแบ่งที่มนุษย์ตั้งอาจไม่ใช่เส้นที่ดีที่สุดสำหรับข้อมูลจริง · C. กฎไม่ปรับตามข้อมูลใหม่เอง
ความอธิบายได้เป็นจุดแข็งของกฎ ไม่ใช่ข้อจำกัด rule trace บอกได้เสมอว่าชั้นไหนยิงคำตัดสิน
Cite this lesson
If you teach from this lesson or reuse it in slides or documents, credit it with the text below. If you changed it, add (adapted) after the title.
"Hands-on: a rule-based comfort classifier" from TESA Open Knowledge by the Thai Embedded Systems Association (TESA), https://github.com/tesaiot/tesa-qualification-program, licensed under CC BY-NC 4.0
Thai attribution: "ลงมือทำ: ตัวจำแนกความสบายด้วยกฎ" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0
TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0
Content is licensed CC BY-NC 4.0. Reuse it non-commercially and credit the Thai Embedded Systems Association (TESA) every time. · How to cite TESA