Showing posts with label HomePod Mini. Show all posts
Showing posts with label HomePod Mini. Show all posts

Wednesday, October 4, 2023

DIY SwitchBot using Matter Over Thread running on Silicon Labs EFR32xG24 Explorer Kit in 5 Minutes.

The following steps guide you to DIY SwitchBot using Matter Over Thread running on Silicon Labs EFR32xG24 Explorer Kit xG24-EK2703A in 5 minutes.

1. Make sure you install Silicon Labs Simplicity Studio v5 and GSDK 4.3.1 with Matter extension 2.1.0-1.1.

2.Connect your xG24-EK2703A kit to your desktop and create "Matter - SoC OnOff Plug over Thread" project as base for your DIY SwitchBot using Matter Over Thread project.

3.Install and add a "sg90" PWM instance in "SOFTWARE COMPONENTS"

4.Configure "sg90" instance to use Timer0 PA00 as PWM output with PWM frequency 50 Hz.

 

5. Replace source code in "void AppTask::ActionCompleted(OnOffPlugManager::Action_t aAction)" with the following codes (red lines), which implements on/off rotating position for SG90 to turn on/off switch.

//YK for SG90 SwitchBot
#include "sl_pwm.h"
#include "sl_pwm_init_sg90_config.h"
#include "sl_sleeptimer.h"

extern sl_pwm_instance_t sl_pwm_sg90;

void AppTask::ActionCompleted(OnOffPlugManager::Action_t aAction)
{
    // action has been completed on the outlet
    if (aAction == OnOffPlugManager::ON_ACTION)
    {
        SILABS_LOG("Outlet ON")
        sl_pwm_set_duty_cycle(&sl_pwm_sg90, 2);
        sl_pwm_start(&sl_pwm_sg90);
        sl_sleeptimer_delay_millisecond(200);
        sl_pwm_set_duty_cycle(&sl_pwm_sg90, 5);
        sl_sleeptimer_delay_millisecond(200);
        sl_pwm_stop(&sl_pwm_sg90);
    }
    else if (aAction == OnOffPlugManager::OFF_ACTION)
    {
        SILABS_LOG("Outlet OFF")
        sl_pwm_set_duty_cycle(&sl_pwm_sg90, 9);
        sl_pwm_start(&sl_pwm_sg90);
        sl_sleeptimer_delay_millisecond(200);
        sl_pwm_set_duty_cycle(&sl_pwm_sg90, 5);
        sl_sleeptimer_delay_millisecond(200);
        sl_pwm_stop(&sl_pwm_sg90);
    }
#ifdef SL_CATALOG_SIMPLE_BUTTON_PRESENT
    if (sAppTask.mSyncClusterToButtonAction)
    {
        chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateClusterState, reinterpret_cast<intptr_t>(nullptr));
        sAppTask.mSyncClusterToButtonAction = false;
    }
#endif
}

6. Add the following two line to set initial SG90 position after "sl_pwm_init(&sl_pwm_sg90, &pwm_sg90_config);" in "void sl_pwm_init_instances(void)".

  //YK for SG90 SwitchBot
  sl_pwm_set_duty_cycle(&sl_pwm_sg90, 5);
  sl_pwm_start(&sl_pwm_sg90);

7. Build and download firmware into xG24-EK2703A kit(remember to dowload bootloader into the kit too)

8. Connect GND, PWR, Signal line of SG90 to GND, 3V3, and PWM pin on xG24-EK2703A kit.

9.Start RTT viewer to get QR code link for Matter Provision.


 

10. Since Apple Home supports Matter Over Thread now, we use Apple HomePod mini (iOS 17) and iPhone Home App to add our DIY SwitchBot into Apple Home.

11. Now, we can mount the DIY SwitchBot to wall switch and use Apple Home to control wall switch/light remotely.



Thursday, April 13, 2023

How to add one extra endpoint for Matter/OpenThread Light.

The following steps show you how to add one extra endpoint for Matter/OpenThread Light with Silicon Labs EFR32MG24 BRD4187C radio board. 

1. Create MatterLightOverThread with Silicon Labs EFR32MG24 BRD4187C radio board first.

2. Start ZAP tool (Zigbee Cluster Configurator) and copy endpoint 1 to create endpoint 2.

3. Enable all required client->server commands for endpoint 2 of on/off and level cluster in ZAP tool.

 

4. Make a copy of LightingManager.h to LightingManager_ep2.h and LightingManager.cpp to LightingManager_ep2.cpp.

5. Add "#include "LightingManager_ep2.h"" and the following items for endpoint 2 in AppTask.h.

    static void ActionInitiated_ep2(LightingManager_ep2::Action_t aAction, int32_t aActor);
    static void ActionCompleted_ep2(LightingManager_ep2::Action_t aAction);
    static void UpdateClusterState_ep2(intptr_t context);

