Commit message
This commit is contained in:
parent
c1ea49c0b0
commit
1a1ad4c62f
31
README.md
31
README.md
|
@ -1,3 +1,30 @@
|
|||
# modbusTCP-server-app
|
||||
# 이 코드 템플릿은 SDT Cloud 환경에서 mqtt 메세지를 발행하는 코드입니다.
|
||||
|
||||
Your repository description
|
||||
# 패키지 설치
|
||||
- 코드는 sdtcloudpubsub 패키지를 사용합니다. 아래 명령어로 패키지를 다운로드 해야합니다.
|
||||
```bash
|
||||
$ pip install sdtcloudpubsub
|
||||
```
|
||||
|
||||
# 코드 작성
|
||||
- 코드는 runAction 함수에서 동작하고자 하는 기능을 작성합니다.
|
||||
- msg 변수는 발행될 메세지 입니다.
|
||||
- sdtcloudpubsub의 pubMessage 함수는 발행할 메세지 내용인 dictionary 타입 변수를 입력 받아 처리합니다.
|
||||
|
||||
# 메세지 발행
|
||||
- 다음 변수로 메세지를 발행하는 코드를 작성하면...
|
||||
```bash
|
||||
msg = {
|
||||
"message": "Hello World"
|
||||
}
|
||||
```
|
||||
- 실제로 발행되는 메세지은 다음과 같습니다.
|
||||
```bash
|
||||
msg = {
|
||||
"data": {
|
||||
"message": "Hello World"
|
||||
},
|
||||
"timestamp": 12312311...
|
||||
}
|
||||
|
||||
```
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"modbus-server": {
|
||||
"address": "192.168.0.11",
|
||||
"port": 5020
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
version: bwc/v2 # bwc 버전 정보입니다.
|
||||
spec:
|
||||
appName: aio-test-app # 앱의 이름입니다.
|
||||
runFile: main.py # 앱의 실행 파일입니다.
|
||||
env:
|
||||
bin: python3 # 앱을 실행할 바이너라 파일 종류입니다.(장비에 따라 다르므로 확인 후 정의해야 합니다.)
|
||||
virtualEnv: # 사용할 가상환경 이름입니다.
|
||||
package: requirements.txt # 설치할 Python 패키지 정보 파일입니다.(기본 값은 requirement.txt 입니다.)
|
||||
stackbase:
|
||||
tagName: v0.0.3 # Stackbase(gitea)에 릴리즈 태그명 입니다.
|
||||
repoName: modbusTCP-server-app # Stackbase(gitea)에 저장될 저장소 이릅니다.
|
|
@ -0,0 +1,114 @@
|
|||
import asyncio
|
||||
#from pymodbus.server.async_io import ModbusTcpServer
|
||||
from pymodbus.server.async_io import ModbusTcpServer, StartAsyncTcpServer
|
||||
from pymodbus.datastore import ModbusSequentialDataBlock
|
||||
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
|
||||
import comm_m4
|
||||
import time
|
||||
import struct
|
||||
import signal
|
||||
import sys
|
||||
|
||||
|
||||
async def run_server():
|
||||
with open(os.path.join('./config.json'), encoding='UTF-8') as f:
|
||||
jsonData = json.load
|
||||
|
||||
server = ModbusTcpServer(context, address=(jsonData['modbus-server']['address'], jsonData['modbus-server']['port']))
|
||||
|
||||
task_input = asyncio.create_task(set_input(store))
|
||||
task_output = asyncio.create_task(set_output(store))
|
||||
task_stop_output = asyncio.create_task(stop_output(store))
|
||||
task_cal = asyncio.create_task(set_cal(store))
|
||||
|
||||
await asyncio.gather(server.serve_forever(), task_input, task_output, task_stop_output, task_cal)
|
||||
|
||||
|
||||
async def set_input(store):
|
||||
while True:
|
||||
try:
|
||||
rsp = store.getValues(16,0, count=10)
|
||||
if rsp[0] == 1:
|
||||
data = aio.voltage_once()
|
||||
byte_data = b''.join(struct.pack('f', d) for d in data)
|
||||
result = {'registers': [0]*16}
|
||||
for i in range(8):
|
||||
result['registers'][2*i+1], result['registers'][2*i] = struct.unpack('H', byte_data[4*i:4*i+2])[0], struct.unpack('H', byte_data[4*i+2:4*i+4])[0]
|
||||
|
||||
send_data = result['registers']
|
||||
store.setValues(3,1,send_data)
|
||||
store.setValues(6,0,[0])
|
||||
except Exception as e:
|
||||
print(f'error input:{e}')
|
||||
|
||||
await asyncio.sleep(1)
|
||||
|
||||
|
||||
async def set_output(store):
|
||||
while True:
|
||||
try:
|
||||
rsp = store.getValues(16,20, count=10)
|
||||
channels = [i + 1 for i, value in enumerate(rsp[:8]) if value != 0]
|
||||
voltages = [value for value in rsp[:8] if value != 0]
|
||||
for ch, vol in zip(channels, voltages):
|
||||
aio.start_output(channel=ch, voltage=vol)
|
||||
store.setValues(16,20,[0]*10)
|
||||
except Exception as e:
|
||||
print(f'error output:{e}')
|
||||
|
||||
await asyncio.sleep(1)
|
||||
|
||||
|
||||
async def stop_output(store):
|
||||
while True:
|
||||
try:
|
||||
rsp = store.getValues(16,30, count=10)
|
||||
channels = [i + 1 for i, value in enumerate(rsp[:8]) if value == 0]
|
||||
for ch in channels:
|
||||
aio.stop_output(channel=ch)
|
||||
store.setValues(16,30,[2]*10)
|
||||
except Exception as e:
|
||||
print(f'error stp[]:{e}')
|
||||
|
||||
await asyncio.sleep(1)
|
||||
|
||||
|
||||
async def set_cal(store):
|
||||
while True:
|
||||
try:
|
||||
rsp = store.getValues(16,40, count=1)
|
||||
if rsp[0] == 0:
|
||||
aio.calibration('AO')
|
||||
elif rsp[0] == 1:
|
||||
aio.calibration('AI')
|
||||
store.setValues(16,40,[2]*6)
|
||||
except Exception as e:
|
||||
print(f'error:{e}')
|
||||
|
||||
await asyncio.sleep(1)
|
||||
|
||||
|
||||
def exit_handler(signum, frame):
|
||||
global aio
|
||||
if aio is not None:
|
||||
del aio
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
aio = comm_m4.AIO()
|
||||
|
||||
signal.signal(signal.SIGINT, exit_handler)
|
||||
coil_block = ModbusSequentialDataBlock(0, [0] * 100)
|
||||
holding_block = ModbusSequentialDataBlock(0, [0]*30 + [2]*16 + [0]*(100-36))
|
||||
store = ModbusSlaveContext(
|
||||
co=coil_block,
|
||||
hr=holding_block
|
||||
)
|
||||
context = ModbusServerContext(slaves=store, single=True)
|
||||
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_until_complete(run_server())
|
|
@ -0,0 +1,6 @@
|
|||
# Write package's name that need your app.
|
||||
#awsiotsdk
|
||||
#pyyaml
|
||||
#sdtcloudpubsub
|
||||
|
||||
pymodbus
|
Loading…
Reference in New Issue