Indoor temperature forecasting is a critical building block for intelligent HVAC control systems. Traditional HVAC controllers react to temperature deviations after they occur, which often leads to delayed corrections, unnecessary compressor activity, and increased energy consumption.
Machine learning based forecasting enables predictive control, where future indoor temperature trends can be anticipated using historical sensor data and environmental conditions. By accurately forecasting indoor temperature over a short prediction horizon, HVAC systems can plan smoother and more energy-efficient control actions.
In this example, we demonstrate how a neural network based indoor temperature forecasting model can be trained offline and compiled for deployment using Tiny ML ModelMaker. The trained model is intended to run fully on-device and can serve as an input to higher-level control or optimization algorithms that determine compressor actuation strategies.
For this example, we use a synthetic HVAC dataset designed to emulate realistic indoor thermal behavior. You can find the dataset here.
The dataset captures the relationship between compressor operation, outdoor temperature, and resulting indoor temperature over time. The dataset consists of time-series samples collected at uniform timesteps and includes the following signals:
- Compressor frequency (
compressorFrequency) - Outdoor temperature (
outdoorTemperature) - Indoor temperature (
indoorTemperature)
Input features:
- Past 5
compressorFrequencyvalues - Past 5
outdoorTemperaturevalues - Past 5
indoorTemperaturevalues
Prediction target:
indoorTemperature at the next timestep (or over a short future horizon. You can do this by setting forecast_horizon parameter in the YAML file.)
Here is the command to use this dataset with Tiny ML ModelZoo:
./run_tinyml_modelzoo.sh examples/hvac_indoor_temp_forecast/config.yamlUsers can configure the model pipeline using a YAML configuration file (like shown in the command above), where different stages (dataset loading, data processing and feature extraction, training, testing, and compilation) can be enabled or disabled based on requirements.
The YAML file is the core configuration file used in Tiny ML ModelMaker to define the pipeline for tasks such as dataset loading, model training, testing, and compilation.
common:
target_module: 'timeseries'
task_type: 'generic_timeseries_forecasting'
target_device: 'F28P55'
run_name: '{date-time}/{model_name}'
dataset:
# enable/disable dataset loading
enable: True
dataset_name: hvac_indoor_temp_forecast
input_data_path: https://software-dl.ti.com/C2000/esd/mcu_ai/datasets/hvac_indoor_temp_forecast_dataset.zipImportant parameters configured here are: task_type set to generic_timeseries_forecasting, indicating the type of task being performed.target_device set to F28P55, ensuring that the compiled output is optimized for this device. Dataset loading is enabled, with the correct path to the dataset zip folder provided (input_data_path). The data_dir parameter is automatically detected based on the task type (forecasting tasks use 'files').
data_processing_feature_extraction: # One or more can be cascaded in the list
# transforms: 'Downsample SimpleWindow'
data_proc_transforms: ['SimpleWindow'] # 'SimpleWindow' must be specified for forecasting tasks
# Downsample
#sampling_rate: 5
#new_sr: 2
# SimpleWindow
frame_size: 5
stride_size: 0.2
forecast_horizon: 1 # Number of future timesteps to be predicted
variables: 3 # takes the first 'variables' columns after the time columns as input to predict the target variables
target_variables: [2] # Other format for `target_variables` specification: ['pm','torque'] or [7,11] or ['7','11',]. If numbers which represent indices, are provided in list, assign column number 0 to the first non time column and continue numbering from thereFor forecasting tasks, the SimpleWindow transform must be selected. Additionally, the important parameters configured here are: frame_size set to 5, representing the number of timestamps in a frame.variables set to 3, indicating the number of input variables.target_variables: Set to [2], as the indoorTemperature variable is located at index 2 (when column numbering starts from 0).
training:
# enable/disable training
enable: True
# F28x generic timeseries model names: CLS_1k_NPU, CLS_4k_NPU, CLS_6k_NPU, CLS_13k_NPU
# GUI only model names: ArcFault_model_200_t, ArcFault_model_300_t, ArcFault_model_700_t
model_name: 'FCST_LSTM10' #'FCST_13k' #
#model_name: 'FCST_13k'
# model_spec: '../tinyml-mlbackend/proprietary_models/cnn_af_3l.py'
model_config: ''
batch_size: 6
training_epochs: 10
num_gpus: 0
quantization: 2
optimizer: adamw
learning_rate: 0.003
weight_decay: 0.001
lr_scheduler: none
output_int: False
testing:
enable: True # False
compilation:
# enable/disable compilationp
enable: True # False
keep_libc_files: TrueThe data is then trained using FCST_LSTM10 model which is 611 paramters LSTM based model to learn indoor thermal dynamic. quantization is set to 2 which means we use TI NPU quantization. We are compiling this example using the ti-npu soft preset, which means the software emulation of the TI-NPU with some optimized operations.
On running the YAML file, the following accuracies were observed:
INFO: root.main.FloatTrain.BestEpoch: Printing statistics of best epoch:
INFO: root.main.FloatTrain.BestEpoch: Best epoch:9
INFO: root.main.FloatTrain.BestEpoch: Overall SMAPE across all variables: 0.30%
INFO: root.main.FloatTrain.BestEpoch: Per-Variable Metrics:
INFO: root.main.FloatTrain.BestEpoch: Variable indoorTemperature:
INFO: root.main.FloatTrain.BestEpoch: SMAPE of indoorTemperature across all predicted timesteps: 0.30%
INFO: root.main.FloatTrain.BestEpoch: R² of indoorTemperature across all predicted timesteps: 0.9971
INFO: root.main.FloatTrain.BestEpoch: Timestep 1:
INFO: root.main.FloatTrain.BestEpoch: SMAPE: 0.30%
INFO: root.main.FloatTrain.BestEpoch: R²: 0.9971
INFO: root.main : Epoch 9: Best Overall SMAPE across all variables across all predicted timesteps so far: 0.80% (Epoch 3)
INFO: root.main.QuantTrain.BestEpoch: Printing statistics of best epoch:
INFO: root.main.QuantTrain.BestEpoch: Best epoch:4
INFO: root.main.QuantTrain.BestEpoch: Overall SMAPE across all variables: 0.80%
INFO: root.main.QuantTrain.BestEpoch: Per-Variable Metrics:
INFO: root.main.QuantTrain.BestEpoch: Variable indoorTemperature:
INFO: root.main.QuantTrain.BestEpoch: SMAPE of indoorTemperature across all predicted timesteps: 0.80%
INFO: root.main.QuantTrain.BestEpoch: R² of indoorTemperature across all predicted timesteps: 0.9893
INFO: root.main.QuantTrain.BestEpoch: Timestep 1:
INFO: root.main.QuantTrain.BestEpoch: SMAPE: 0.80%
INFO: root.main.QuantTrain.BestEpoch: R²: 0.9893
INFO: root.main.test_data : Variable indoorTemperature:
INFO: root.main.test_data : SMAPE of indoorTemperature across all predicted timesteps: 0.73%
INFO: root.main.test_data : R² of indoorTemperature across all predicted timesteps: 0.9857
INFO: root.main.test_data : Timestep 1:
INFO: root.main.test_data : SMAPE: 0.73%
INFO: root.main.test_data : R²: 0.9857
You can find the compiled model at: tinyml-modelmaker/data/projects/{dataset_name}/run/{date-time}/{model_name}/compilation
We have compiled this example using the ti-npu soft preset for F28P55x device, which means the software emulation of the TI-NPU with some optimized operations. After successfully running Modelmaker, you will get four main files:
-
Artifacts:
mod.aandtvmgen_default.hare generated and stored in:data/projects/{dataset_name}/run/{date-time}/{model_name}/compilation/artifacts
-
Golden Vectors:
user_input_config.handtest_vector.care stored in:data/projects/{dataset_name}/run/{date-time}/{model_name}/training/quantization/golden_vectors
These four files will be needed while running on device.
In this example, we will use the following setup:
- Device: LAUNCHXL-F28P55X
- C2000Ware Version: 6.00
- Code Composer Studio (CCS): Version 20.3.0
Steps to run this example on-device can be found by following this guide: Deploying Forecasting Models from ModelMaker to Device
Upon flashing and running the project we can see the model output matches the golden vectors.
Here are the key performance metrics for the model running on the device:
| Metric | Value |
|---|---|
| Device Name | F28P55x |
| AI Model Cycles | 199432 |
| Inference Time | 1329.55 µs |
| Results Match | TRUE |
| Model Size | 9452 bytes |
| Model Flash | 9174 bytes |
| Model SRAM | 278 bytes |
| Application Size | 229 bytes |
| Application FLASH | 227 bytes |
| Application SRAM | 2 bytes |
Flash Usage |
SRAM Usage |
Update history: [23rd Dec 2025]: Compatible with v1.3 of Tiny ML Modelmaker


