Skip to content

Commit ae3ac31

Browse files
committed
feat(matter): adds new temperature sensor matter endpoint
1 parent cd772f1 commit ae3ac31

File tree

7 files changed

+273
-0
lines changed

7 files changed

+273
-0
lines changed

CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ set(ARDUINO_LIBRARY_Matter_SRCS
175175
libraries/Matter/src/MatterEndpoints/MatterColorLight.cpp
176176
libraries/Matter/src/MatterEndpoints/MatterEnhancedColorLight.cpp
177177
libraries/Matter/src/MatterEndpoints/MatterFan.cpp
178+
libraries/Matter/src/MatterEndpoints/MatterTemperatureSensor.cpp
178179
libraries/Matter/src/Matter.cpp)
179180

180181
set(ARDUINO_LIBRARY_PPP_SRCS
@@ -401,3 +402,4 @@ endif()
401402
if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_WiFiProv)
402403
maybe_add_component(espressif__network_provisioning)
403404
endif()
405+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/*
16+
* This example is the smallest code that will create a Matter Device which can be
17+
* commissioned and controlled from a Matter Environment APP.
18+
* It controls a GPIO that could be attached to a LED for visualization.
19+
* Additionally the ESP32 will send debug messages indicating the Matter activity.
20+
* Turning DEBUG Level ON may be useful to following Matter Accessory and Controller messages.
21+
*/
22+
23+
// Matter Manager
24+
#include <Matter.h>
25+
#include <WiFi.h>
26+
27+
// List of Matter Endpoints for this Node
28+
// Celcius Temperature Sensor Endpoint - at least one per node
29+
MatterTemperatureSensor CelciusTempSensor;
30+
31+
// WiFi is manually set and started
32+
const char *ssid = "your-ssid"; // Change this to your WiFi SSID
33+
const char *password = "your-password"; // Change this to your WiFi password
34+
35+
// Simulate a temperature sensor - add you prefered library code here
36+
float getTemperature() {
37+
static float CelciusTempHWSensor = -10.0;
38+
39+
// it will increase from -10C to 10C in 0.5C steps to simulate a temperature sensor
40+
CelciusTempHWSensor = CelciusTempHWSensor + 0.5;
41+
if (CelciusTempHWSensor > 10) {
42+
CelciusTempHWSensor = -10;
43+
}
44+
45+
return CelciusTempHWSensor;
46+
}
47+
48+
void setup() {
49+
Serial.begin(115200);
50+
51+
// Manually connect to WiFi
52+
WiFi.begin(ssid, password);
53+
// Wait for connection
54+
while (WiFi.status() != WL_CONNECTED) {
55+
delay(500);
56+
Serial.print(".");
57+
}
58+
Serial.println();
59+
60+
// set initial temperature sensor measurement
61+
// Simulated Sensor - it shall print -25C first and then move to the -10C to 10C range
62+
CelciusTempSensor.begin(-25.00);
63+
64+
// Matter beginning - Last step, after all EndPoints are initialized
65+
Matter.begin();
66+
67+
// Check Matter Accessory Commissioning state, which may change during execution of loop()
68+
if (!Matter.isDeviceCommissioned()) {
69+
Serial.println("");
70+
Serial.println("Matter Node is not commissioned yet.");
71+
Serial.println("Initiate the device discovery in your Matter environment.");
72+
Serial.println("Commission it to your Matter hub with the manual pairing code or QR code");
73+
Serial.printf("Manual pairing code: %s\r\n", Matter.getManualPairingCode().c_str());
74+
Serial.printf("QR code URL: %s\r\n", Matter.getOnboardingQRCodeUrl().c_str());
75+
// waits for Matter Temperature Sensor Commissioning.
76+
uint32_t timeCount = 0;
77+
while (!Matter.isDeviceCommissioned()) {
78+
delay(100);
79+
if ((timeCount++ % 50) == 0) { // 50*100ms = 5 sec
80+
Serial.println("Matter Node not commissioned yet. Waiting for commissioning.");
81+
}
82+
}
83+
Serial.println("Matter Node is commissioned and connected to Wi-Fi. Ready for use.");
84+
}
85+
}
86+
87+
void loop() {
88+
Serial.printf("Current Temperature is %.02fC\r\n", (float)CelciusTempSensor);
89+
// update the temperature sensor value every 5 seconds
90+
// Matter phone APP shall display the change in temperature
91+
delay(5000);
92+
CelciusTempSensor = getTemperature();
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"fqbn_append": "PartitionScheme=huge_app",
3+
"requires": [
4+
"CONFIG_SOC_WIFI_SUPPORTED=y",
5+
"CONFIG_ESP_MATTER_ENABLE_DATA_MODEL=y"
6+
]
7+
}

