2021년 9월 21일 화요일

개방형 빌딩 관리 제어 자동화 플랫폼 VOLTTRON 기술 소개

 VOLTTRON™은 미국 에너지 부(DOE)에서 개발한 건물 거주 관리, 에너지 소스, 전력망 관리 자동화, 통합을 위한 오픈소스기반  분산 제어 및 감지 플랫폼이다. VOLTTRON은 장치, 플랫폼 에이전트, 클라우드 에이전트 및 전력망의 신호를 연결한다. 이 플랫폼은 수요 대응 및 분산 재생 가능 에너지 소스 통합과 같은 사용 사례를 지원한다. 


볼트론 플랫폼 기반 캠퍼스 시설물 관리 어플리케이션(VOLTRON DASHBOARD)

개념
VOLTTRON은 에이전트 실행을 위한 환경을 제공하며 장치(빌딩 시스템, 계량기 등), 외부 리소스 및 데이터 보관, 검색과 같은 플랫폼 서비스와의 인터페이스 역할을 한다. IoT 프로토콜, BACNET, BAS, MODBUS 등 개방형 통신 국제 표준을 지원해 상호운용성, 연결성을 지원한다. VOLTTRON은 애플리케이션 개발을 용이하게 하고 빌딩 엔지니어와 같은 도메인 전문가가 작성해야 하는 코드 라인을 최소화한다. 이를 위해 에이전트 기반 프로그래밍 패러다임을 제공하기 때문에 VOLTTRON 애플리케이션을 에이전트라고 한다. VOLTTRON은 에이전트 개발을 단순화하는 유틸리티 및 헬퍼 클래스 모음을 제공한다.

볼트론 시스템 구조도

미국 에너지 부(DOE)의 BTO(Building Technologies Office) 자금을 지원하는 Pacific Northwest National Laboratory(PNNL)는 건물 및 그리드 통합을 지원하기 위한 트랜잭션 네트워크 플랫폼으로 VOLTTRON을 개발 유지 관리한다. 
볼트론 개발자(History)

VOLTTRON 소스 코드에는 에이전트 실행 소프트웨어가 포함된다. VOLTTRON 기능을 활성화하고 향상시키는 중요한 서비스를 수행하는 에이전트 기능(오류 감지, 요구 응답 등)을 수행하기 위해 플랫폼을 활용하는 수많은 에이전트가 있다. 이 플랫폼은 네트워크로 연결된 엔티티(장비, 조직, 건물, 그리드 등)간의 에너지, 운영 및 금융 트랜잭션을 지원하고 오픈 소스 장치 통신, 제어 프로토콜 및 통합 분석을 사용하여 기존 건물의 제어 인프라를 향상시킬 수 있다. 
아키텍처(Conceptual Architecture of Building Energy
Management Open Source Software (BEMOSS))

오픈 플랫폼 개발과 성장을 장려하기 위해 모든 VOLTTRON 소프트웨어, 플랫폼 서비스 및 에이전트는 오픈소스이며 BSD(Berkeley Software Distribution) 스타일 라이선스를 사용하여 소프트웨어의 무료 배포 및 개발을 허용한다. 아울러, 개방 표준을 기반으로 하므로, 메일, 트위터와 같은 서비스와 연결성, 상호운용성이 쉽게 지원된다. 
이 라이선스는 오픈 소스 코드 위에 독점 솔루션을 개발하는 조직을 지원한다. 별도로 라이선스가 부여된(PNNL에 의해) 플랫폼 플러그인은 대규모 배포를 위해 플랫폼에 추가 기능을 제공한다. 이 플러그인을 사용하면 행위자가 코드가 유용하고 신뢰할 수 있으며 유익하다는 에이전트 패키지에 서명할 수 있다. 

에이전트 이동성 서비스를 사용하면 에이전트가 플랫폼간에 이동할 수 있습니다. 모든 VOLTTRON 구성 요소는 다양한 주제에 대해 게시/구독 패턴 디자인을 사용한 기술로 통신한다. 예를 들어 날씨 에이전트는 관심있는 에이전트가 구독할 "날씨"토픽에 날씨 정보를 게시할 수 있다(*주. ROS와 유사한 방식).
유스케이스

