Commit 03e2a5aa authored by harshavardhan.c's avatar harshavardhan.c

Automatic OEE Calculator.

parent 8bfeedb0
......@@ -2,159 +2,83 @@ if __name__ == '__main__':
from dotenv import load_dotenv
load_dotenv()
import asyncio
import logging
import os
import time
from datetime import datetime
import pytz
from production_monitoring import ProductionMonitor
from scripts.config import read_settings
from scripts.core.engine.automation_engine import AutomationEngine
from scripts.core.handlers.form_handler import FormHandler
from scripts.db.databases import oee_session
from scripts.db.mongo.dbs.siam_oee import SiamOEE
from scripts.schemas.form import FormDetails, EndProductionRequest
from datetime import datetime, timedelta
from scripts.constants import CommonConstants, TagCategoryConstants
from scripts.core.engine.oee_calculator import OEEEngine
from scripts.core.handlers.batch_oee_calc_handler import CalculateBatchOEEHandler
from scripts.core.handlers.common_handler import CommonHandler
from scripts.logging import logger
from scripts.schemas.batch_oee import MachineOEERequest, BatchOEEData, OEEDataInsertRequest, OEEDataSaveRequest
from scripts.utils.common_utils import CommonUtils
from scripts.utils.kafka_util import DataPush
from scripts.utils.security.encryption import create_token
production_mon = ProductionMonitor()
automation_engine = AutomationEngine()
oee_mongo = SiamOEE()
form_handler = FormHandler()
data_push = DataPush()
settings = read_settings()
def calculate_oee_params(data, downtime):
start_time = datetime.fromtimestamp(
data.get("start_time") // 1000, tz=pytz.timezone("Asia/Bangkok"))
end_time = datetime.now(tz=pytz.timezone("Asia/Bangkok"))
available_time = (end_time - start_time).total_seconds() / 60
if downtime > available_time:
downtime = 0
operating_time = available_time - downtime
availability = operating_time / available_time
good_count, units_produced = production_mon.get_current_produced_count()
if not good_count:
good_count = 0
if not units_produced:
units_produced = 0
productive_time = units_produced * (1 / data.get("cycle_time"))
performance = productive_time / operating_time
if units_produced:
quality = good_count / units_produced
else:
quality = 0
oee = availability * performance * quality
class MachineOEECalculator:
def __init__(self, project_id=None):
self.common_util = CommonUtils()
self.batch_oee_handler = CalculateBatchOEEHandler()
self.common_handler = CommonHandler(project_id=project_id)
self.oee_engine = OEEEngine()
self.data_push = DataPush()
return oee * 100, availability * 100, performance * 100, quality * 100
def calculate_machine_oee(self, request_data: MachineOEERequest):
def update_oee():
tag_mapping = {
"oee": "site_100$dept_100$line_100$equipment_101$tag_215",
"availability": "site_100$dept_100$line_100$equipment_101$tag_216",
"performance": "site_100$dept_100$line_100$equipment_101$tag_217",
"quality": "site_100$dept_100$line_100$equipment_101$tag_218",
"running_lot": "site_100$dept_100$line_100$equipment_101$tag_219",
"running_item": "site_100$dept_100$line_100$equipment_101$tag_220",
"target": "site_100$dept_100$line_100$equipment_101$tag_222",
"downtime": "site_100$dept_100$line_100$equipment_101$tag_223"
}
data = oee_mongo.find_record_by_status("started")
if not data:
data = oee_mongo.find_record_by_status("producing")
if not data:
print("No data found, waiting for batch to start producing")
return
data_dict = {}
if data.get("run_start_time"):
run_start_time = datetime.fromtimestamp(data.get("run_start_time") // 1000, tz=pytz.timezone("Asia/Bangkok"))
downtime = automation_engine.get_downtime(
run_start_time=run_start_time,
production_end_time=datetime.now(tz=pytz.timezone("Asia/Bangkok"))
)
else:
downtime = 0
oee, availability, performance, quality = calculate_oee_params(data, downtime)
data_dict.update(
{
tag_mapping.get("running_lot"): data.get("job", ""), # job no
tag_mapping.get("running_item"): data.get("item", ""), # item no
tag_mapping.get("target"): data.get("qty_released", 0), # quality released
tag_mapping.get("oee"): oee,
tag_mapping.get("availability"): availability,
tag_mapping.get("performance"): performance,
tag_mapping.get("quality"): quality,
tag_mapping.get("downtime"): downtime,
}
)
message_dict = {
"data": data_dict,
"site_id": settings["automation"]["site_id"],
"gw_id": "",
"pd_id": "",
"p_id": settings["automation"]["project_id"],
"timestamp": int(time.time() * 1000),
"msg_id": 1,
"retain_flag": False
}
data_push.publish_message(message_dict)
def check_produce_start():
data = oee_mongo.find_record_by_status("running")
if not data:
print("No data found, waiting for batch to start running")
return
if data.get("prod_status") == "running":
print(f"{data.get('job')} is running ....")
if production_mon.check_production_run():
data["prod_status"] = "producing"
oee_mongo.update_oee(data, data.get("job", ""), data.get("uf_process", ""), False)
def check_production_end():
data = oee_mongo.find_record_by_status("producing")
if not data:
print("No data found, waiting for batch to start producing")
return
print(f"{data.get('job')} is producing ....")
if production_mon.check_production_end(data):
data["prod_status"] = "completed"
data["end_time"] = int(time.time() * 1000)
form_details = FormDetails(**data.get("form_details", {})).dict()
end_production_request = EndProductionRequest(**form_details, submitted_data=dict(data=data),
date=int(time.time() * 1000))
cookies = {"login-token": create_token()}
session = oee_session()
try:
asyncio.run(form_handler.end_production(end_production_request, session, cookies))
hierarchy_dict = self.common_handler.get_valid_oee_monitoring_hierarchy(project_id=request_data.project_id)
now = datetime.today() - timedelta(days=1)
oee_start_time = datetime.strptime(request_data.monitor_time, '%H:%M').replace(year=now.year,
month=now.month,
day=now.day).strftime(
CommonConstants.USER_META_TIME_FORMAT)
oee_end_time = datetime.now().strftime(CommonConstants.USER_META_TIME_FORMAT)
for k, v in hierarchy_dict.items():
site_id = k.split("$")[0]
downtime = self.common_util.get_downtime_details_by_hierarchy(
hierarchy=k, project_id=request_data.project_id)
input_data = OEEDataInsertRequest(prod_start_time=oee_start_time,
prod_end_time=oee_end_time, downtime=downtime,
hierarchy=k, cycle_time=os.environ.get("CYCLE_TIME", default=5),
tz=request_data.tz,
project_id=request_data.project_id)
input_data.total_units, input_data.reject_units = self.batch_oee_handler.get_data_for_tags(
input_data=input_data)
oee_response: BatchOEEData = self.oee_engine.start_batch_oee_calc(
request_data=OEEDataSaveRequest(**input_data.dict()))
data_dict = {
v[TagCategoryConstants.OEE_OUTPUT_CATEGORY]: oee_response.oee,
v[TagCategoryConstants.OEE_OUTPUT_PERFORMANCE_CATEGORY]: oee_response.performance,
v[TagCategoryConstants.OEE_OUTPUT_QUALITY_CATEGORY]: oee_response.quality,
v[TagCategoryConstants.OEE_OUTPUT_QUALITY_LOSS_CATEGORY]: oee_response.quality_loss,
v[TagCategoryConstants.OEE_OUTPUT_PERFORMANCE_LOSS_CATEGORY]: oee_response.performance_loss,
v[TagCategoryConstants.OEE_OUTPUT_AVAILABILITY_CATEGORY]: oee_response.availability,
v[TagCategoryConstants.OEE_OUTPUT_AVAILABILITY_LOSS_CATEGORY]: oee_response.availability_loss
}
message_dict = {
"data": data_dict,
"site_id": site_id,
"gw_id": "",
"pd_id": "",
"p_id": request_data.project_id,
"timestamp": int(time.time() * 1000),
"msg_id": 1,
"retain_flag": False
}
self.data_push.publish_message(message_dict)
except Exception as e:
logging.exception(e)
return
oee_mongo.update_oee(data, data.get("job", ""), data.get("uf_process", ""), False)
del session
logger.exception(f"Exception Occurred while calculating oee for the hierarchy {e.args}")
return
if __name__ == '__main__':
while True:
check_production_end()
projects_list = os.environ.get("OEE_PROJECTS", default="project_170")
monitor_start_time = os.environ.get("OEE_START_TIME", default="00:00")
for project in projects_list.split(","):
MachineOEECalculator().calculate_machine_oee(
request_data=MachineOEERequest(project_id=project, monitor_time="00:00",
tz="Asia/Kolkata"))
time.sleep(10)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment