forked from project-chip/connectedhomeip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEnergyTimeUtils.cpp
153 lines (133 loc) · 5.36 KB
/
EnergyTimeUtils.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
*
* Copyright (c) 2024 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 <EnergyTimeUtils.h>
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app/EventLogging.h>
using namespace chip;
using namespace chip::app;
using namespace chip::app::DataModel;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::EnergyEvse;
using namespace chip::app::Clusters::EnergyEvse::Attributes;
using chip::app::LogEvent;
using chip::Protocols::InteractionModel::Status;
namespace chip {
namespace app {
namespace Clusters {
namespace DeviceEnergyManagement {
/**
* @brief Helper function to get current timestamp in Epoch format
*
* @param[out] chipEpoch reference to hold return timestamp. Set to 0 if an error occurs.
*/
CHIP_ERROR GetEpochTS(uint32_t & chipEpoch)
{
chipEpoch = 0;
System::Clock::Milliseconds64 cTMs;
CHIP_ERROR err = System::SystemClock().GetClock_RealTimeMS(cTMs);
/* If the GetClock_RealTimeMS returns CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE, then
* This platform cannot ever report real time !
* This should not be certifiable since getting time is a Mandatory
* feature of EVSE Cluster
*/
VerifyOrDie(err != CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Zcl, "Unable to get current time - err:%" CHIP_ERROR_FORMAT, err.Format());
return err;
}
auto unixEpoch = std::chrono::duration_cast<System::Clock::Seconds32>(cTMs).count();
if (!UnixEpochToChipEpochTime(unixEpoch, chipEpoch))
{
ChipLogError(Zcl, "Unable to convert Unix Epoch time to Matter Epoch Time");
return CHIP_ERROR_INCORRECT_STATE;
}
return CHIP_NO_ERROR;
}
/**
* @brief Helper function to get current timestamp and work out the day of week
*
* NOTE that the time_t is converted using localtime to provide the timestamp
* in local time. If this is not supported on some platforms an alternative
* implementation may be required.
*
* @param unixEpoch (as time_t)
*
* @return bitmap value for day of week as defined by EnergyEvse::TargetDayOfWeekBitmap. Note
* only one bit will be set for the day of the week.
*/
BitMask<EnergyEvse::TargetDayOfWeekBitmap> GetLocalDayOfWeekFromUnixEpoch(time_t unixEpoch)
{
// Define a timezone structure and initialize it to the local timezone
// This will capture any daylight saving time changes
struct tm local_time;
localtime_r(&unixEpoch, &local_time);
// Get the day of the week (0 = Sunday, 1 = Monday, ..., 6 = Saturday)
uint8_t dayOfWeek = static_cast<uint8_t>(local_time.tm_wday);
// Calculate the bitmap value based on the day of the week. Note that the value in bitmap
// maps directly to the definition in EnergyEvse::TargetDayOfWeekBitmap.
uint8_t bitmap = static_cast<uint8_t>(1 << dayOfWeek);
return bitmap;
}
/**
* @brief Helper function to get current timestamp and work out the day of week based on localtime
*
* @return bitmap value for day of week as defined by EnergyEvse::TargetDayOfWeekBitmap. Note
* only one bit will be set for the current day.
*/
CHIP_ERROR GetLocalDayOfWeekNow(BitMask<EnergyEvse::TargetDayOfWeekBitmap> & dayOfWeekMap)
{
System::Clock::Milliseconds64 cTMs;
CHIP_ERROR err = chip::System::SystemClock().GetClock_RealTimeMS(cTMs);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Zcl, "Uable to get current time. error=%" CHIP_ERROR_FORMAT, err.Format());
return err;
}
time_t unixEpoch = std::chrono::duration_cast<chip::System::Clock::Seconds32>(cTMs).count();
dayOfWeekMap = GetLocalDayOfWeekFromUnixEpoch(unixEpoch);
return CHIP_NO_ERROR;
}
/**
* @brief Helper function to get current timestamp and work out the current number of minutes
* past midnight based on localtime
*
* @param reference to hold the number of minutes past midnight
*/
CHIP_ERROR GetMinutesPastMidnight(uint16_t & minutesPastMidnight)
{
chip::System::Clock::Milliseconds64 cTMs;
CHIP_ERROR err = chip::System::SystemClock().GetClock_RealTimeMS(cTMs);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Zcl, "EVSE: unable to get current time to check user schedules error=%" CHIP_ERROR_FORMAT, err.Format());
return err;
}
time_t unixEpoch = std::chrono::duration_cast<chip::System::Clock::Seconds32>(cTMs).count();
// Define a timezone structure and initialize it to the local timezone
// This will capture any daylight saving time changes
struct tm local_time;
localtime_r(&unixEpoch, &local_time);
minutesPastMidnight = static_cast<uint16_t>((local_time.tm_hour * 60) + local_time.tm_min);
return err;
}
} // namespace DeviceEnergyManagement
} // namespace Clusters
} // namespace app
} // namespace chip