libraries/Matter/keywords.txt

+6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ MatterEndPoint KEYWORD1
1818
MatterFan KEYWORD1
1919
FanMode_t KEYWORD1
2020
FanModeSequence_t KEYWORD1
21+
MatterTemperatureSensor KEYWORD1
2122

2223
#######################################
2324
# Methods and Functions (KEYWORD2)
@@ -62,6 +63,10 @@ setMode KEYWORD2
6263
getMode KEYWORD2
6364
onChangeMode KEYWORD2
6465
onChangeSpeedPercent KEYWORD2
66+
setRawTemperature KEYWORD2
67+
getRawTemperature KEYWORD2
68+
setTemperatureCelsius KEYWORD2
69+
getTemperatureCelsius KEYWORD2
6570

6671
#######################################
6772
# Constants (LITERAL1)
@@ -88,3 +93,4 @@ FAN_MODE_SEQ_OFF_LOW_MED_HIGH_AUTO LITERAL1
8893
FAN_MODE_SEQ_OFF_LOW_HIGH_AUTO LITERAL1
8994
FAN_MODE_SEQ_OFF_HIGH_AUTO LITERAL1
9095
FAN_MODE_SEQ_OFF_HIGH LITERAL1
96+

libraries/Matter/src/Matter.h

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <MatterEndpoints/MatterColorLight.h>
2727
#include <MatterEndpoints/MatterEnhancedColorLight.h>
2828
#include <MatterEndpoints/MatterFan.h>
29+
#include <MatterEndpoints/MatterTemperatureSensor.h>
2930

3031
using namespace esp_matter;
3132

