기기에서 추가로 필요한 모듈이 있다면, functions 밑에 디렉토리를 만들어 함께 포함시킵니다. 예를 들어 기기를 실제로 제어하기위해서 필요한 모듈 같은 것들이 포함될 수 있습니다. 추가한 모듈, 라이브러리의 디렉토리 명은 자유롭게 정의 가능합니다. 모듈을 import 할 때, 상대 경로로 작성합니다.
등록/삭제/제어/상태 함수 작성
등록 / 삭제 함수는 반드시 하나씩 만들어주어야 합니다.
제어 함수는 기기가 할 수 있는 제어 명령 별로 하나씩 존재합니다.
상태 함수가 없을 경우 기기 상태 정보가 바뀌는 것을 알 수 없습니다.
모든 함수는 device_info를 첫번째 인자로 받습니다. device_info에 포함된 정보는 다음과 같습니다.
device_info
json 형태로 정의되어 있습니다.
key
description
deviceId
등록된 기기 ID
deviceType
등록된 기기의 타입
deviceState
기기의 최근 상태 정보
alias
기기를 식별할 수 있는 이름
registeredAt
기기가 등록된 시간
preferences
기기와 연결하기 위해 필요한 정보
profile
기기의 profile (상세 정의는 Profile 참고)
등록 함수 작성
hub에서 서브 기기를 등록할 호출되는 함수입니다
@register 데코레이터 사용합니다
함수명은 자유롭게 정의 가능합니다
파리미터로 device_info 받습니다
@registerdef [함수명](device_info):# 기기 등록 코드 작성# 등록에 필요한 parameter는 "device_info["preferences"]['preference_name' 에 정의한 값]"으로 받아옴py
삭제 함수 작성
hub에서 서브 기기를 삭제할 때 호출되는 함수입니다
@unregister 데코레이터 사용합니다
함수명은 자유롭게 정의 가능합니다
device_info를 파라미터로 받습니다
@unregister
def [함수명](device_info):
# 기기 등록 해제 코드 작성
# 특별히 기기에 해제요청을 보내지 않아도 되면 pass로 비워두어도 됨
제어 함수 작성
hub에서 서브 기기를 제어할 때 호출되는 함수입니다
@control 데코레이터 사용합니다
서브기기가 수행할 수 있는 각 제어 명령 별로 하나의 함수를 작성합니다. 함수 이름은 capability에 정의된 command의 name과 연결됩니다
제어 명령은 device_info 이외에 기본 인자로 component 정보와 capability 정보를 추가로 받습니다
API의 응답 값으로 전달해줄 결과를 return 합니다. 없는 경우는 생략합니다
제어명령에 추가 arguments 가 필요한 경우 2가지 작업이 필요합니다. sync가 안맞으면 정상적으로 실행되지 않습니다
capability에 명시합니다
python 코드에 method parameter 마지막에 추가합니다
@control
def [command_name](device_info, component: str, capability: str [, 추가 parameter가 있다면 작성]):
# 기기 제어 코드 작성
상태 함수 작성
hub에서 서브기기의 상태값을 모니터링 하기위해 호출하는 함수입니다
@state 데코레이터 사용하고, exception과 countdown을 함께 작성해주어야 합니다
함수명은 자유롭게 정의 가능합니다.
파리미터로 device_info 받습니다
@state(exceptions=(Exception, ), countdown=10)def [함수명](device_info):# 기기의 상태값을 지속적으로 받아오는 함수 코드 작성# 상태값 변화를 감지하면 set_attribute를 호출하여 업데이트된 상태값을 알려주어야함
상태값 변화를 감지하면, set_attribute를 호출하여 hub에 상태값이 변했음을 알려줍니다
set_attribute를 호출하지 않으면 상태값 변화가 저장되지 않습니다
set_attribute 호출 방법
기기 id 는 device_info로 부터 받아옵니다.
device_info["device_id"]
규칙에 맞춰 attribute의 key값을 만들어줍니다.
{profile의 components id}{capability의 id}{attribute name}
이때 capability의 id와 attribute name의 첫글자는 대문자로 작성
기기로 부터 받은 상태값을 넘겨줍니다
set_attribute 호출 방법
set_attribute([기기의 id], [attribute key값], [상태값])
Functions Example
webOSTV.py
# webOSTV와 연동되는 코드# TV와 통신을 위해 PyWebOSTV 모듈을 import해서 사용하고 있습니다from devices import get_register, get_unregister, get_control, get_state, set_attributefrom.pywebostv import PyWebOSTVregister =get_register()unregister =get_unregister()control =get_control()state =get_state()@registerdefregister_tv(device_info): ip = device_info["preferences"]["ip"] tv_controller =PyWebOSTV(ip).get_tv_controller() tv_controller.register_tv()@unregisterdefunregister_tv(device_info):pass@controldefpower_on(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_controller =PyWebOSTV(ip).get_tv_controller() tv_controller.power_on()@controldefpower_off(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_controller =PyWebOSTV(ip).get_tv_controller() tv_controller.register_tv() tv_controller.power_off()@controldefset_volume(device_info,component:str,capability:str,volume:int): ip = device_info["preferences"]["ip"] tv_controller =PyWebOSTV(ip).get_tv_controller() tv_controller.register_tv() tv_controller.set_volume(volume)return{"volume": volume}@controldefvolume_up(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_controller =PyWebOSTV(ip).get_tv_controller() tv_controller.register_tv() tv_controller.volume_up()return{}@controldefvolume_down(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_controller =PyWebOSTV(ip).get_tv_controller() tv_controller.register_tv() tv_controller.volume_down()return{}@controldefmute(device_info,component:str,capability:str,mute:bool): ip = device_info["preferences"]["ip"] tv_controller =PyWebOSTV(ip).get_tv_controller() tv_controller.register_tv() tv_controller.mute(mute)return{}@controldefchannel_up(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_controller =PyWebOSTV(ip).get_tv_controller() tv_controller.register_tv() tv_controller.channel_up()return{}@controldefchannel_down(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_controller =PyWebOSTV(ip).get_tv_controller() tv_controller.register_tv() tv_controller.channel_down()return{}@controldefhome(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_remote_controller =PyWebOSTV(ip).get_tv_remote_controller() tv_remote_controller.home()return{}@controldefback(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_remote_controller =PyWebOSTV(ip).get_tv_remote_controller() tv_remote_controller.back()return{}@controldefok(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_remote_controller =PyWebOSTV(ip).get_tv_remote_controller() tv_remote_controller.ok()return{}@controldefleft(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_remote_controller =PyWebOSTV(ip).get_tv_remote_controller() tv_remote_controller.left()return{}@controldefright(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_remote_controller =PyWebOSTV(ip).get_tv_remote_controller() tv_remote_controller.right()return{}@controldefup(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_remote_controller =PyWebOSTV(ip).get_tv_remote_controller() tv_remote_controller.up()return{}@controldefdown(device_info,component:str,capability:str): ip = device_info["preferences"]["ip"] tv_remote_controller =PyWebOSTV(ip).get_tv_remote_controller() tv_remote_controller.down()return{}@controldefcapture(device_info,component:str,capability:str,upload_uri:str): ip = device_info["preferences"]["ip"] tv_controller =PyWebOSTV(ip).get_tv_controller() tv_controller.register_tv() tv_controller.capture(upload_uri)return{}@state(exceptions=(Exception, ), countdown=10)defsubscribe_volume(device_info): ip = device_info["preferences"]["ip"] device_id = device_info["deviceId"]try: tv_controller =PyWebOSTV(ip).get_tv_controller() tv_controller.register_tv()defvolume_callback(response):try:try: volume = response["payload"]["volumeStatus"]["volume"] muted = response["payload"]["volumeStatus"]["muteStatus"]exceptKeyError: volume = response["payload"]["volume"] muted = response["payload"]["muted"]set_attribute(device_id, "online", True)set_attribute(device_id, "mainWebOSTVVolume", volume)set_attribute(device_id, "mainWebOSTVMuted", muted)except:pass tv_controller.subscribe_volume(volume_callback)exceptExceptionas e:set_attribute(device_id, "online", False)raise e@state(exceptions=(Exception, ), countdown=10)defsubscribe_channel(device_info): ip = device_info["preferences"]["ip"] device_id = device_info["deviceId"]try: tv_controller =PyWebOSTV(ip).get_tv_controller() tv_controller.register_tv()defprogram_info_callback(response):try: program_name = response["payload"]["programName"] channel_name = response["payload"]["channelName"] channel_number = response["payload"]["channelNumber"]set_attribute(device_id, "online", True)set_attribute(device_id, "mainWebOSTVProgramName", program_name)set_attribute(device_id, "mainWebOSTVChannelName", channel_name)set_attribute(device_id, "mainWebOSTVChannelNumber", channel_number)except:pass tv_controller.subscribe_program_info(program_info_callback)exceptExceptionas e:set_attribute(device_id, "online", False)raise e