Skip to content
Fondazione ITS INCOM

Examples · Internet of Things

A sensor that speaks

A reading from the sensors becomes a sentence, and the sentence becomes an MP3 that a Raspberry Pi plays in the classroom. A model makes the sentence friendlier; your code checks its numbers.

Intermediate · 45 min

The idea

A display needs someone looking at it. A voice reaches everyone in the room: “Lab 2: the air is stale, please open a window.”

The program takes a reading, writes a sentence, and turns it into an MP3:

  1. a template writes the sentence: the numbers exactly as they are, the same way every time;
  2. a model writes a friendlier one, and your code keeps it only if every number is still there;
  3. a voice reads it into reading.mp3.

What you need

A key and the openai library, as in Your first API call in Python. On the Raspberry Pi, a speaker or headphones.

The program

Save it as speak_reading.py:

import json
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://api.ai.itsincom.org/v1",
    api_key=os.environ["API_KEY"],
)

reading = {"room": "Lab 2", "temperature": 27.4, "humidity": 61, "co2": 1450}  # from your sensors

# 1. A template: the numbers exactly as they are, the same way every time
sentence = (f"{reading['room']}: the temperature is {reading['temperature']} degrees, "
            f"humidity {reading['humidity']} percent, carbon dioxide {reading['co2']} parts per million.")
if reading["co2"] > 1000:
    sentence += " The air is stale: please open a window."

# 2. A friendlier sentence from a model, kept only if every number is still there
answer = client.chat.completions.create(
    model="gemma-4-26b",
    temperature=0.7,
    messages=[
        {"role": "system", "content": "You are the voice of the air monitor of a classroom. From the reading, "
                                      "write one or two short sentences to be read aloud, in plain words, with "
                                      "no symbols and no emoji. Say the temperature, the humidity and the CO2, "
                                      "each number exactly as in the reading. If the CO2 is over 1000, ask to "
                                      "open a window."},
        {"role": "user", "content": json.dumps(reading)},
    ],
)
friendly = answer.choices[0].message.content.strip()
numbers = [str(reading[key]) for key in ("temperature", "humidity", "co2")]
if all(number in friendly for number in numbers):
    sentence = friendly
else:
    print("A number is missing or changed, so the template speaks. The model wrote:", friendly)

# 3. The sentence becomes an MP3
speech = client.audio.speech.create(model="tts-1", voice="amy", input=sentence, response_format="mp3")
speech.write_to_file("reading.mp3")
print(sentence)
print("reading.mp3 is ready")

Run it with python3 speak_reading.py. It takes a few seconds.

What you should see

The temperature is 27.4 degrees, the humidity is 61 percent, and the CO2 is 1450. Please open a window.
reading.mp3 is ready

The model writes a different sentence every time. When a number goes missing, the template speaks instead:

A number is missing or changed, so the template speaks. The model wrote: The CO2 level is 1450. Please open a window.
Lab 2: the temperature is 27.4 degrees, humidity 61 percent, carbon dioxide 1450 parts per million. The air is stale: please open a window.
reading.mp3 is ready

This happened to us with a vaguer system message, which did not name the three values. That is the reason for the check: a model can leave out or change a number, a template cannot.

On the Raspberry Pi

Install a player once, then play the file:

sudo apt install mpg123
mpg123 reading.mp3

From your Python program, the same with subprocess.run(["mpg123", "-q", "reading.mp3"]).

Good to know

Exercise

All examples