볼트론은 유스케이스 개발을 위한 개발도구, 예제, 문서를 매우 상세하게 제공하고 있으며, 오픈소스 기반 하드웨어를 제공해, 편리하게 빌딩 통제 및 제어를 구현해 볼 수 있다. 

이런 볼트론의 개방성은 많은 스포서와 커뮤니티를 만들고 있다. 
볼트론 커뮤니티

설치
미리 우분투 등 리눅스 개발환경이 마련되어 있다는 가정하에, 설치하는 방법은 다음과 같다.
sudo apt-get update
sudo apt-get install build-essential python-dev openssl libssl-dev libevent-dev git
git clone https://github.com/VOLTTRON/volttron
cd volttron
python bootstrap.py

볼트론 플랫폼 활성화를 한다.
. env/bin/activate
volttron -vv -l volttron.log&

메시지 버스 생성을 한다.
scripts/core/make-listener

로그를 확인한다. 
tail volttron.log

로그 결과는 다음과 유사하게 출력될 것이다.
2016-10-17 18:17:52,245 (listeneragent-3.2 11367) listener.agent INFO: Peer: 'pubsub', Sender: 'listeneragent-3.2_1'
:, Bus: u'', Topic: 'heartbeat/ListenerAgent/f230df97-658e-45d3-8165-18a2ec834d3f', Headers:
{'Date': '2016-10-18T01:17:52.239724+00:00', 'max_compatible_version': u'', 'min_compatible_version': '3.0'},
Message: {'status': 'GOOD', 'last_updated': '2016-10-18T01:17:47.232972+00:00', 'context': 'hello'}

빌딩 관리 제어 에이전트 개발을 위해 다음을 실행한다.
vpkg init TestAgent tester

Agent version number: [0.1]: 0.5
Agent author: []: VOLTTRON Team
Author's email address: []: volttron@pnnl.gov
Agent homepage: []: https://volttron.org/
Short description of the agent: []: Agent development tutorial.

결과 다음과 같은 폴더 및 파일이 생성된다.
TestAgent/
├── setup.py
├── config
└── tester
    ├── agent.py
    └── __init__.py

메인코드 tester와 agent.py는 다음과 같다. 목적에 맞게 코딩한다.
def tester(config_path, **kwargs):
    """Parses the Agent configuration and returns an instance of
    the agent created using that configuration.

    :param config_path: Path to a configuration file.

    :type config_path: str
    :returns: Tester
    :rtype: Tester
    """
    try:
        config = utils.load_config(config_path)
    except StandardError:
        config = {}

    if not config:
        _log.info("Using Agent defaults for starting configuration.")

    setting1 = int(config.get('setting1', 1))
    setting2 = config.get('setting2', "some/random/topic")

    return Tester(setting1,
                  setting2,
                  **kwargs)

class Tester(Agent):
    """
    Document agent constructor here.
    """

    def __init__(self, setting1=1, setting2="some/random/topic",
                 **kwargs):
        super(Tester, self).__init__(**kwargs)
        _log.debug("vip_identity: " + self.core.identity)

        self.setting1 = setting1
        self.setting2 = setting2

        self.default_config = {"setting1": setting1,
                               "setting2": setting2}


        #Set a default configuration to ensure that self.configure is called immediately to setup
        #the agent.
        self.vip.config.set_default("config", self.default_config)
        #Hook self.configure up to changes to the configuration file "config".
        self.vip.config.subscribe(self.configure, actions=["NEW", "UPDATE"], pattern="config")

    def configure(self, config_name, action, contents):
        """
        Called after the Agent has connected to the message bus. If a configuration exists at startup
        this will be called before onstart.

        Is called every time the configuration in the store changes.
        """
        config = self.default_config.copy()
        config.update(contents)

        _log.debug("Configuring Agent")

        try:
            setting1 = int(config["setting1"])
            setting2 = str(config["setting2"])
        except ValueError as e:
            _log.error("ERROR PROCESSING CONFIGURATION: {}".format(e))
            return

        self.setting1 = setting1
        self.setting2 = setting2

        self._create_subscriptions(self.setting2)

