@@ -28,12 +28,173 @@ using namespace chip::app::Clusters;
2828using namespace chip ::app::Clusters::CommodityTariff;
2929using namespace chip ::app::Clusters::CommodityTariff::Structs;
3030using namespace chip ::app::Clusters::CommodityTariff::TariffDataSamples;
31+ using namespace chip ::System;
32+ using namespace chip ::System::Clock;
33+ using namespace chip ::System::Clock::Literals;
3134
3235static constexpr uint32_t kSecondsPer4hr = 14400 ; // 4 hours in seconds
3336
3437static uint8_t presetIndex = 0 ;
3538
36- // Number of presets (compile-time constant)
39+ // Test Time Management Implementation
40+ namespace {
41+
42+ class TestTimeManager
43+ {
44+ public:
45+ TestTimeManager () = default ;
46+ ~TestTimeManager () { ShutdownMockClock (); }
47+
48+ void EnableTestTime (bool enable, uint32_t aInitialTimeValue_s = 0 );
49+ void AdvanceTestTime (chip::System::Clock::Seconds32 offset);
50+ bool IsTestTimeEnabled () const { return mTestTimeEnabled ; }
51+
52+ private:
53+ void InitializeMockClock (uint32_t aInitialTimeValue_s = 0 );
54+ void ShutdownMockClock ();
55+ void AdvanceMockTime (chip::System::Clock::Seconds32 offset);
56+
57+ chip::System::Clock::Internal::MockClock * pMockClock = nullptr ;
58+ chip::System::Clock::ClockBase * pRealClock = nullptr ;
59+ bool mTestTimeEnabled = false ;
60+ };
61+
62+ TestTimeManager gTestTimeManager ;
63+
64+ void TestTimeManager::InitializeMockClock (uint32_t aInitialTimeValue_s)
65+ {
66+ // Create and configure the mock clock
67+ pMockClock = new Clock::Internal::MockClock ();
68+ pRealClock = &SystemClock ();
69+ Microseconds64 realTime_us;
70+ CHIP_ERROR err = CHIP_NO_ERROR;
71+
72+ if (aInitialTimeValue_s == 0 )
73+ {
74+ // Get current real time to use as initial mock time
75+ err = chip::System::SystemClock ().GetClock_RealTime (realTime_us);
76+ }
77+ else
78+ {
79+ realTime_us = aInitialTimeValue_s * 1'000' 000_us; // seconds to microseconds
80+ }
81+
82+ if (err == CHIP_NO_ERROR)
83+ {
84+ pMockClock->SetClock_RealTime (realTime_us);
85+
86+ // Also set monotonic time to maintain consistency
87+ auto monotonicTime = std::chrono::duration_cast<Milliseconds64>(realTime_us);
88+ pMockClock->SetMonotonic (monotonicTime);
89+
90+ ChipLogProgress (DeviceLayer, " Mock clock initialized with current real time" );
91+ }
92+ else
93+ {
94+ // Fallback: use a reasonable default time if real time is unavailable
95+ Microseconds64 defaultTime (std::chrono::seconds (1704067200 )); // Jan 1, 2024
96+ pMockClock->SetClock_RealTime (defaultTime);
97+ pMockClock->SetMonotonic (std::chrono::duration_cast<Milliseconds64>(defaultTime));
98+
99+ ChipLogProgress (DeviceLayer, " Mock clock initialized with default time" );
100+ }
101+
102+ // Install the mock clock globally
103+ Clock::Internal::SetSystemClockForTesting (pMockClock);
104+ }
105+
106+ void TestTimeManager::ShutdownMockClock ()
107+ {
108+ if (pMockClock)
109+ {
110+ // Restore the real system clock
111+ Clock::Internal::SetSystemClockForTesting (pRealClock);
112+ delete pMockClock;
113+ pMockClock = nullptr ;
114+ }
115+ }
116+
117+ void TestTimeManager::AdvanceMockTime (Seconds32 offset)
118+ {
119+ if (!mTestTimeEnabled || !pMockClock)
120+ {
121+ ChipLogError (DeviceLayer, " Cannot advance time - test time not enabled" );
122+ return ;
123+ }
124+
125+ // Get current mock time
126+ Microseconds64 currentTime, newTime;
127+
128+ pMockClock->GetClock_RealTime (currentTime);
129+
130+ // Update both real time and monotonic time consistently
131+ pMockClock->AdvanceRealTime (std::chrono::duration_cast<Milliseconds64>(offset));
132+ pMockClock->AdvanceMonotonic (std::chrono::duration_cast<Milliseconds64>(offset));
133+
134+ // Update base time reference
135+ pMockClock->GetClock_RealTime (newTime);
136+
137+ ChipLogProgress (DeviceLayer, " Advanced mock time: %" PRIu32 " s -> %" PRIu32 " s (+%" PRIu32 " s)" ,
138+ std::chrono::duration_cast<Seconds32>(currentTime).count (),
139+ std::chrono::duration_cast<Seconds32>(newTime).count (), offset.count ());
140+ }
141+
142+ void TestTimeManager::EnableTestTime (bool enable, uint32_t aInitialTimeValue_s)
143+ {
144+ if (enable == mTestTimeEnabled )
145+ {
146+ // No change needed, but still trigger updates if re-enabling with same state
147+ if (enable)
148+ {
149+ ChipLogProgress (DeviceLayer, " Test time already enabled" );
150+ }
151+ else
152+ {
153+ ChipLogProgress (DeviceLayer, " Test time already disabled" );
154+ }
155+ return ;
156+ }
157+
158+ if (enable)
159+ {
160+ // Enable test time mode
161+ InitializeMockClock (aInitialTimeValue_s);
162+ mTestTimeEnabled = true ;
163+ ChipLogProgress (DeviceLayer, " 🔧 Test time mode ENABLED - using mock clock" );
164+ }
165+ else
166+ {
167+ // Disable test time mode - this effectively resets to real time
168+ ShutdownMockClock ();
169+ mTestTimeEnabled = false ;
170+ ChipLogProgress (DeviceLayer, " ⏰ Test time mode DISABLED - restored real system clock" );
171+ }
172+ }
173+
174+ void TestTimeManager::AdvanceTestTime (Seconds32 offset)
175+ {
176+ if (!mTestTimeEnabled )
177+ {
178+ ChipLogError (DeviceLayer, " Cannot advance time - test time not enabled. Call EnableTestTime(true) first." );
179+ return ;
180+ }
181+
182+ if (offset.count () > 0 )
183+ {
184+ AdvanceMockTime (offset);
185+ ChipLogProgress (DeviceLayer, " ⏩ Time advanced by %" PRIu32 " seconds (%" PRIu32 " minutes, %" PRIu32 " hours)" ,
186+ offset.count (), offset.count () / 60 , offset.count () / 3600 );
187+ }
188+
189+ // Trigger tariff time synchronization
190+ CommodityTariffInstance * instance = GetCommodityTariffInstance ();
191+ if (instance)
192+ {
193+ instance->TariffTimeAttrsSync ();
194+ }
195+ }
196+
197+ } // anonymous namespace
37198
38199// Safe accessor function
39200static const TariffDataSet & GetNextPreset ()
@@ -47,7 +208,6 @@ void SetTestEventTrigger_TariffDataUpdated()
47208{
48209 const TariffDataSet & tariff_preset = GetNextPreset ();
49210 CommodityTariffDelegate * dg = GetCommodityTariffDelegate ();
50- CommodityTariffInstance * instance = GetCommodityTariffInstance ();
51211
52212 using namespace chip ::app::CommodityTariffAttrsDataMgmt;
53213 using CommodityTariffAttrTypeEnum = chip::app::Clusters::CommodityTariff::CommodityTariffDelegate::CommodityTariffAttrTypeEnum;
@@ -109,8 +269,17 @@ void SetTestEventTrigger_TariffDataUpdated()
109269 if (err != CHIP_NO_ERROR)
110270 return ;
111271
112- instance->ActivateTariffTimeTracking (tariff_preset.TariffTestTimestamp );
113- dg->TariffDataUpdate (tariff_preset.TariffTestTimestamp );
272+ // Enable test time with the preset timestamp
273+ gTestTimeManager .EnableTestTime (true , tariff_preset.TariffTestTimestamp );
274+
275+ if (dg)
276+ {
277+ dg->TariffDataUpdate (tariff_preset.TariffTestTimestamp );
278+ }
279+ else
280+ {
281+ ChipLogError (AppServer, " The tariff provider instance is null" );
282+ }
114283}
115284
116285void SetTestEventTrigger_TariffDataClear ()
@@ -126,13 +295,8 @@ void SetTestEventTrigger_TariffDataClear()
126295 */
127296void SetTestEventTrigger_TimeShift24h ()
128297{
129- CommodityTariffInstance * instance = GetCommodityTariffInstance ();
130-
131- if (instance)
132- {
133- instance->TariffTimeTrackingSetOffset (kSecondsPerDay );
134- instance->TariffTimeAttrsSync ();
135- }
298+ gTestTimeManager .EnableTestTime (true );
299+ gTestTimeManager .AdvanceTestTime (chip::System::Clock::Seconds32 (kSecondsPerDay ));
136300}
137301
138302/*
@@ -141,23 +305,13 @@ void SetTestEventTrigger_TimeShift24h()
141305 */
142306void SetTestEventTrigger_TimeShift4h ()
143307{
144- CommodityTariffInstance * instance = GetCommodityTariffInstance ();
145-
146- if (instance)
147- {
148- instance->TariffTimeTrackingSetOffset (kSecondsPer4hr );
149- instance->TariffTimeAttrsSync ();
150- }
308+ gTestTimeManager .EnableTestTime (true );
309+ gTestTimeManager .AdvanceTestTime (chip::System::Clock::Seconds32 (kSecondsPer4hr ));
151310}
152311
153312void SetTestEventTrigger_TimeShiftDisable ()
154313{
155- CommodityTariffInstance * instance = GetCommodityTariffInstance ();
156-
157- if (instance)
158- {
159- instance->TariffTimeTrackingSetOffset (0 );
160- }
314+ gTestTimeManager .EnableTestTime (false );
161315}
162316
163317bool HandleCommodityTariffTestEventTrigger (uint64_t eventTrigger)
0 commit comments