Commit message
This commit is contained in:
parent
50a6bf2373
commit
5297824869
52
control.json
52
control.json
|
@ -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": 6,
|
||||||
|
"step3": 9,
|
||||||
|
"step4": 20,
|
||||||
|
"step5": 20,
|
||||||
|
"step6": 7,
|
||||||
|
"step7": 12,
|
||||||
|
"step8": 10,
|
||||||
|
"step9": 140
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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.49 # Stackbase(gitea)에 릴리즈 태그명 입니다.
|
tagName: v0.0.50 # Stackbase(gitea)에 릴리즈 태그명 입니다.
|
||||||
repoName: sampyo-dio # Stackbase(gitea)에 저장될 저장소 이릅니다.
|
repoName: sampyo-dio # Stackbase(gitea)에 저장될 저장소 이릅니다.
|
||||||
|
|
115
main.py
115
main.py
|
@ -1,6 +1,5 @@
|
||||||
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
|
||||||
|
@ -10,6 +9,8 @@ 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,7 +212,8 @@ 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
|
||||||
|
@ -185,7 +226,9 @@ def Command_Read():
|
||||||
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]
|
||||||
|
@ -193,7 +236,8 @@ def Command_Read():
|
||||||
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_PureWater(chip=output_lines, status=status, action='On', duration=pure_duration)
|
# 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
|
||||||
|
@ -227,6 +271,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 +280,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':
|
||||||
|
@ -351,7 +401,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 +424,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 +443,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 +460,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 +477,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 +527,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 +545,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 +556,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":{
|
||||||
|
|
Loading…
Reference in New Issue