@@ -58,6 +59,7 @@ class ArduinoMatter {
5859
friend class MatterColorLight;
5960
friend class MatterEnhancedColorLight;
6061
friend class MatterFan;
62+
friend class MatterTemperatureSensor;
6163

6264
protected:
6365
static void _init();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <sdkconfig.h>
16+
#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
17+
18+
#include <Matter.h>
19+
#include <app/server/Server.h>
20+
#include <MatterEndpoints/MatterTemperatureSensor.h>
21+
22+
using namespace esp_matter;
23+
using namespace esp_matter::endpoint;
24+
using namespace chip::app::Clusters;
25+
26+
bool MatterTemperatureSensor::attributeChangeCB(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val) {
27+
bool ret = true;
28+
if (!started) {
29+
log_e("Matter Temperature Sensor device has not begun.");
30+
return false;
31+
}
32+
33+
log_d("Temperature Sensor Attr update callback: endpoint: %u, cluster: %u, attribute: %u, val: %u", endpoint_id, cluster_id, attribute_id, val->val.u32);
34+
return ret;
35+
}
36+
37+
MatterTemperatureSensor::MatterTemperatureSensor() {}
38+
39+
MatterTemperatureSensor::~MatterTemperatureSensor() {
40+
end();
41+
}
42+
43+
bool MatterTemperatureSensor::begin(int16_t _rawTemperature) {
44+
ArduinoMatter::_init();
45+
46+
temperature_sensor::config_t temperature_sensor_config;
47+
temperature_sensor_config.temperature_measurement.measured_value = _rawTemperature;
48+
temperature_sensor_config.temperature_measurement.min_measured_value = nullptr;
49+
temperature_sensor_config.temperature_measurement.max_measured_value = nullptr;
50+
51+
// endpoint handles can be used to add/modify clusters.
52+
endpoint_t *endpoint = temperature_sensor::create(node::get(), &temperature_sensor_config, ENDPOINT_FLAG_NONE, (void *)this);
53+
if (endpoint == nullptr) {
54+
log_e("Failed to create Temperature Sensor endpoint");
55+
return false;
56+
}
57+
rawTemperature = _rawTemperature;
58+
setEndPointId(endpoint::get_id(endpoint));
59+
log_i("Temperature Sensor created with endpoint_id %d", getEndPointId());
60+
started = true;
61+
return true;
62+
}
63+
64+
void MatterTemperatureSensor::end() {
65+
started = false;
66+
}
67+
68+
bool MatterTemperatureSensor::setRawTemperature(int16_t _rawTemperature) {
69+
if (!started) {
70+
log_e("Matter Temperature Sensor device has not begun.");
71+
return false;
72+
}
73+
74+
// avoid processing the a "no-change"
75+
if (rawTemperature == _rawTemperature) {
76+
return true;
77+
}
78+
79+
esp_matter_attr_val_t temperatureVal = esp_matter_invalid(NULL);
80+
81+
if (!getAttributeVal(TemperatureMeasurement::Id, TemperatureMeasurement::Attributes::MeasuredValue::Id, &temperatureVal)) {
82+
log_e("Failed to get Temperature Sensor Attribute.");
83+
return false;
84+
}
85+
if (temperatureVal.val.i16 != _rawTemperature) {
86+
temperatureVal.val.i16 = _rawTemperature;
87+
bool ret;
88+
ret = updateAttributeVal(TemperatureMeasurement::Id, TemperatureMeasurement::Attributes::MeasuredValue::Id, &temperatureVal);
89+
if (!ret) {
90+
log_e("Failed to update Fan Speed Percent Attribute.");
91+
return false;
92+
}
93+
rawTemperature = _rawTemperature;
94+
}
95+
log_v("Temperature Sensor set to %.02f Celcius Degrees", (float)_rawTemperature / 100.00);
96+
97+
return true;
98+
}
99+
100+
#endif /* CONFIG_ESP_MATTER_ENABLE_DATA_MODEL */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#pragma once
16+
#include <sdkconfig.h>
17+
#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL
18+
19+
#include <Matter.h>
20+
#include <MatterEndPoint.h>
21+
22+
class MatterTemperatureSensor : public MatterEndPoint {
23+
public:
24+
MatterTemperatureSensor();
25+
~MatterTemperatureSensor();
26+
// default initial raw temperature
27+
virtual bool begin(int16_t _rawTemperature = 0);
28+
bool begin(double temperatureCelcius) {
29+
int16_t rawValue = static_cast<int16_t>(temperatureCelcius * 100.0f);
30+
return begin(rawValue);
31+
}
32+
// this will just stop processing Temperature Sensor Matter events
33+
void end();
34+
35+
// set the reported raw temperature
36+
bool setRawTemperature(int16_t _rawTemperature);
37+
bool setTemperatureCelsius(double temperatureCelcius) {
38+
int16_t rawValue = static_cast<int16_t>(temperatureCelcius * 100.0f);
39+
return setRawTemperature(rawValue);
40+
}
41+
int16_t getRawTemperature() { // returns the reported raw temperature
42+
return rawTemperature;
43+
}
44+
double getTemperatureCelsius() { // returns the reported temperature in Celcius
45+
return (double)rawTemperature / 100.0;
46+
}
47+
void operator=(double temperatureCelcius) { // sets the reported temperature in Celcius{
48+
int16_t rawValue = static_cast<int16_t>(temperatureCelcius * 100.0f);
49+
setRawTemperature(rawValue);
50+
}
51+
operator double() { // returns the reported temperature in Celcius
52+
return (double) getTemperatureCelsius();
53+
}
54+
55+
// this function is called by Matter internal event processor. It could be overwritten by the application, if necessary.
56+
bool attributeChangeCB(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val);
57+
// User Callback for whenever the Light state is changed by the Matter Controller
58+
59+
protected:
60+
bool started = false;
61+
int16_t rawTemperature = 0; // default initial reported temperature
62+
};
63+
#endif /* CONFIG_ESP_MATTER_ENABLE_DATA_MODEL */

0 commit comments

Comments
 (0)