6. Add led2 for endpoint by clicking "Adding New Instances" in Simple LED SOFTWARE COMPONENTS and configure led2 to use PA05 which is pin 7 on EXP header of BRD4001A/BRD4002A mainboard.

7. Add "#define LIGHT_LED_EP2 &sl_led_led2" and "LEDWidget sLightLED_ep2;" for led light of endpoint 2 in AppTask.c.

8. Add implementation of ActionInitiated_ep2, ActionCompleted_ep2, and UpdateClusterState_ep2 in AppTask.c.

void AppTask::ActionInitiated_ep2(LightingManager_ep2::Action_t aAction, int32_t aActor)
{
    // Action initiated, update the light led
    bool lightOn = aAction == LightingManager_ep2::ON_ACTION;
    EFR32_LOG("Turning _ep2 light %s", (lightOn) ? "On" : "Off")

#ifdef ENABLE_WSTK_LEDS
    sLightLED_ep2.Set(lightOn);
#endif // ENABLE_WSTK_LEDS

#ifdef DISPLAY_ENABLED
    sAppTask.GetLCD().WriteDemoUI(lightOn);
#endif
#ifdef SL_CATALOG_SIMPLE_BUTTON_PRESENT
    if (aActor == AppEvent::kEventType_Button)
    {
        sAppTask.mSyncClusterToButtonAction = true;
    }
#endif
}

void AppTask::ActionCompleted_ep2(LightingManager_ep2::Action_t aAction)
{
    // action has been completed bon the light
    if (aAction == LightingManager_ep2::ON_ACTION)
    {
        EFR32_LOG("EP2 Light ON")
    }
    else if (aAction == LightingManager_ep2::OFF_ACTION)
    {
        EFR32_LOG("EP2 Light OFF")
    }
#ifdef SL_CATALOG_SIMPLE_BUTTON_PRESENT
    if (sAppTask.mSyncClusterToButtonAction)
    {
        chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateClusterState_ep2, reinterpret_cast<intptr_t>(nullptr));
        sAppTask.mSyncClusterToButtonAction = false;
    }
#endif
}

void AppTask::UpdateClusterState_ep2(intptr_t context)
{
    uint8_t newValue = LightMgr_ep2().IsLightOn();

    // write the new on/off value
    EmberAfStatus status = OnOffServer::Instance().setOnOffValue(2, newValue, false);

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        EFR32_LOG("ERR: updating ep2 on/off %x", status);
    }

9. Add kEventType_Light_ep2 enum behind kEventType_Light in AppEvent.h and use the following codes to replace original codes in LightActionEventHandler to support endpoint 2 light action.

    void AppTask::LightActionEventHandler(AppEvent * aEvent)
{
    bool initiated = false;
    LightingManager::Action_t action;
    LightingManager_ep2::Action_t action_ep2;
    int32_t actor;
    int32_t actor_ep2;
    CHIP_ERROR err = CHIP_NO_ERROR;

    if (aEvent->Type == AppEvent::kEventType_Light)
    {
        action = static_cast<LightingManager::Action_t>(aEvent->LightEvent.Action);
        actor  = aEvent->LightEvent.Actor;
    }
    else if (aEvent->Type == AppEvent::kEventType_Light_ep2)
      {
          action_ep2 = static_cast<LightingManager_ep2::Action_t>(aEvent->LightEvent.Action);
          actor_ep2  = aEvent->LightEvent.Actor;
      }
#ifdef SL_CATALOG_SIMPLE_BUTTON_PRESENT
    else if (aEvent->Type == AppEvent::kEventType_Button)
    {
        action = (LightMgr().IsLightOn()) ? LightingManager::OFF_ACTION : LightingManager::ON_ACTION;
        actor  = AppEvent::kEventType_Button;
    }
#endif
    else
    {
        err = APP_ERROR_UNHANDLED_EVENT;
    }

    if (err == CHIP_NO_ERROR)
    {
        if (aEvent->Type == AppEvent::kEventType_Light){
          initiated = LightMgr().InitiateAction(actor, action);

          if (!initiated)
          {
              EFR32_LOG("Action is already in progress or active.");
          }
        }
        else if (aEvent->Type == AppEvent::kEventType_Light_ep2)
        {
          initiated = LightMgr_ep2().InitiateAction(actor_ep2, action_ep2);

          if (!initiated)
          {
              EFR32_LOG("_ep2 Action is already in progress or active.");
          }
        }
    }
}

10. Add "#include "LightingManager_ep2.h"" ZclCallbacks.cpp and use the following codes in MatterPostAttributeChangeCallback function.

