Compare commits

...

3 Commits

Author SHA1 Message Date
support.sampyo 61e7c3d4b7 Commit message 2024-10-10 07:53:25 +00:00
support.sampyo 5297824869 Commit message 2024-10-10 07:00:26 +00:00
support.sampyo 50a6bf2373 Commit message 2024-07-30 05:22:35 +00:00
4 changed files with 146 additions and 68 deletions

View File

@ -1,49 +1,49 @@
{ {
"device": { "device": {
"setzero": { "enter": {
"action": "Off" "action": "Off"
}, },
"main": {
"action": "Off",
"duration": 4
},
"measure": { "measure": {
"action": "On" "action": "On"
}, },
"mixed": { "mixed": {
"action": "Off" "action": "Off"
}, },
"pure": {
"action": "Off",
"duration": 1.5
},
"enter":{
"action": "Off"
},
"vent": {
"action": "On"
},
"motor": { "motor": {
"action": "Off" "action": "Off"
}, },
"main": { "pure": {
"action": "Off", "action": "Off",
"duration": 1.5 "duration": 4
},
"setzero": {
"action": "Off"
},
"vent": {
"action": "Off"
} }
}, },
"working-time":{
"step0": 5,
"step1": 10,
"step2": 6,
"step3": 7,
"step4": 20,
"step5": 10,
"step6": 6,
"step7": 6,
"step8": 10,
"step9": 0.5
},
"maintenance": { "maintenance": {
"clean": { "clean": {
"duration": 20, "duration": 20,
"time": 25 "time": 25
} }
}, },
"type": "manual" "type": "manual",
"working-time": {
"step0": 5,
"step1": 10,
"step2": 0.5,
"step3": 4,
"step4": 20,
"step5": 20,
"step6": 0.5,
"step7": 15,
"step8": 10,
"step9": 140
}
} }

View File

@ -7,5 +7,5 @@ spec:
virtualEnv: base # 사용할 가상환경 이름입니다. virtualEnv: base # 사용할 가상환경 이름입니다.
package: requirements.txt # 설치할 Python 패키지 정보 파일입니다.(기본 값은 requirement.txt 입니다.) package: requirements.txt # 설치할 Python 패키지 정보 파일입니다.(기본 값은 requirement.txt 입니다.)
stackbase: stackbase:
tagName: v0.0.48 # Stackbase(gitea)에 릴리즈 태그명 입니다. tagName: v0.0.51 # Stackbase(gitea)에 릴리즈 태그명 입니다.
repoName: sampyo-dio # Stackbase(gitea)에 저장될 저장소 이릅니다. repoName: sampyo-dio # Stackbase(gitea)에 저장될 저장소 이릅니다.

152
main.py
View File

