blob: 0164749ce7167b28eb2b8d4b44ce359055f828d5 [file] [log] [blame]
/*
*
* Copyright (c) 2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SensorManagerCommon.h"
#include "PWMManager.h"
#ifdef CONFIG_CHIP_USE_MARS_SENSOR
#include <zephyr/drivers/sensor.h>
#endif // CONFIG_CHIP_USE_MARS_SENSOR
LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);
using namespace chip;
using namespace ::chip::DeviceLayer;
constexpr float kMinTempDelta = 0.5; // 0.5 degree Celsius
#ifdef CONFIG_CHIP_USE_MARS_SENSOR
k_timer sSensorBanForNextMeasurTimer;
volatile bool mSensorBanForNextMeasurFlag = false;
constexpr uint16_t kSensorBanForNextMeasurTimeout = 1000; // 1s timeout
const struct device * const sht3xd_dev = DEVICE_DT_GET_ONE(sensirion_sht3xd);
#ifdef USE_COLOR_TEMPERATURE_LIGHT
#define TEMP_LOW_LIM 0 // °C
#define TEMP_HIGH_LIM 40 // °C
#endif // USE_COLOR_TEMPERATURE_LIGHT
#else
constexpr float kSimulatedHum = 55.5; // percents
constexpr uint16_t kSimulatedReadingFrequency = 4; // change simulated number
static float mSimulatedTemp[] = { 23.01, 24.02, 28.03, 25.50, 22.05, 21.25, 21.07, 26.08, 18.09, 27.11 };
#endif // CONFIG_CHIP_USE_MARS_SENSOR
SensorManager SensorManager::sSensorManager;
CHIP_ERROR SensorManager::Init()
{
#ifdef CONFIG_CHIP_USE_MARS_SENSOR
if (!device_is_ready(sht3xd_dev))
{
LOG_ERR("Device %s is not ready", sht3xd_dev->name);
return CHIP_ERROR_INCORRECT_STATE;
}
#ifdef USE_COLOR_TEMPERATURE_LIGHT
RgbColor_t rgb = { 0 };
#endif // USE_COLOR_TEMPERATURE_LIGHT
// Initialise the timer to ban sensor measurement
k_timer_init(&sSensorBanForNextMeasurTimer, &SensorManager::SensorBanForNextMeasurTimerTimeoutCallback, nullptr);
k_timer_user_data_set(&sSensorBanForNextMeasurTimer, this);
#endif // CONFIG_CHIP_USE_MARS_SENSOR
return CHIP_NO_ERROR;
}
CHIP_ERROR SensorManager::GetTempAndHumMeasurValue(int16_t * pTempMeasured, uint16_t * pHumMeasured)
{
static float lastTemp = 0.0;
float temp = 0.0;
float hum = 0.0;
#ifdef CONFIG_CHIP_USE_MARS_SENSOR
static struct sensor_value sensorTemp = { 0 };
static struct sensor_value sensorHum = { 0 };
if (!mSensorBanForNextMeasurFlag)
{
int status = sensor_sample_fetch(sht3xd_dev);
if (status)
{
LOG_ERR("Device %s is not ready to fetch the sensor samples (status: %d)", sht3xd_dev->name, status);
return System::MapErrorZephyr(status);
}
status = sensor_channel_get(sht3xd_dev, SENSOR_CHAN_AMBIENT_TEMP, &sensorTemp);
if (status)
{
LOG_ERR("Device %s is not ready to temperature measurement (status: %d)", sht3xd_dev->name, status);
return System::MapErrorZephyr(status);
}
status = sensor_channel_get(sht3xd_dev, SENSOR_CHAN_HUMIDITY, &sensorHum);
if (status)
{
LOG_ERR("Device %s is not ready to humidity measurement (status: %d)", sht3xd_dev->name, status);
return System::MapErrorZephyr(status);
}
mSensorBanForNextMeasurFlag = true;
// Start next timer to measurement the air quality sensor
k_timer_start(&sSensorBanForNextMeasurTimer, K_MSEC(kSensorBanForNextMeasurTimeout), K_NO_WAIT);
}
temp = (float) sensor_value_to_double(&sensorTemp);
hum = (float) sensor_value_to_double(&sensorHum);
#ifdef USE_COLOR_TEMPERATURE_LIGHT
SetColorTemperatureLight(temp);
#endif // USE_COLOR_TEMPERATURE_LIGHT
#else
/* Temperature simulation is used */
static uint8_t nbOfRepetition = 0;
static uint8_t simulatedIndex = 0;
if (simulatedIndex >= ArraySize(mSimulatedTemp))
{
simulatedIndex = 0;
}
temp = mSimulatedTemp[simulatedIndex];
nbOfRepetition++;
if (nbOfRepetition >= kSimulatedReadingFrequency)
{
simulatedIndex++;
nbOfRepetition = 0;
}
/* Humidity simulation is used */
hum = kSimulatedHum;
#endif // CONFIG_CHIP_USE_MARS_SENSOR
if ((temp >= (lastTemp + kMinTempDelta)) || temp <= (lastTemp - kMinTempDelta))
{
lastTemp = temp;
}
else
{
temp = lastTemp;
}
if (pTempMeasured != NULL)
{
// Per spec Application Clusters 2.3.4.1. : MeasuredValue = 100 x temperature [°C]
*pTempMeasured = (int16_t) 100 * temp;
}
if (pHumMeasured != NULL)
{
*pHumMeasured = (uint16_t) hum;
}
return CHIP_NO_ERROR;
}
int16_t SensorManager::GetMinMeasuredTempValue()
{
return mMinMeasuredTempCelsius;
}
int16_t SensorManager::GetMaxMeasuredTempValue()
{
return mMaxMeasuredTempCelsius;
}
#ifdef CONFIG_CHIP_USE_MARS_SENSOR
void SensorManager::SensorBanForNextMeasurTimerTimeoutCallback(k_timer * timer)
{
if (!timer)
{
return;
}
mSensorBanForNextMeasurFlag = false;
}
#ifdef USE_COLOR_TEMPERATURE_LIGHT
void SensorManager::SetColorTemperatureLight(int8_t temp)
{
RgbColor_t rgb = { 0 };
if (temp >= mMinMeasuredTempCelsius && temp <= TEMP_LOW_LIM)
{
/* Set Color Temperature Light in range -40...0°C */
rgb.b = RGB_MAX_VALUE * (1 - ((float) temp - TEMP_LOW_LIM) / (mMinMeasuredTempCelsius - TEMP_LOW_LIM));
}
else if (temp >= TEMP_HIGH_LIM && temp <= mMaxMeasuredTempCelsius)
{
/* Set Color Temperature Light in range 40...125°C */
rgb.r = RGB_MAX_VALUE * (1 - ((float) temp - TEMP_HIGH_LIM) / (mMaxMeasuredTempCelsius - TEMP_HIGH_LIM));
}
else if (temp > TEMP_LOW_LIM && temp < TEMP_HIGH_LIM)
{
uint8_t steps_in_part = (TEMP_HIGH_LIM - TEMP_LOW_LIM) / 4;
uint8_t step_num = temp % steps_in_part;
float step_val = (float) RGB_MAX_VALUE / steps_in_part;
if (temp < steps_in_part)
{
/* Set Color Temperature Light in range 1...9°C */
rgb.b = RGB_MAX_VALUE;
rgb.g = step_num * step_val;
}
else if (temp < 2 * steps_in_part)
{
/* Set Color Temperature Light in range 10...19°C */
rgb.b = RGB_MAX_VALUE;
rgb.g = RGB_MAX_VALUE;
rgb.r = step_num * step_val;
}
else if (temp < 3 * steps_in_part)
{
/* Set Color Temperature Light in range 20...29°C */
rgb.r = RGB_MAX_VALUE;
rgb.g = RGB_MAX_VALUE;
rgb.b = RGB_MAX_VALUE - (step_num * step_val);
}
else
{
/* Set Color Temperature Light in range 30...39°C */
rgb.r = RGB_MAX_VALUE;
rgb.g = RGB_MAX_VALUE - (step_num * step_val);
}
}
else
{
LOG_ERR("Couldn't set the Color Temperature Light");
}
PwmManager::getInstance().setPwm(PwmManager::EAppPwm_Red, ((uint32_t) rgb.r * 1000) / 0xff);
PwmManager::getInstance().setPwm(PwmManager::EAppPwm_Green, ((uint32_t) rgb.g * 1000) / 0xff);
PwmManager::getInstance().setPwm(PwmManager::EAppPwm_Blue, ((uint32_t) rgb.b * 1000) / 0xff);
}
#endif // USE_COLOR_TEMPERATURE_LIGHT
#endif // CONFIG_CHIP_USE_MARS_SENSOR