Skip to content

Commit 639a08e

Browse files
authored
Merge pull request #10710 from SuGlider/matter_pressure_sensor
feat(matter): adds a Pressure Sensor Matter Endpoint
2 parents 626a09f + 56a9b1d commit 639a08e

File tree

7 files changed

+305
-0
lines changed

7 files changed

+305
-0
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ set(ARDUINO_LIBRARY_Matter_SRCS
177177
libraries/Matter/src/MatterEndpoints/MatterFan.cpp
178178
libraries/Matter/src/MatterEndpoints/MatterTemperatureSensor.cpp
179179
libraries/Matter/src/MatterEndpoints/MatterHumiditySensor.cpp
180+
libraries/Matter/src/MatterEndpoints/MatterPressureSensor.cpp
180181
libraries/Matter/src/Matter.cpp)
181182

182183
set(ARDUINO_LIBRARY_PPP_SRCS
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
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 an example code that will create a Matter Device which can be
17+
* commissioned and controlled from a Matter Environment APP.
18+
* Additionally the ESP32 will send debug messages indicating the Matter activity.
19+
* Turning DEBUG Level ON may be useful to following Matter Accessory and Controller messages.
20+
*/
21+
22+
// Matter Manager
23+
#include <Matter.h>
24+
#include <WiFi.h>
25+
26+
// List of Matter Endpoints for this Node
27+
// Matter Pressure Sensor Endpoint
28+
MatterPressureSensor SimulatedPressureSensor;
29+
30+
// set your board USER BUTTON pin here - decommissioning button
31+
const uint8_t buttonPin = BOOT_PIN; // Set your pin here. Using BOOT Button.
32+
33+
// WiFi is manually set and started
34+
const char *ssid = "your-ssid"; // Change this to your WiFi SSID
35+
const char *password = "your-password"; // Change this to your WiFi password
36+
37+
// Button control - decommision the Matter Node
38+
uint32_t button_time_stamp = 0; // debouncing control
39+
bool button_state = false; // false = released | true = pressed
40+
const uint32_t decommissioningTimeout = 5000; // keep the button pressed for 5s, or longer, to decommission
41+
42+
// Simulate a pressure sensor - add your preferred pressure sensor library code here
43+
float getSimulatedPressure() {
44+
// The Endpoint implementation keeps an uint16_t as internal value information,
45+
// which stores data in hPa (pressure measurement unit)
46+
static float simulatedPressureHWSensor = 950;
47+
48+
// it will increase from 950 to 1100 hPa in steps of 10 hPa to simulate a pressure sensor
49+
simulatedPressureHWSensor = simulatedPressureHWSensor + 10;
50+
if (simulatedPressureHWSensor > 1100) {
51+
simulatedPressureHWSensor = 950;
52+
}
53+
54+
return simulatedPressureHWSensor;
55+
}
56+
57+
void setup() {
58+
// Initialize the USER BUTTON (Boot button) that will be used to decommission the Matter Node
59+
pinMode(buttonPin, INPUT_PULLUP);
60+
61+
Serial.begin(115200);
62+
63+
// Manually connect to WiFi
64+
WiFi.begin(ssid, password);
65+
// Wait for connection
66+
while (WiFi.status() != WL_CONNECTED) {
67+
delay(500);
68+
Serial.print(".");
69+
}
70+
Serial.println();
71+
72+
// set initial pressure sensor measurement
73+
// Simulated Sensor - it shall initially print 900hPa and then move to the 950 to 1100 hPa as pressure range
74+
SimulatedPressureSensor.begin(900.00);
75+
76+
// Matter beginning - Last step, after all EndPoints are initialized
77+
Matter.begin();
78+
79+
// Check Matter Accessory Commissioning state, which may change during execution of loop()
80+
if (!Matter.isDeviceCommissioned()) {
81+
Serial.println("");
82+
Serial.println("Matter Node is not commissioned yet.");
83+
Serial.println("Initiate the device discovery in your Matter environment.");
84+
Serial.println("Commission it to your Matter hub with the manual pairing code or QR code");
85+
Serial.printf("Manual pairing code: %s\r\n", Matter.getManualPairingCode().c_str());
86+
Serial.printf("QR code URL: %s\r\n", Matter.getOnboardingQRCodeUrl().c_str());
87+
// waits for Matter Pressure Sensor Commissioning.
88+
uint32_t timeCount = 0;
89+
while (!Matter.isDeviceCommissioned()) {
90+
delay(100);
91+
if ((timeCount++ % 50) == 0) { // 50*100ms = 5 sec
92+
Serial.println("Matter Node not commissioned yet. Waiting for commissioning.");
93+
}
94+
}
95+
Serial.println("Matter Node is commissioned and connected to Wi-Fi. Ready for use.");
96+
}
97+
}
98+
99+
void loop() {
100+
static uint32_t timeCounter = 0;
101+
102+
// Print the current pressure value every 5s
103+
if (!(timeCounter++ % 10)) { // delaying for 500ms x 10 = 5s
104+
// Print the current pressure value
105+
Serial.printf("Current Pressure is %.02fhPa\r\n", SimulatedPressureSensor.getPressure());
106+
// Update Pressure from the (Simulated) Hardware Sensor
107+
// Matter APP shall display the updated pressure percent
108+
SimulatedPressureSensor.setPressure(getSimulatedPressure());
109+
}
110+
111+
// Check if the button has been pressed
112+
if (digitalRead(buttonPin) == LOW && !button_state) {
113+
// deals with button debouncing
114+
button_time_stamp = millis(); // record the time while the button is pressed.
115+
button_state = true; // pressed.
116+
}
117+
118+
if (digitalRead(buttonPin) == HIGH && button_state) {
119+
button_state = false; // released
120+
}
121+
122+
// Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node
123+
uint32_t time_diff = millis() - button_time_stamp;
124+
if (button_state && time_diff > decommissioningTimeout) {
125+
// Factory reset is triggered if the button is pressed longer than 10 seconds
126+
Serial.println("Decommissioning the Light Matter Accessory. It shall be commissioned again.");
127+
Matter.decommission();
128+
}
129+
130+
delay(500);
131+
}
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

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ FanMode_t KEYWORD1
2020
FanModeSequence_t KEYWORD1
2121
MatterTemperatureSensor KEYWORD1
2222
MatterHumiditySensor KEYWORD1
23+
MatterPressureSensor KEYWORD1
2324

2425
#######################################
2526
# Methods and Functions (KEYWORD2)
@@ -68,6 +69,8 @@ setTemperature KEYWORD2
6869
getTemperature KEYWORD2
6970
setHumidity KEYWORD2
7071
getHumidity KEYWORD2
72+
setPressure KEYWORD2
73+
getPressure KEYWORD2
7174

7275
#######################################
7376
# Constants (LITERAL1)

libraries/Matter/src/Matter.h

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <MatterEndpoints/MatterFan.h>
2929
#include <MatterEndpoints/MatterTemperatureSensor.h>
3030
#include <MatterEndpoints/MatterHumiditySensor.h>
31+
#include <MatterEndpoints/MatterPressureSensor.h>
3132

3233
using namespace esp_matter;
3334

@@ -62,6 +63,7 @@ class ArduinoMatter {
6263
friend class MatterFan;
6364
friend class MatterTemperatureSensor;
6465
friend class MatterHumiditySensor;
66+
friend class MatterPressureSensor;
6567

6668
protected:
6769
static void _init();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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 <MatterEndpoints/MatterPressureSensor.h>
20+
21+
using namespace esp_matter;
22+
using namespace esp_matter::endpoint;
23+
using namespace chip::app::Clusters;
24+
25+
bool MatterPressureSensor::attributeChangeCB(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val) {
26+
bool ret = true;
27+
if (!started) {
28+
log_e("Matter Pressure Sensor device has not begun.");
29+
return false;
30+
}
31+
32+
log_d("Pressure Sensor Attr update callback: endpoint: %u, cluster: %u, attribute: %u, val: %u", endpoint_id, cluster_id, attribute_id, val->val.u32);
33+
return ret;
34+
}
35+
36+
MatterPressureSensor::MatterPressureSensor() {}
37+
38+
MatterPressureSensor::~MatterPressureSensor() {
39+
end();
40+
}
41+
42+
bool MatterPressureSensor::begin(int16_t _rawPressure) {
43+
ArduinoMatter::_init();
44+
45+
pressure_sensor::config_t pressure_sensor_config;
46+
pressure_sensor_config.pressure_measurement.pressure_measured_value = _rawPressure;
47+
pressure_sensor_config.pressure_measurement.pressure_min_measured_value = nullptr;
48+
pressure_sensor_config.pressure_measurement.pressure_max_measured_value = nullptr;
49+
50+
// endpoint handles can be used to add/modify clusters
51+
endpoint_t *endpoint = pressure_sensor::create(node::get(), &pressure_sensor_config, ENDPOINT_FLAG_NONE, (void *)this);
52+
if (endpoint == nullptr) {
53+
log_e("Failed to create Pressure Sensor endpoint");
54+
return false;
55+
}
56+
rawPressure = _rawPressure;
57+
setEndPointId(endpoint::get_id(endpoint));
58+
log_i("Pressure Sensor created with endpoint_id %d", getEndPointId());
59+
started = true;
60+
return true;
61+
}
62+
63+
void MatterPressureSensor::end() {
64+
started = false;
65+
}
66+
67+
bool MatterPressureSensor::setRawPressure(int16_t _rawPressure) {
68+
if (!started) {
69+
log_e("Matter Pressure Sensor device has not begun.");
70+
return false;
71+
}
72+
73+
// avoid processing the a "no-change"
74+
if (rawPressure == _rawPressure) {
75+
return true;
76+
}
77+
78+
esp_matter_attr_val_t pressureVal = esp_matter_invalid(NULL);
79+
80+
if (!getAttributeVal(PressureMeasurement::Id, PressureMeasurement::Attributes::MeasuredValue::Id, &pressureVal)) {
81+
log_e("Failed to get Pressure Sensor Attribute.");
82+
return false;
83+
}
84+
if (pressureVal.val.i16 != _rawPressure) {
85+
pressureVal.val.i16 = _rawPressure;
86+
bool ret;
87+
ret = updateAttributeVal(PressureMeasurement::Id, PressureMeasurement::Attributes::MeasuredValue::Id, &pressureVal);
88+
if (!ret) {
89+
log_e("Failed to update Pressure Sensor Measurement Attribute.");
90+
return false;
91+
}
92+
rawPressure = _rawPressure;
93+
}
94+
log_v("Pressure Sensor set to %.02f Degrees", (float)_rawPressure / 100.00);
95+
96+
return true;
97+
}
98+
99+
#endif /* CONFIG_ESP_MATTER_ENABLE_DATA_MODEL */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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 MatterPressureSensor : public MatterEndPoint {
23+
public:
24+
MatterPressureSensor();
25+
~MatterPressureSensor();
26+
// begin Matter Pressure Sensor endpoint with initial float pressure
27+
bool begin(double pressure = 0.00) {
28+
return begin(static_cast<int16_t>(pressure));
29+
}
30+
// this will stop processing Pressure Sensor Matter events
31+
void end();
32+
33+
// set the reported raw pressure in hPa
34+
bool setPressure(double pressure) {
35+
int16_t rawValue = static_cast<int16_t>(pressure);
36+
return setRawPressure(rawValue);
37+
}
38+
// returns the reported float pressure in hPa
39+
double getPressure() {
40+
return (double)rawPressure;
41+
}
42+
// double conversion operator
43+
void operator=(double pressure) {
44+
setPressure(pressure);
45+
}
46+
// double conversion operator
47+
operator double() {
48+
return (double)getPressure();
49+
}
50+
51+
// this function is called by Matter internal event processor. It could be overwritten by the application, if necessary.
52+
bool attributeChangeCB(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val);
53+
54+
protected:
55+
bool started = false;
56+
// implementation keeps pressure in hPa
57+
int16_t rawPressure = 0;
58+
// internal function to set the raw pressure value (Matter Cluster)
59+
bool setRawPressure(int16_t _rawPressure);
60+
bool begin(int16_t _rawPressure);
61+
};
62+
#endif /* CONFIG_ESP_MATTER_ENABLE_DATA_MODEL */

0 commit comments

Comments
 (0)