Information
We are currently investigating an issue with the editor of some pages. Please save your work and avoid to create new pages until this banner is gone.
In this section we will modify our smart bulb ACS component in order to make it BACI compliant. BACI is a control interface specification we use for ACS at ALMA. For more details this document is available. There is also another useful tutorial here. BACI is only available for C++ components.
From these different sources we can take some guidelines:
When we are defining actions, we must write its arguments and what it returns. Every asynchronous action must have "in ACS::CBvoid cb, in ACS:CBDescIn desc". Note that beside arguments there is also a word "in". Here is short explanation of all possibilities (from Advance CORBA programming with C++):
So, in short:
To make our component a BACI compliant code, we must perform the following modifications:
This is the repository with all the code and external libraries needed: https://bitbucket.sco.alma.cl/users/fcaro/repos/acs-baci-smart-bulb/browse
working_dir: /home/francisco/workspace prefix: ACSIOT module: acsiot component_name: TuyaBulbBaci functions: - 'void turnOn()' - 'void turnOff()' properties: - 'readonly attribute ACS::ROboolean status'
#ifndef _TUYABULBBACI_IDL_ #define _TUYABULBBACI_IDL_ #pragma prefix "ACSIOT" #include <baci.idl> module acsiot { interface TuyaBulbBaci : ACS::CharacteristicComponent { void turnOn(); void turnOff(); readonly attribute ACS::ROboolean status; }; }; #endif
... TuyaBulbBaciImpl_OBJECTS = TuyaBulbBaciImpl hmac_sha256 sha256 TuyaBulbBaciImpl_LIBS = TuyaBulbBaciStubs baci ssl crypto ...
#ifndef _TUYABULBBACI_IMPL_H #define _TUYABULBBACI_IMPL_H #ifndef __cplusplus #error This is a C++ include file and cannot be used from plain C #endif // Base component implementation, including container services and component lifecycle infrastructure #include <baciCharacteristicComponentImpl.h> #include <baciROboolean.h> #include <baciDevIO.h> // Skeleton interface for server implementation #include <TuyaBulbBaciS.h> // Extras #include "httplib.h" #include "hmac_sha256.h" #include "json.hpp" // Error definitions for catching and raising exceptions template <class T> class TuyaBulbBaciDevIO; class TuyaBulbBaciImpl : public virtual baci::CharacteristicComponentImpl, public virtual POA_acsiot::TuyaBulbBaci { // This is for calling private function getStatus from TuyaBulbBaciDevIO object friend TuyaBulbBaciDevIO<bool>; public: TuyaBulbBaciImpl(const ACE_CString& name, maci::ContainerServices* containerServices); virtual ~TuyaBulbBaciImpl(); void turnOn(); void turnOff(); // This is the public function to check the BACI property value virtual ACS::ROboolean_ptr status(); private: const std::string api_region; const std::string client_id; const std::string api_secret; const std::string device_id; const std::string base_url; std::string token; // This is our BACI property baci::ROboolean* m_status_p; httplib::Result sendRequest( const std::string uri, const std::string action = "GET", const std::map<std::string, std::string> headers_map = {}, const std::string headers_str = "", const std::string body = "", const std::string body_sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", const std::string version = "v1.0" ); std::string getToken(); bool getStatus(); }; // DevIO template definition for TuyaBulbBaci template <class T> class TuyaBulbBaciDevIO : public DevIO<T> { public: TuyaBulbBaciDevIO(TuyaBulbBaciImpl* component) : component(component) {}; virtual ~TuyaBulbBaciDevIO() {}; virtual bool initializeValue(){ return false; } virtual T read(ACS::Time& timestamp) { timestamp = ::getTimeStamp(); return component->getStatus(); } virtual void write(const T& value, ACS::Time& timestamp) { // no op, since status is a read only characteristic } protected: TuyaBulbBaciImpl* component; }; #endif
from Acspy.Clients.SimpleClient import PySimpleClient client = PySimpleClient() bulb_comp = client.getComponent("TuyaBulbBaciCPP") status = bulb_comp.status bulb_comp.turnOn() bulb_comp.status() bulb_comp.turnOff() bulb_comp.status()
>>> from Acspy.Clients.SimpleClient import PySimpleClient >>> >>> client = PySimpleClient() >>> bulb_comp = client.getComponent("TuyaBulbBaciCPP") >>> bulb_comp.status.get_sync() (False, ACSErr.Completion(timeStamp=138772104611657330, type=0, code=0, previousError=[])) >>> bulb_comp.turnOn() >>> bulb_comp.status.get_sync() (True, ACSErr.Completion(timeStamp=138772104679161260, type=0, code=0, previousError=[])) >>> bulb_comp.turnOff() >>> bulb_comp.status.get_sync() (False, ACSErr.Completion(timeStamp=138772104807303050, type=0, code=0, previousError=[]))