주제 구독 및 발행은 다음과 같이 처리한다. 구독 발행 패턴이라 각 에이전트가 관제, 통신, 제어하고 싶은 내용을 코딩한다.
def _create_subscriptions(self, topic):
    #Unsubscribe from everything.
    self.vip.pubsub.unsubscribe("pubsub", None, None)

    self.vip.pubsub.subscribe(peer='pubsub',
                              prefix=topic,
                              callback=self._handle_publish)

def _handle_publish(self, peer, sender, bus, topic, headers,
                            message):
    #By default no action is taken.
    pass

에이전트 패키징은 다음처럼 설정한다.
from setuptools import setup, find_packages

MAIN_MODULE = 'agent'

# Find the agent package that contains the main module
packages = find_packages('.')
agent_package = 'tester'

# Find the version number from the main module
agent_module = agent_package + '.' + MAIN_MODULE
_temp = __import__(agent_module, globals(), locals(), ['__version__'], -1)
__version__ = _temp.__version__

# Setup
setup(
    name=agent_package + 'agent',
    version=__version__,
    author_email="volttron@pnnl.gov",
    url="https://volttron.org/",
    description="Agent development tutorial.",
    author="VOLTTRON Team",
    install_requires=['volttron'],
    packages=packages,
    entry_points={
        'setuptools.installation': [
            'eggsecutable = ' + agent_module + ':main',
        ]
    }
)

에이전트 실행은 다음과 같다. 
./start-volttron
python scripts/install-agent.py -s TestAgent/ -c TestAgent/config -t testagent

테스트는 다음과 같다.
vctl start --name testeragent-0.1

마무리
이 글은 빌딩 관리 자동화 개방형 플랫폼인 볼트론에 대한 소개를 간략히 다루었다. IoT, 빅데이터 처리와 같이 부상하는 기술을 적절히 녹여 넣고, 아키텍처 디자인은 실용성있는 표준, 상호운용성, 확장성을 충분히 고려했다. 기술을 살펴보면 느끼겠지만, 개방형 플랫폼이 어떤 기술인지 명확히 기술개발을 해본 전문가들이 모여 만든 것임을 알 수 있다. 


전문가로써 깊이있는 연구진 구성, 장기적이고 지속적이고 충분한 지원, 자율적이고 합리적인 연구 문화와 환경이 이런 기술을 가능하게 했다. 매번 바뀌는 연구 거버넌스, 관주도 트랜드 기반 대형 연구단에서는 이런 결과물은 거의 불가능할 것이라 생각한다. 언제부터인가 사업관리로만 전락한 연구과제들, 정치화된 조직으로 인해 파편화된 연구, 핵심기술 못보고 홍보만 보는 전문성없는 연구과제평가 시스템, 전문성 리더쉽 구체적 기술경험 없이 공허한 말만하는 책임자, 겉보기 덩치만 크고 핵심연구자는 없는 연구진, 실속있는 핵심 기술 개발 없는 아웃소싱 연구들, 불필요한 행정일에 질려버린 연구자, 연구비는 풍족하지만 열악한 연구제도환경과 이해관계들로 인해 적당히 타협된 연구... 국내에서 정말 쉽지 않은 것인지 이런 사례를 볼때마다 아쉬움이 있는 것은 어쩔 수 없다. 거버넌스는 10년 전이나 지금이나 바뀐것이 별로 없어 보인다.

레퍼런스
VOLTTRON DOCUMENT 7.0(2020.8)
ENERGY.GOV

댓글 없음:

댓글 쓰기

생성 AI 건설 기술 트랜드

이 글은 생성 AI 건설 기술 트랜드를 간략히 정리한다. 레퍼런스 AI is hard (to do well) - AEC Magazine AI Copilot for architects launches in beta - AEC Magazine How to...