@ -1,15 +1,16 @@
import json import json
import time import time
import argparse
import sys, signal import sys, signal
import gpiod import gpiod
from pymodbus.client import ModbusTcpClient from pymodbus.client import ModbusTcpClient
# import AWSIoTPythonSDK.MQTTLib as AWSIoTPyMQTT # import AWSIoTPythonSDK.MQTTLib as AWSIoTPyMQTT
# import sdtcloudnodeqmqtt import sdtcloudnodeqmqtt
import pytz import pytz
from datetime import datetime from datetime import datetime
import threading, socket import threading, socket
import uuid import uuid
import logging
from logging.handlers import RotatingFileHandler
def Motor(chip, status, action): def Motor(chip, status, action):
if action == 'On': if action == 'On':
@ -64,15 +65,14 @@ def Valve_PureWater(chip, status, action, duration=7):
chip.set_values(status) chip.set_values(status)
time.sleep(0.05) time.sleep(0.05)
def Valve_EnterWater(chip, status, action): # def Valve_EnterWater(chip, status, action):
if action == 'On': def Valve_EnterWater(chip, status, action, duration=7):
status[4] = 1 # if action == 'On':
else: # action == 'Off' # status[4] = 1
status[4] = 0 # else: # action == 'Off'
# status[4] = 0
chip.set_values(status) # chip.set_values(status)
def Valve_MainWater(chip, status, action, duration=7):
global main_valve_status global main_valve_status
status[5] = 0 status[5] = 0
@ -101,6 +101,43 @@ def Valve_MainWater(chip, status, action, duration=7):
chip.set_values(status) chip.set_values(status)
time.sleep(0.05) time.sleep(0.05)
# def Valve_MainWater(chip, status, action, duration=7):
def Valve_MainWater(chip, status, action):
global main_valve_status
# status[5] = 0
# status[6] = 0
# chip.set_values(status)
# time.sleep(0.05)
# if main_valve_status != 0 and action == 'Off':
# status[5] = 0
# status[6] = 1
# chip.set_values(status)
# time.sleep(7)
# main_valve_status = 0
# elif main_valve_status == 0 and action == 'On':
# status[5] = 1
# status[6] = 0
# chip.set_values(status)
# time.sleep(duration)
# if duration >= 7:
# main_valve_status = 2
# elif duration < 7:
# main_valve_status = 1
# status[5] = 0
# status[6] = 0
# chip.set_values(status)
# time.sleep(0.05)
if action == 'On':
status[4] = 1
else: # action == 'Off'
status[4] = 0
chip.set_values(status)
def Measure_Weight(client): def Measure_Weight(client):
# print('in') # print('in')
val = 0 val = 0
@ -125,12 +162,13 @@ def Calculate_Concentration(weight):
result = (float(weight) * volume_water * 128.5) - 126.11 # 1000 / 531 = 1.883239171 result = (float(weight) * volume_water * 128.5) - 126.11 # 1000 / 531 = 1.883239171
data['data']['concentration'] = result data['data']['concentration'] = result
# print(f'{weight}, {result}') # print(f'{weight}, {result}')
return result
def Set_Zero(client): def Set_Zero(client):
client.write_coil(1, 1) client.write_coil(1, 1)
def Command_Read(): def Command_Read():
global client, main_valve_status global client, main_valve_status, logger
with open('./control.json', 'r') as f: with open('./control.json', 'r') as f:
cmd = json.load(f) cmd = json.load(f)
@ -156,11 +194,13 @@ def Command_Read():
# Step 1. Vent pured water before input mixed water # Step 1. Vent pured water before input mixed water
# Target valve status: [Motor: Off, Vent: On, Pure: Off, Enter: On, Main: On] # Target valve status: [Motor: Off, Vent: On, Pure: Off, Enter: On, Main: On]
Valve_EnterWater(chip=output_lines, status=status, action='On') # Valve_EnterWater(chip=output_lines, status=status, action='On')
Valve_MainWater(chip=output_lines, status=status, action='On')
time.sleep(0.5) time.sleep(0.5)
Valve_Vent(chip=output_lines, status=status, action='On') Valve_Vent(chip=output_lines, status=status, action='On')
time.sleep(0.5) time.sleep(0.5)
Valve_MainWater(chip=output_lines, status=status, action='On', duration=main_duration) # Valve_MainWater(chip=output_lines, status=status, action='On', duration=main_duration)
Valve_EnterWater(chip=output_lines, status=status, action='On', duration=main_duration)
time.sleep(step1_duration) time.sleep(step1_duration)
# Step 2. Empty the remaining pure water # Step 2. Empty the remaining pure water
@ -172,28 +212,33 @@ def Command_Read():
# Target valve status: [Motor: Off, Vent: Off, Pure: Off, Enter: On, Main: On] # Target valve status: [Motor: Off, Vent: Off, Pure: Off, Enter: On, Main: On]
Valve_Vent(chip=output_lines, status=status, action='Off') Valve_Vent(chip=output_lines, status=status, action='Off')
time.sleep(0.5) time.sleep(0.5)
Valve_EnterWater(chip=output_lines, status=status, action='On') # Valve_EnterWater(chip=output_lines, status=status, action='On')
Valve_EnterWater(chip=output_lines, status=status, action='On', duration=main_duration)
time.sleep(step3_duration) time.sleep(step3_duration)
# Step 4. Mesure the weight # Step 4. Mesure the weight
# Target valve status: [Motor: Off, Vent: Off, Pure: Off, Enter: Off, Main: Off] # Target valve status: [Motor: Off, Vent: Off, Pure: Off, Enter: Off, Main: Off]
Valve_EnterWater(chip=output_lines, status=status, action='Off')
time.sleep(0.5)
Valve_MainWater(chip=output_lines, status=status, action='Off') Valve_MainWater(chip=output_lines, status=status, action='Off')
time.sleep(0.5)
Valve_EnterWater(chip=output_lines, status=status, action='Off')
time.sleep(step4_duration) time.sleep(step4_duration)
end = Measure_Weight(client=client) end = Measure_Weight(client=client)
time.sleep(1) time.sleep(1)
Calculate_Concentration(weight=(float(end)-float(start))) res = Calculate_Concentration(weight=(float(end)-float(start)))
logger.debug(f'[auto] weight: {end - start} concentration: {res:.3f}')
# Step 5. Drain the mixed water and add pure water. # Step 5. Drain the mixed water and add pure water.
# Target valve status: [Motor: Off, Vent: On, Pure: On, Enter: On, Main: Off] # Target valve status: [Motor: Off, Vent: On, Pure: On, Enter: On, Main: Off]
Valve_EnterWater(chip=output_lines, status=status, action='On')
time.sleep(0.5)
Valve_Vent(chip=output_lines, status=status, action='On') Valve_Vent(chip=output_lines, status=status, action='On')
time.sleep(0.5) time.sleep(0.5)
Valve_PureWater(chip=output_lines, status=status, action='On', duration=pure_duration) Valve_EnterWater(chip=output_lines, status=status, action='On')
time.sleep(0.5)
# Valve_PureWater(chip=output_lines, status=status, action='On', duration=pure_duration)
Valve_PureWater(chip=output_lines, status=status, action='On')
time.sleep(step5_duration) time.sleep(step5_duration)
# Step 6. Drain mixed water # Step 6. Drain mixed water
@ -203,19 +248,19 @@ def Command_Read():
# Step 7. Input pure water and clean # Step 7. Input pure water and clean
# Target valve status: [Motor: On, Vent: Off, Pure: On, Enter: On, Main: Off] # Target valve status: [Motor: On, Vent: Off, Pure: On, Enter: On, Main: Off]
Valve_EnterWater(chip=output_lines, status=status, action='On')
time.sleep(0.5)
Valve_Vent(chip=output_lines, status=status, action='Off') Valve_Vent(chip=output_lines, status=status, action='Off')
time.sleep(0.5) time.sleep(0.5)
Valve_EnterWater(chip=output_lines, status=status, action='On')
time.sleep(0.5)
Motor(chip=output_lines, status=status, action='On') Motor(chip=output_lines, status=status, action='On')
time.sleep(step7_duration) time.sleep(step7_duration)
# Step 8. Drain pure Water # Step 8. Drain pure Water
# Target valve status: [Motor: On, Vent: On, Pure: Off, Enter: Off, Main: Off] # Target valve status: [Motor: On, Vent: On, Pure: Off, Enter: Off, Main: Off]
Valve_EnterWater(chip=output_lines, status=status, action='Off')
time.sleep(0.5)
Valve_Vent(chip=output_lines, status=status, action='On') Valve_Vent(chip=output_lines, status=status, action='On')
time.sleep(0.5) time.sleep(0.5)
Valve_EnterWater(chip=output_lines, status=status, action='Off')
time.sleep(0.5)
Valve_PureWater(chip=output_lines, status=status, action='Off') Valve_PureWater(chip=output_lines, status=status, action='Off')
time.sleep(step8_duration) time.sleep(step8_duration)
@ -227,6 +272,7 @@ def Command_Read():
return 1 return 1
elif cmd['type'] == 'clean': elif cmd['type'] == 'clean':
logger.debug(f"[clean] duration: {int(cmd['maintenance']['clean']['duration'])}")
clean_system() clean_system()
time.sleep(3) time.sleep(3)
@ -235,18 +281,23 @@ def Command_Read():
Valve_Vent(chip=output_lines, status=status, action=cmd['device']['vent']['action']) Valve_Vent(chip=output_lines, status=status, action=cmd['device']['vent']['action'])
# Valve_MixedWater(chip=output_lines, status=status, action=cmd['device']['mixed']['action']) # Valve_MixedWater(chip=output_lines, status=status, action=cmd['device']['mixed']['action'])
# Valve_PureWater(chip=output_lines, status=status, action=cmd['device']['pure']['action']) # Valve_PureWater(chip=output_lines, status=status, action=cmd['device']['pure']['action'])
Valve_EnterWater(chip=output_lines, status=status, action=cmd['device']['enter']['action']) # Valve_EnterWater(chip=output_lines, status=status, action=cmd['device']['enter']['action'])
Valve_MainWater(chip=output_lines, status=status, action=cmd['device']['main']['action'])
if cmd['device']['pure']['duration'] == 0: if cmd['device']['pure']['duration'] == 0:
Valve_PureWater(chip=output_lines, status=status, action=cmd['device']['pure']['action']) Valve_PureWater(chip=output_lines, status=status, action=cmd['device']['pure']['action'])
else: else:
Valve_PureWater(chip=output_lines, status=status, action=cmd['device']['pure']['action'], duration=cmd['device']['pure']['duration']) Valve_PureWater(chip=output_lines, status=status, action=cmd['device']['pure']['action'], duration=cmd['device']['pure']['duration'])
# if cmd['device']['main']['duration'] == 0:
# Valve_MainWater(chip=output_lines, status=status, action=cmd['device']['main']['action'])
# else:
# Valve_MainWater(chip=output_lines, status=status, action=cmd['device']['main']['action'], duration=cmd['device']['main']['duration'])
if cmd['device']['main']['duration'] == 0: if cmd['device']['main']['duration'] == 0:
Valve_MainWater(chip=output_lines, status=status, action=cmd['device']['main']['action']) Valve_EnterWater(chip=output_lines, status=status, action=cmd['device']['enter']['action'])
else: else:
Valve_MainWater(chip=output_lines, status=status, action=cmd['device']['main']['action'], duration=cmd['device']['main']['duration']) Valve_EnterWater(chip=output_lines, status=status, action=cmd['device']['enter']['action'], duration=cmd['device']['main']['duration'])
if cmd['device']['measure']['action'] == 'On': if cmd['device']['measure']['action'] == 'On':
@ -301,13 +352,13 @@ def runAction():
# 2. device-app-light-app -> Good # 2. device-app-light-app -> Good
# 3. device-test-app -> Bad # 3. device-test-app -> Bad
global data global data
# sdtcloud = sdtcloudnodeqmqtt.sdtcloudnodeqmqtt() sdtcloud = sdtcloudnodeqmqtt.sdtcloudnodeqmqtt()
# mqttClient1 = sdtcloud.setClient(f"device-app-1{uuid.uuid1()}") # parameter is client ID(string) mqttClient1 = sdtcloud.setClient(f"device-app-1{uuid.uuid1()}") # parameter is client ID(string)
# mqttClient2 = sdtcloud.setClient(f"device-app-2{uuid.uuid1()}") # parameter is client ID(string) mqttClient2 = sdtcloud.setClient(f"device-app-2{uuid.uuid1()}") # parameter is client ID(string)
# mqttClient3 = sdtcloud.setClient(f"device-app-3{uuid.uuid1()}") # parameter is client ID(string) mqttClient3 = sdtcloud.setClient(f"device-app-3{uuid.uuid1()}") # parameter is client ID(string)
# mqttClient4 = sdtcloud.setClient(f"device-app-4{uuid.uuid1()}") # parameter is client ID(string) mqttClient4 = sdtcloud.setClient(f"device-app-4{uuid.uuid1()}") # parameter is client ID(string)
# mqttClient5 = sdtcloud.setClient(f"device-app-5{uuid.uuid1()}") # parameter is client ID(string) mqttClient5 = sdtcloud.setClient(f"device-app-5{uuid.uuid1()}") # parameter is client ID(string)
# mqttlist = [mqttClient1, mqttClient2, mqttClient3, mqttClient4, mqttClient5] mqttlist = [mqttClient1, mqttClient2, mqttClient3, mqttClient4, mqttClient5]
# If you have config's value, please make config.json file. # If you have config's value, please make config.json file.
# - Project Code's variable: projectCode(string) # - Project Code's variable: projectCode(string)
@ -322,7 +373,7 @@ def runAction():
if result: if result:
data['timestamp'] = int(time.time() * 1000) data['timestamp'] = int(time.time() * 1000)
# sdtcloud.pubMessage(mqttlist[cnt], data) sdtcloud.pubMessage(mqttlist[cnt], data)
cnt += 1 cnt += 1
if cnt == 5: if cnt == 5:
cnt = 0 cnt = 0
@ -351,7 +402,7 @@ def runAction():
time.sleep(3 - diff) time.sleep(3 - diff)
def handle_client(conn, ip, port): def handle_client(conn, ip, port):
global data global data, logger
while True: while True:
try: try:
recv = conn.recv(100) recv = conn.recv(100)
@ -374,6 +425,8 @@ def handle_client(conn, ip, port):
data_weight = '{:.3f}'.format(h_weight) data_weight = '{:.3f}'.format(h_weight)
data_concent = '{:.3f}'.format(h_concentration) data_concent = '{:.3f}'.format(h_concentration)
logger.debug(f'TCP [R:Transfer data] weight: {data_weight}, concent: {data_concent}')
send_msg = 'STX' + time_str + '|' + data_weight + '|' + data_concent + 'ETX' send_msg = 'STX' + time_str + '|' + data_weight + '|' + data_concent + 'ETX'
try: try:
@ -391,6 +444,7 @@ def handle_client(conn, ip, port):
conn.sendall(err_msg.encode("utf8")) conn.sendall(err_msg.encode("utf8"))
elif message[3] == 'S': # Start measurement elif message[3] == 'S': # Start measurement
logger.debug(f'TCP [S:Start measurement]')
try: try:
with open('./control.json', 'r') as f: with open('./control.json', 'r') as f:
cmd = json.load(f) cmd = json.load(f)
@ -407,6 +461,7 @@ def handle_client(conn, ip, port):
conn.sendall(err_msg.encode("utf8")) conn.sendall(err_msg.encode("utf8"))
elif message[3] == 'C': # Clean sequence elif message[3] == 'C': # Clean sequence
logger.debug(f'TCP [C:Clean sequence]')
try: try:
with open('./control.json', 'r') as f: with open('./control.json', 'r') as f:
cmd = json.load(f) cmd = json.load(f)
@ -423,6 +478,7 @@ def handle_client(conn, ip, port):
conn.sendall(err_msg.encode("utf8")) conn.sendall(err_msg.encode("utf8"))
elif message[3] == 'T': # Stop measurement elif message[3] == 'T': # Stop measurement
logger.debug(f'TCP [T:Stop measurement]')
try: try:
with open('./control.json', 'r') as f: with open('./control.json', 'r') as f:
cmd = json.load(f) cmd = json.load(f)
@ -472,6 +528,11 @@ def start_server(addr, port):
soc.close() soc.close()
def seoul_time(*args):
utc_dt = datetime.now()
seoul_tz = pytz.timezone('Asia/Seoul')
return utc_dt.replace(tzinfo=pytz.utc).astimezone(seoul_tz).timetuple()
def exit_handler(signum, frame): def exit_handler(signum, frame):
Motor(chip=output_lines, status=status, action='Off') Motor(chip=output_lines, status=status, action='Off')
Valve_Vent(chip=output_lines, status=status, action='Off') Valve_Vent(chip=output_lines, status=status, action='Off')
@ -485,6 +546,7 @@ def exit_handler(signum, frame):
sys.exit(0) sys.exit(0)
if __name__ == "__main__": if __name__ == "__main__":
# Set GPIO
output_chip = gpiod.chip('gpiochip11') output_chip = gpiod.chip('gpiochip11')
config = gpiod.line_request() config = gpiod.line_request()
config.consumer = 'output' config.consumer = 'output'
@ -495,24 +557,40 @@ if __name__ == "__main__":
status = [0, 0, 0, 0, 0, 0, 0, 0] status = [0, 0, 0, 0, 0, 0, 0, 0]
# When forced to terminate
signal.signal(signal.SIGINT, exit_handler) signal.signal(signal.SIGINT, exit_handler)
# Set the logger
logger = logging.getLogger('sampyo_dio')
logger.setLevel(logging.DEBUG)
handler = RotatingFileHandler('/home/root/working.log', maxBytes=1024*1024, backupCount=3)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
formatter.converter = seoul_time
handler.setFormatter(formatter)
logger.addHandler(handler)
# Initialized valves
main_valve_status = 0 main_valve_status = 0
pure_valve_status = 0 pure_valve_status = 0
Valve_MainWater(chip=output_lines, status=status, action='Off') Valve_MainWater(chip=output_lines, status=status, action='Off')
Valve_PureWater(chip=output_lines, status=status, action='Off') Valve_PureWater(chip=output_lines, status=status, action='Off')
# Read config file
with open('./config.json', encoding='UTF-8') as f: with open('./config.json', encoding='UTF-8') as f:
jsonData = json.load(f) jsonData = json.load(f)
# Set the weight of water in the chamber
volume_water = 1000.0 / float(jsonData['volume-water']) volume_water = 1000.0 / float(jsonData['volume-water'])
# Set the IP address and port of NodeQ RS-232 module and activate TCP Client
modbus_addr = jsonData['modbus-server']['address'] modbus_addr = jsonData['modbus-server']['address']
modbus_port = jsonData['modbus-server']['port'] modbus_port = jsonData['modbus-server']['port']
client = ModbusTcpClient(modbus_addr, modbus_port) client = ModbusTcpClient(modbus_addr, modbus_port)
# Define the default data format
data = { data = {
"timestamp": 0, "timestamp": 0,
"data":{ "data":{

0
working.log Normal file
View File