diff --git a/control.json b/control.json index ae7b748..7ac224c 100644 --- a/control.json +++ b/control.json @@ -1,49 +1,49 @@ { "device": { - "setzero": { + "enter": { "action": "Off" }, + "main": { + "action": "Off", + "duration": 4 + }, "measure": { "action": "On" }, "mixed": { "action": "Off" }, - "pure": { - "action": "Off", - "duration": 1.5 - }, - "enter":{ - "action": "Off" - }, - "vent": { - "action": "On" - }, "motor": { "action": "Off" }, - "main": { + "pure": { "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": { "clean": { "duration": 20, "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 + } +} \ No newline at end of file diff --git a/framework.yaml b/framework.yaml index 4580450..bd39d7f 100644 --- a/framework.yaml +++ b/framework.yaml @@ -7,5 +7,5 @@ spec: virtualEnv: base # 사용할 가상환경 이름입니다. package: requirements.txt # 설치할 Python 패키지 정보 파일입니다.(기본 값은 requirement.txt 입니다.) stackbase: - tagName: v0.0.49 # Stackbase(gitea)에 릴리즈 태그명 입니다. + tagName: v0.0.50 # Stackbase(gitea)에 릴리즈 태그명 입니다. repoName: sampyo-dio # Stackbase(gitea)에 저장될 저장소 이릅니다. diff --git a/main.py b/main.py index 7b671f0..b8b3547 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,5 @@ import json import time -import argparse import sys, signal import gpiod from pymodbus.client import ModbusTcpClient @@ -10,6 +9,8 @@ import pytz from datetime import datetime import threading, socket import uuid +import logging +from logging.handlers import RotatingFileHandler def Motor(chip, status, action): if action == 'On': @@ -64,17 +65,16 @@ def Valve_PureWater(chip, status, action, duration=7): chip.set_values(status) time.sleep(0.05) -def Valve_EnterWater(chip, status, action): - if action == 'On': - status[4] = 1 - else: # action == 'Off' - status[4] = 0 +# def Valve_EnterWater(chip, status, action): +def Valve_EnterWater(chip, status, action, duration=7): + # if action == 'On': + # status[4] = 1 + # else: # action == 'Off' + # status[4] = 0 - chip.set_values(status) - -def Valve_MainWater(chip, status, action, duration=7): + # chip.set_values(status) global main_valve_status - + status[5] = 0 status[6] = 0 chip.set_values(status) @@ -101,6 +101,43 @@ def Valve_MainWater(chip, status, action, duration=7): chip.set_values(status) 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): # print('in') val = 0 @@ -125,12 +162,13 @@ def Calculate_Concentration(weight): result = (float(weight) * volume_water * 128.5) - 126.11 # 1000 / 531 = 1.883239171 data['data']['concentration'] = result # print(f'{weight}, {result}') + return result def Set_Zero(client): client.write_coil(1, 1) def Command_Read(): - global client, main_valve_status + global client, main_valve_status, logger with open('./control.json', 'r') as f: cmd = json.load(f) @@ -156,11 +194,13 @@ def Command_Read(): # Step 1. Vent pured water before input mixed water # 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) Valve_Vent(chip=output_lines, status=status, action='On') 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) # 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] Valve_Vent(chip=output_lines, status=status, action='Off') 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) # Step 4. Mesure the weight @@ -185,7 +226,9 @@ def Command_Read(): end = Measure_Weight(client=client) 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. # Target valve status: [Motor: Off, Vent: On, Pure: On, Enter: On, Main: Off] @@ -193,7 +236,8 @@ def Command_Read(): time.sleep(0.5) Valve_Vent(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', duration=pure_duration) + Valve_PureWater(chip=output_lines, status=status, action='On') time.sleep(step5_duration) # Step 6. Drain mixed water @@ -227,6 +271,7 @@ def Command_Read(): return 1 elif cmd['type'] == 'clean': + logger.debug(f"[clean] duration: {int(cmd['maintenance']['clean']['duration'])}") clean_system() time.sleep(3) @@ -235,20 +280,25 @@ def Command_Read(): 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_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: Valve_PureWater(chip=output_lines, status=status, action=cmd['device']['pure']['action']) else: 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: - 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: - 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': result = Measure_Weight(client=client) Calculate_Concentration(result) @@ -351,7 +401,7 @@ def runAction(): time.sleep(3 - diff) def handle_client(conn, ip, port): - global data + global data, logger while True: try: recv = conn.recv(100) @@ -374,6 +424,8 @@ def handle_client(conn, ip, port): data_weight = '{:.3f}'.format(h_weight) 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' try: @@ -391,6 +443,7 @@ def handle_client(conn, ip, port): conn.sendall(err_msg.encode("utf8")) elif message[3] == 'S': # Start measurement + logger.debug(f'TCP [S:Start measurement]') try: with open('./control.json', 'r') as f: cmd = json.load(f) @@ -407,6 +460,7 @@ def handle_client(conn, ip, port): conn.sendall(err_msg.encode("utf8")) elif message[3] == 'C': # Clean sequence + logger.debug(f'TCP [C:Clean sequence]') try: with open('./control.json', 'r') as f: cmd = json.load(f) @@ -423,6 +477,7 @@ def handle_client(conn, ip, port): conn.sendall(err_msg.encode("utf8")) elif message[3] == 'T': # Stop measurement + logger.debug(f'TCP [T:Stop measurement]') try: with open('./control.json', 'r') as f: cmd = json.load(f) @@ -471,6 +526,11 @@ def start_server(addr, port): client_handler.start() 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): Motor(chip=output_lines, status=status, action='Off') @@ -485,6 +545,7 @@ def exit_handler(signum, frame): sys.exit(0) if __name__ == "__main__": + # Set GPIO output_chip = gpiod.chip('gpiochip11') config = gpiod.line_request() config.consumer = 'output' @@ -495,24 +556,40 @@ if __name__ == "__main__": status = [0, 0, 0, 0, 0, 0, 0, 0] + # When forced to terminate 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 pure_valve_status = 0 Valve_MainWater(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: jsonData = json.load(f) + # Set the weight of water in the chamber 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_port = jsonData['modbus-server']['port'] client = ModbusTcpClient(modbus_addr, modbus_port) + # Define the default data format data = { "timestamp": 0, "data":{ diff --git a/working.log b/working.log new file mode 100644 index 0000000..e69de29