You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 8 Next »

To control a smart bulb using ACS we will implement a python component using the Component Generator tool.

Install dependencies

python -m pip install tinytuya

Create component's YML template

The component generation tool uses a template in YML to create the component's IDL and implementation.

tuya_bulb.yml
working_dir: ~/workspace
prefix: ACSIOT
module: acsiot
component_name: TuyaBulb
functions:
  - 'void turnOn(in string api_region, in string api_key, in string api_secret, in string device_id)'
  - 'void turnOff(in string api_region, in string api_key, in string api_secret, in string device_id)'

The "working_dir" is where the component's IDL and implementation directories will be created, the rest is kind of self explanatory (tongue).

Generate component's IDL and boilerplate code

In short, the component generator tool works as follows:

> python create_acs_component.py --help
Usage: create_acs_component.py [OPTIONS] COMPONENT_YAML_PATH

  Creates an ACS component from a YAML definition.

Options:
  -l, --language [python|cpp|java]
                                  Component's implementation language.
                                  [default: python]
  --version                       Show the version and exit.
  --help                          Show this message and exit.

So in our case we will run:

> python create_acs_component.py -l python path/to/tuya_bulb.yml

If everything is ok the generator will create the component's IDL and implementation directories and files. Also it will add the component to the CDB. The output will be something like:

component generator example output
2022-05-16 19:09:15 acs __main__[1225] INFO Loading component's YAML definition.
2022-05-16 19:09:15 acs __main__[1225] DEBUG Component's definition: {'working_dir': '/home/developer/workspace', 'prefix': 'ACSIOT', 'module': 'acsiot', 'component_name': 'TuyaBulb', 'functions': ['void turnOn(string api_region, string api_key, string api_secret, string device_id)', 'void turnOff(string api_region, string api_key, string api_secret, string device_id)']}
2022-05-16 19:09:15 acs __main__[1225] INFO Creating IDL's directories
\nCreating/checking Module directory
   CREATED >>> |---idlTuyaBulb 
   CREATED >>>     |---bin 
   CREATED >>>     |---include 
   CREATED >>>     |---idl 
   CREATED >>>     |---lib 
   CREATED >>>     |---lib/endorsed 
   CREATED >>>     |---lib/python 
   CREATED >>>     |---lib/ACScomponents 
   CREATED >>>     |---lib/python/site-packages 
   CREATED >>>     |---man 
   CREATED >>>     |---man/man1 
   CREATED >>>     |---man/man2 
   CREATED >>>     |---man/man3 
   CREATED >>>     |---man/man4 
   CREATED >>>     |---man/man5 
   CREATED >>>     |---man/man6 
   CREATED >>>     |---man/man7 
   CREATED >>>     |---man/man8 
   CREATED >>>     |---man/mann 
   CREATED >>>     |---man/manl 
   CREATED >>>     |---doc 
   CREATED >>>     |---object 
   CREATED >>>     |---LOGS 
   CREATED >>>     |---test 
   CREATED >>>     |---src 
   CREATED >>>     |---rtai 
   CREATED >>>     |---config 
   CREATED >>>     |---config/CDB 
   CREATED >>>     |---config/CDB/schemas 
   CREATED >>>     |---ChangeLog
\nCopying Makefile template for WS code
2022-05-16 19:09:15 acs __main__[1225] INFO Creating IDL's content
2022-05-16 19:09:15 acs __main__[1225] DEBUG IDL's content: #ifndef _TUYABULB_IDL_
#define _TUYABULB_IDL_
 
#pragma prefix "ACSIOT"
 
#include <acscomponent.idl>
 
module acsiot {
    interface TuyaBulb : ACS::ACSComponent {
        void turnOn(string api_region, string api_key, string api_secret, string device_id);

        void turnOff(string api_region, string api_key, string api_secret, string device_id);
    };
};

#endif

2022-05-16 19:09:15 acs __main__[1225] INFO Editing Makefile
2022-05-16 19:09:15 acs __main__[1225] INFO Adding component to CDB
2022-05-16 19:09:15 acs __main__[1225] DEBUG CDB's content: <?xml version="1.0" encoding="ISO-8859-1"?>
<Components  xmlns="urn:schemas-cosylab-com:Components:1.0"
       xmlns:cdb="urn:schemas-cosylab-com:CDB:1.0" 
       xmlns:baci="urn:schemas-cosylab-com:BACI:1.0" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <e Name="PBEND_B_01"   Code="acsexmplPowerSupplyImpl"
                             Type="IDL:alma/PS/PowerSupply:1.0"
                             Container="bilboContainer" ImplLang="cpp" />
      ...
	  ...
	  ...
      <e Name="TuyaBulbPython" 	
         Code="acsiotImpl.TuyaBulbImpl" 
         Type="IDL:ACSIOT/acsiot/TuyaBulb:1.0"
         Container="aragornContainer" ImplLang="py" />
