Flask REST API 서버와 PLC 및 Redis 통합 (1)

초이·2024년 7월 15일
0

Flask REST API 서버와 PLC 및 Redis 통합

이번 글에서는 Flask를 이용한 REST API 서버와 PLC 및 Redis와의 통합을 다루는 두 개의 코드 스니펫을 분석해 보겠다. 첫 번째 코드 스니펫은 Flask를 사용하여 EIP(Engineering Protocol) 관련 태그를 관리하는 REST API 서버를 설정하고, 두 번째 코드 스니펫은 PLC와 Redis를 이용하여 태그 데이터를 읽고 쓰는 기능을 구현한다.


1. Flask REST API 서버 코드
Flask와 Flask-RESTx 설정:

  • Flask 애플리케이션을 생성하고, Flask-RESTx를 사용하여 API를 구성한다.
from flask import Flask, request
from flask_restx import Api, Resource, fields
from taglist import process_tags, start_read, stop_read, write_data, stop_tag

app = Flask(__name__)
api = Api(app, version='1.0', title='EIP Tag')

API 네임스페이스와 모델 정의:

  • /api/eip 네임스페이스를 설정하고, 데이터 모델을 정의한다.
ns = api.namespace('api/eip', description='EIP operations')

memory_map_model = api.model('MemoryMap', {
    'type': fields.String(description='Memory type'),
    'address': fields.Integer(description='Address'),
    'dataType': fields.String(description='Data type'),
    'rwType': fields.String(description='Read/Write type'),
    'tagArraySize': fields.Integer(description='Tag array size'),
    'tagArray': fields.List(fields.String, description='Tag array')
})

tag_model = api.model('Tag', {
    'type': fields.String(description='Type'),
    'id': fields.String(description='Unique ID'),
    'name': fields.String(description='Alias name'),
    'memoryMap': fields.List(fields.Nested(memory_map_model), description='Memory map')
})

write_data_model = api.model('WriteData', {
    'tags': fields.List(fields.Nested(api.model('WriteTag', {
        'tag': fields.String(required=True, description='Tag to write'),
        'value': fields.String(required=True, description='Value to write')
    })))
})

API 엔드포인트 정의:

  • /state: 현재 EIP 서버 상태를 조회한다.
  • /tag: 태그를 등록하고, 읽기 작업을 중지한다.
  • /read: 등록된 모든 태그를 읽기 시작하고, 읽기 작업을 중지한다.
  • /write: 태그에 데이터를 쓴다.
@ns.route('/state')
class EIPState(Resource):
    @ns.doc(description='Get the current state of the Python EIP server')
    def get(self):
        return {'state': 'running'}, 200

@ns.route('/tag')
class Tag(Resource):
    @ns.doc(description='Register tags from the provided JSON')
    @ns.expect(tag_model)
    def post(self):
        data = request.json
        global tag_name_dict
        tag_name_dict = process_tags(data)  # process_tags 함수를 호출하여 tag_name_dict 생성
        return {'results': list(tag_name_dict.keys())}, 201
    
    @ns.doc(description='Stop reading specified tags')
    def delete(self):
        global tag_name_dict
        if not tag_name_dict:
            return {'message': 'No tags to stop'}, 400
        tag_list = list(tag_name_dict.keys())  # 모든 등록된 태그 이름들의 리스트
        results = stop_tag(tag_list)
        tag_name_dict.clear()
        return {'results': results}, 200

@ns.route('/read')
class Read(Resource):
    @ns.doc(description='Start reading all registered tags')
    def post(self):
        global tag_name_dict
        if not tag_name_dict:
            return {'message': 'No tags to read'}, 400
        tag_list = list(tag_name_dict.keys())  # 모든 등록된 태그 이름들의 리스트
        results = start_read(tag_list)
        return {'results': results}, 201
    
    @ns.doc(description='Stop redis server')
    def delete(self):
        # Stop reading tags
        stop_read()
        return {'message': 'Stopped reading'}, 200
    
@ns.route('/write')
class Write(Resource):
    @ns.doc(description='Write data to tags')
    @ns.expect(write_data_model)
    def post(self):
        data = request.json
        if not data or not data.get('tags'):
            return {'message': 'No data to write'}, 400
        result = write_data(data)
        return {'result': result}, 201

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

핵심 기능

EIPState 클래스는 EIP 서버의 상태를 조회하는 엔드포인트를 제공한다.
Tag 클래스는 태그를 등록하고, 읽기 작업을 중지할 수 있는 엔드포인트를 제공한다.
Read 클래스는 등록된 태그의 읽기를 시작하고 중지하는 기능을 제공한다.
Write 클래스는 태그에 데이터를 쓰는 기능을 제공한다.

profile
MacBook이 갖고싶은 살암

0개의 댓글