-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Tizen] [lighting-app] Add GPIO control and dbus UI (#29958)
* Add simple gpio implementation * dbus - add xml and integrate in gn * Integrate dbus controller into app * Use property instead of method call * Use gdbus_library GN template for generating iface * Expose Matter clusters via Tizen App D-Bus * Update for color cluster * Fix color temperature set * Expose Identify cluster via example app D-Bus API * Alight D-Bus API property names with Matter * Add led manager * Add license * clean unused callback * Preserve the state of the color temperature * Set color temperature mode as default * Remove unused static variable * Update signals name * Add else to define to remove warning * Remove unused value * Add [-with-ui] to tinze in all_targets_linux_x64.txt * Verify by CI that -with-ui works * Restyled by gn --------- Co-authored-by: Arkadiusz Bokowy <[email protected]> Co-authored-by: Restyled.io <[email protected]>
- Loading branch information
Showing
14 changed files
with
572 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* | ||
* 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. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <lib/core/CHIPError.h> | ||
#include <lib/core/DataModelTypes.h> | ||
|
||
#include <peripheral_io.h> | ||
|
||
namespace example { | ||
class LedManager | ||
{ | ||
public: | ||
explicit LedManager(chip::EndpointId endpointId); | ||
void SetOnOff(bool on); | ||
CHIP_ERROR Init(); | ||
|
||
private: | ||
void InitOnOff(); | ||
|
||
// Numbers of GPIO used to control LED in order: RED, GREEN, BLUE | ||
static constexpr int number_of_pins = 3; | ||
static constexpr int pins[number_of_pins] = { 20, 19, 18 }; | ||
peripheral_gpio_h gpio[number_of_pins] = {}; | ||
|
||
const chip::EndpointId mEndpointId; | ||
}; | ||
|
||
} // namespace example |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
/* | ||
* | ||
* 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 "DBusInterface.h" | ||
|
||
#include <app-common/zap-generated/attributes/Accessors.h> | ||
#include <app-common/zap-generated/cluster-enums.h> | ||
#include <app-common/zap-generated/ids/Attributes.h> | ||
#include <app-common/zap-generated/ids/Clusters.h> | ||
#include <app/ConcreteAttributePath.h> | ||
#include <app/clusters/color-control-server/color-control-server.h> | ||
#include <app/clusters/level-control/level-control.h> | ||
#include <app/clusters/on-off-server/on-off-server.h> | ||
#include <lib/support/logging/CHIPLogging.h> | ||
#include <platform/CHIPDeviceLayer.h> | ||
|
||
#include "dbus/DBusLightApp.h" | ||
|
||
using namespace chip; | ||
using namespace chip::app; | ||
|
||
namespace example { | ||
|
||
// Dummy class to satisfy the CommandHandler::Callback interface. | ||
class CommandHandlerCallback : public CommandHandler::Callback | ||
{ | ||
public: | ||
using Status = Protocols::InteractionModel::Status; | ||
void OnDone(CommandHandler & apCommandObj) {} | ||
void DispatchCommand(CommandHandler & apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & apPayload) {} | ||
Status CommandExists(const ConcreteCommandPath & aCommandPath) { return Status::Success; } | ||
}; | ||
|
||
DBusInterface::DBusInterface(chip::EndpointId endpointId) : mEndpointId(endpointId) | ||
{ | ||
mManager = g_dbus_object_manager_server_new("/"); | ||
mIfaceIdentify = light_app_identify_skeleton_new(); | ||
mIfaceOnOff = light_app_on_off_skeleton_new(); | ||
mIfaceLevelControl = light_app_level_control_skeleton_new(); | ||
mIfaceColorControl = light_app_color_control_skeleton_new(); | ||
} | ||
|
||
DBusInterface::~DBusInterface() | ||
{ | ||
g_object_unref(mIfaceIdentify); | ||
g_object_unref(mIfaceOnOff); | ||
g_object_unref(mIfaceLevelControl); | ||
g_object_unref(mIfaceColorControl); | ||
g_object_unref(mManager); | ||
} | ||
|
||
CHIP_ERROR DBusInterface::Init() | ||
{ | ||
// During the initialization we are going to connect glib signals, so we need to be | ||
// on the GLib Matter context. Otherwise, signals will be emitted on the glib default | ||
// main context. | ||
return chip::DeviceLayer::PlatformMgrImpl().GLibMatterContextInvokeSync(InitOnGLibMatterContext, this); | ||
} | ||
|
||
void DBusInterface::Identify(uint16_t time) | ||
{ | ||
light_app_identify_emit_identify(mIfaceIdentify, time); | ||
} | ||
|
||
void DBusInterface::SetOnOff(bool on) | ||
{ | ||
InternalSetGuard guard(this); | ||
if (light_app_on_off_get_on_off(mIfaceOnOff) != on) | ||
light_app_on_off_set_on_off(mIfaceOnOff, on); | ||
} | ||
|
||
void DBusInterface::SetCurrentLevel(uint8_t value) | ||
{ | ||
InternalSetGuard guard(this); | ||
if (light_app_level_control_get_current_level(mIfaceLevelControl) != value) | ||
light_app_level_control_set_current_level(mIfaceLevelControl, value); | ||
} | ||
|
||
void DBusInterface::SetColorMode(chip::app::Clusters::ColorControl::ColorMode colorMode) | ||
{ | ||
InternalSetGuard guard(this); | ||
if (light_app_color_control_get_color_mode(mIfaceColorControl) != colorMode) | ||
light_app_color_control_set_color_mode(mIfaceColorControl, colorMode); | ||
} | ||
|
||
void DBusInterface::SetColorTemperature(uint16_t value) | ||
{ | ||
InternalSetGuard guard(this); | ||
if (light_app_color_control_get_color_temperature_mireds(mIfaceColorControl) != value) | ||
light_app_color_control_set_color_temperature_mireds(mIfaceColorControl, value); | ||
} | ||
|
||
CHIP_ERROR DBusInterface::InitOnGLibMatterContext(DBusInterface * self) | ||
{ | ||
g_autoptr(GDBusConnection) bus = nullptr; | ||
g_autoptr(GError) error = nullptr; | ||
|
||
if ((bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error)) == nullptr) | ||
{ | ||
ChipLogError(NotSpecified, "Couldn't get D-Bus bus: %s", error->message); | ||
return CHIP_ERROR_NOT_CONNECTED; | ||
} | ||
|
||
LightAppObjectSkeleton * object = light_app_object_skeleton_new("/app"); | ||
g_dbus_object_manager_server_export(self->mManager, G_DBUS_OBJECT_SKELETON(object)); | ||
|
||
light_app_object_skeleton_set_identify(object, self->mIfaceIdentify); | ||
light_app_object_skeleton_set_on_off(object, self->mIfaceOnOff); | ||
light_app_object_skeleton_set_level_control(object, self->mIfaceLevelControl); | ||
light_app_object_skeleton_set_color_control(object, self->mIfaceColorControl); | ||
|
||
self->InitOnOff(); | ||
self->InitColor(); | ||
|
||
g_dbus_object_manager_server_set_connection(self->mManager, bus); | ||
g_object_unref(object); | ||
|
||
g_signal_connect(self->mIfaceOnOff, "notify::on-off", G_CALLBACK(OnOnOffChanged), self); | ||
g_signal_connect(self->mIfaceLevelControl, "notify::current-level", G_CALLBACK(OnCurrentLevelChanged), self); | ||
g_signal_connect(self->mIfaceColorControl, "notify::color-temperature-mireds", G_CALLBACK(OnColorTemperatureChanged), self); | ||
|
||
g_bus_own_name_on_connection(bus, "org.tizen.matter.example.lighting", G_BUS_NAME_OWNER_FLAGS_NONE, | ||
reinterpret_cast<GBusAcquiredCallback>(OnBusAcquired), | ||
reinterpret_cast<GBusNameLostCallback>(OnBusLost), self, nullptr); | ||
|
||
return CHIP_NO_ERROR; | ||
} | ||
|
||
void DBusInterface::OnBusAcquired(GDBusConnection *, const char *, DBusInterface * self) | ||
{ | ||
self->mNameAcquired = true; | ||
} | ||
|
||
void DBusInterface::OnBusLost(GDBusConnection *, const char * name, DBusInterface * self) | ||
{ | ||
VerifyOrReturn(self->mNameAcquired, /* connection was lost after name was acquired, so it's not an error */); | ||
ChipLogError(NotSpecified, "Couldn't acquire D-Bus name. Please check D-Bus configuration. Requested name: %s", name); | ||
} | ||
|
||
gboolean DBusInterface::OnOnOffChanged(LightAppOnOff * onOff, GDBusMethodInvocation * invocation, DBusInterface * self) | ||
{ | ||
// Do not handle on-change event if it was triggered by internal set | ||
VerifyOrReturnValue(!self->mInternalSet, G_DBUS_METHOD_INVOCATION_HANDLED); | ||
|
||
chip::DeviceLayer::StackLock lock; | ||
OnOffServer::Instance().setOnOffValue(self->mEndpointId, | ||
light_app_on_off_get_on_off(onOff) ? Clusters::OnOff::Commands::On::Id | ||
: Clusters::OnOff::Commands::Off::Id, | ||
false /* initiatedByLevelChange */); | ||
return G_DBUS_METHOD_INVOCATION_HANDLED; | ||
} | ||
|
||
gboolean DBusInterface::OnCurrentLevelChanged(LightAppLevelControl * levelControl, GDBusMethodInvocation * invocation, | ||
DBusInterface * self) | ||
{ | ||
// Do not handle on-change event if it was triggered by internal set | ||
VerifyOrReturnValue(!self->mInternalSet, G_DBUS_METHOD_INVOCATION_HANDLED); | ||
|
||
Clusters::LevelControl::Commands::MoveToLevel::DecodableType data; | ||
data.level = light_app_level_control_get_current_level(levelControl); | ||
data.optionsMask.Set(Clusters::LevelControl::LevelControlOptions::kExecuteIfOff); | ||
data.optionsOverride.Set(Clusters::LevelControl::LevelControlOptions::kExecuteIfOff); | ||
|
||
chip::DeviceLayer::StackLock lock; | ||
LevelControlServer::MoveToLevel(self->mEndpointId, data); | ||
|
||
return G_DBUS_METHOD_INVOCATION_HANDLED; | ||
} | ||
|
||
gboolean DBusInterface::OnColorTemperatureChanged(LightAppColorControl * colorControl, GDBusMethodInvocation * invocation, | ||
DBusInterface * self) | ||
{ | ||
// Do not handle on-change event if it was triggered by internal set | ||
VerifyOrReturnValue(!self->mInternalSet, G_DBUS_METHOD_INVOCATION_HANDLED); | ||
|
||
CommandHandlerCallback callback; | ||
CommandHandler handler(&callback); | ||
|
||
ConcreteCommandPath path{ self->mEndpointId, Clusters::ColorControl::Id, 0 }; | ||
|
||
Clusters::ColorControl::Commands::MoveToColorTemperature::DecodableType data; | ||
data.colorTemperatureMireds = light_app_color_control_get_color_temperature_mireds(colorControl); | ||
|
||
chip::DeviceLayer::StackLock lock; | ||
ColorControlServer::Instance().moveToColorTempCommand(&handler, path, data); | ||
|
||
return G_DBUS_METHOD_INVOCATION_HANDLED; | ||
} | ||
|
||
void DBusInterface::InitOnOff() | ||
{ | ||
bool isOn = false; | ||
auto status = Clusters::OnOff::Attributes::OnOff::Get(mEndpointId, &isOn); | ||
VerifyOrReturn(status == EMBER_ZCL_STATUS_SUCCESS, ChipLogError(NotSpecified, "Error getting OnOff: 0x%x", status)); | ||
light_app_on_off_set_on_off(mIfaceOnOff, isOn); | ||
} | ||
|
||
void DBusInterface::InitColor() | ||
{ | ||
{ | ||
uint8_t value = 0; | ||
auto status = Clusters::ColorControl::Attributes::ColorMode::Get(mEndpointId, &value); | ||
VerifyOrReturn(status == EMBER_ZCL_STATUS_SUCCESS, ChipLogError(NotSpecified, "Error getting ColorMode: 0x%x", status)); | ||
light_app_color_control_set_color_mode(mIfaceColorControl, value); | ||
} | ||
{ | ||
uint16_t value = 0; | ||
auto status = Clusters::ColorControl::Attributes::ColorTemperatureMireds::Get(mEndpointId, &value); | ||
VerifyOrReturn(status == EMBER_ZCL_STATUS_SUCCESS, | ||
ChipLogError(NotSpecified, "Error getting ColorTemperatureMireds: 0x%x", status)); | ||
light_app_color_control_set_color_temperature_mireds(mIfaceColorControl, value); | ||
} | ||
} | ||
|
||
}; // namespace example |
Oops, something went wrong.