void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size,
                                       uint8_t * value)
{
    ClusterId clusterId     = attributePath.mClusterId;
    AttributeId attributeId = attributePath.mAttributeId;
    EndpointId endpoint = attributePath.mEndpointId;
    ChipLogProgress(Zcl, "Cluster callback: " ChipLogFormatMEI, ChipLogValueMEI(clusterId));

    if (clusterId == OnOff::Id && attributeId == OnOff::Attributes::OnOff::Id)
    {
        //ChipLogProgress(Zcl, "<---YK---> MatterPostAttributeChangeCallback Endpoint %d on/off value=%d", endpoint, value);
        if(endpoint==1)
          LightMgr().InitiateAction(AppEvent::kEventType_Light, *value ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION);
        else if(endpoint==2)
          LightMgr_ep2().InitiateAction(AppEvent::kEventType_Light_ep2, *value ? LightingManager_ep2::ON_ACTION : LightingManager_ep2::OFF_ACTION);
    }
    else if (clusterId == LevelControl::Id)
    {
        ChipLogProgress(Zcl, "Level Control attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u",
                        ChipLogValueMEI(attributeId), type, *value, size);

        // WIP Apply attribute change to Light
    }
    else if (clusterId == ColorControl::Id)
    {
        ChipLogProgress(Zcl, "Color Control attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u",
                        ChipLogValueMEI(attributeId), type, *value, size);

        // WIP Apply attribute change to Light
    }
    else if (clusterId == OnOffSwitchConfiguration::Id)
    {
        ChipLogProgress(Zcl, "OnOff Switch Configuration attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u",
                        ChipLogValueMEI(attributeId), type, *value, size);

        // WIP Apply attribute change to Light
    }
    else if (clusterId == Identify::Id)
    {
        ChipLogProgress(Zcl, "Identify attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u",
                        ChipLogValueMEI(attributeId), type, *value, size);
    }
}

11. Build and download MatterLightOverThread into BRD4187C

12. Join the MatterLightOverThread device into Matter/Thread network of Apple Home mini with Hoe App and you can see two endpoints in Home App to control them separately.


 

 p.s. for your references, on/off command received flow in Matter source code is like the followings:

InteractionModelEngine::OnMessageReceived
ProcessInvokeRequest
ProcessCommandDataIB
DispatchCommand
DispatchSingleClusterCommand
DispatchServerCommand
emberAfOnOffClusterOffCallback
OnOffServer::Instance().offCommand(commandPath);
OnOffServer::setOnOffValue
Attributes::OnOff::Set
emberAfWriteServerAttribute [#define emberAfWriteServerAttribute emberAfWriteAttribute (af.h)]
emberAfWriteAttribute
emAfWriteAttribute
MatterPostAttributeChangeCallback (ZclCallbacks.cpp)

Friday, October 28, 2022

Build and run Matter and OpenThread lighting-app on EFR32MG24 to work with Apple HomePod Mini and iPhone Home App.

The following steps show you how to build and run Matter and OpenThread lighting-app on EFR32MG24 to work with Apple HomePod Mini and iPhone Home App.

1. Refer to steps 1 and 2 in How to setup and build Matter/CHIP EFR32 Lighting Example on Ubuntu 20.04 to setup Ubuntu 20.04 build environment and git master Matter source codes.

2. Switch to v1.0-branch and workable commit.

    cd connectedhomeip/
    git fetch origin
    git branch -a
    git checkout -b v1.0 remotes/origin/v1.0-branch
    git submodule update --init --recursive
    git checkout 561d23d0db215a99705ff0696e73853c8edf11b2
 

3. Build lighting-app for BRD4186C

    ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32/ ./out/lighting-app BRD4186C

4. Download chip-efr32-lighting-example.hex (can be found under out/lighting-app/BRD4186C) in to BRD4186C+BRD4001A.

5. Make sure your Apple HomePod Mini and iPhone are update to OS 16.1.

6. Start Home App on your iPhone and scan the QR code on LCD of BRD4186C+BRD4001A. Following Home App wizard to complete settings.


7. You can have the Matter enable Light connecting with HomePod Mini and control it with iPhone Home App.

P.S. You can add the following code into AppTask::Init() in AppTask.c to print URL on RTT viewer output to generate QR code on browser.

PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE));

P.S. You can use the following command to build lock-app SED for low power device test.

./scripts/examples/gn_efr32_example.sh ./examples/lock-app/efr32/ ./out/lock-app_SED BRD4186C --sed "chip_detail_logging=false chip_automation_logging=false chip_progress_logging=false is_debug=false show_qr_code=true chip_build_libshell=false disable_lcd=false enable_openthread_cli=false"