</Components>

2022-05-16 19:09:15 acs create_python_component[1225] INFO Creating component's directories.
\nCreating/checking Module directory
               |---pyTuyaBulb 
                   |---bin 
                   |---include 
                   |---idl 
                   |---lib 
                   |---lib/endorsed 
                   |---lib/python 
                   |---lib/ACScomponents 
                   |---lib/python/site-packages 
                   |---man 
                   |---man/man1 
                   |---man/man2 
                   |---man/man3 
                   |---man/man4 
                   |---man/man5 
                   |---man/man6 
                   |---man/man7 
                   |---man/man8 
                   |---man/mann 
                   |---man/manl 
                   |---doc 
                   |---object 
                   |---LOGS 
                   |---test 
                   |---src 
                   |---rtai 
                   |---config 
                   |---config/CDB 
                   |---config/CDB/schemas 
                   |---ChangeLog
\nCopying Makefile template for WS code
2022-05-16 19:09:15 acs create_python_component[1225] INFO Creating component's content.
2022-05-16 19:09:15 acs create_python_component[1225] DEBUG Component's content: # Client stubs and definitions, such as structs, enums, etc.
import acsiot
# Skeleton infrastructure for server implementation
import acsiot__POA
   
# Base component implementation
from Acspy.Servants.ACSComponent import ACSComponent
# Services provided by the container to the component
from Acspy.Servants.ContainerServices import ContainerServices
# Basic component lifecycle (initialize, execute, cleanUp and aboutToAbort methods)
from Acspy.Servants.ComponentLifecycle import ComponentLifecycle


class TuyaBulbImpl(acsiot__POA.TuyaBulb, ACSComponent, ContainerServices, ComponentLifecycle):
    def __init__(self):
        ACSComponent.__init__(self)
        ContainerServices.__init__(self)
        self._logger = self.getLogger()
        
    def turnOn(self, api_region, api_key, api_secret, device_id):
        raise NotImplementedError("This function should do something")

    def turnOff(self, api_region, api_key, api_secret, device_id):
        raise NotImplementedError("This function should do something")

2022-05-16 19:09:15 acs create_python_component[1225] INFO Editing Makefile

Implement component

In order to have a working component in valid python we will have to modify the boilerplate code as follows:

pyTuyaBulb/src/acsiotImpl/TuyaBulbImpl.py
# Client stubs and definitions, such as structs, enums, etc.
import acsiot
# Skeleton infrastructure for server implementation
import acsiot__POA
   
# Base component implementation
from Acspy.Servants.ACSComponent import ACSComponent
# Services provided by the container to the component
from Acspy.Servants.ContainerServices import ContainerServices
# Basic component lifecycle (initialize, execute, cleanUp and aboutToAbort methods)
from Acspy.Servants.ComponentLifecycle import ComponentLifecycle

import tinytuya
tinytuya.set_debug(True)


class TuyaBulbImpl(acsiot__POA.TuyaBulb, ACSComponent, ContainerServices, ComponentLifecycle):
    def __init__(self):
        ACSComponent.__init__(self)
        ContainerServices.__init__(self)
        self._logger = self.getLogger()
        
    def turnOn(self, api_region, api_key, api_secret, device_id):
        # raise NotImplementedError("This function should do something")
        client = tinytuya.Cloud(
            apiRegion=api_region,
            apiKey=api_key,
            apiSecret=api_secret
        )

        commands = {
            'commands': [{
                'code': 'switch_led',
                'value': True
            }]
        }
        print("Sending command...")
        result = client.sendcommand(device_id, commands)
        print("Results\n:", result)

    def turnOff(self, api_region, api_key, api_secret, device_id):
        # raise NotImplementedError("This function should do something")
        client = tinytuya.Cloud(
            apiRegion=api_region,
            apiKey=api_key,
            apiSecret=api_secret
        )

        commands = {
            'commands': [{
                'code': 'switch_led',
                'value': False
            }]
        }
        print("Sending command...")
        result = client.sendcommand(device_id, commands)
        print("Results\n:", result)

Build and install IDL

cd idlTuyaBulb/src
make all
make install

Build and install component

cd pyTuyaBulb/src
make all install

Run component

  1. In one terminal run:

    acsStop
    acsStart
  2. In a second terminal run:

    acsStartContainer -py aragornContainer
  3. And in a third terminal run:

    from Acspy.Clients.SimpleClient import PySimpleClient
      
    
    api_region = 'my_region'
    api_key = 'my_api_key'
    api_secret = 'my_api_secret'
    device_id = 'my_device_id'
    
    client = PySimpleClient()
    
    bulb = client.getComponent("TuyaBulbPython")
    bulb.turnOn(api_region, api_key, api_secret, device_id)
    bulb.turnOff(api_region, api_key, api_secret, device_id)
  4. If everything is ok you should have witnessed how the smart bulb lit on and off using ACS.
  • No labels