param_f2_program_test.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. import json
  2. import sys
  3. import os
  4. import pymysql
  5. base_dir = os.path.dirname(os.path.abspath(__file__)) if '__file__' in globals() else os.getcwd()
  6. project_root = os.path.abspath(os.path.join(base_dir, "..", ".."))
  7. sys.path.append(project_root)
  8. from utils.functions import convert_commands_to_md5
  9. from pre_data.common.client_tools import redis_client , write_hset
  10. DB_CONFIG = {
  11. "host": "rm-2zenu092q42967j71.mysql.rds.aliyuncs.com",
  12. "port": 3306,
  13. "user": "u_ai_card",
  14. "password": "BHdfH6pMscM_sN3W",
  15. "database": "ai_card",
  16. "charset": "utf8mb4",
  17. }
  18. PROGRAM_NAME_REPLACE_RULES = {
  19. "'": "分钟",
  20. }
  21. PROGRAM_NAMES_INDEX_KEY = "program-names:index"
  22. PROGRAM_NAMES_STREAM_KEY = "program-names:stream"
  23. PROGRAM_NAMES_KEY_PREFIX = "program-names"
  24. def get_db_connection() -> pymysql.Connection:
  25. return pymysql.connect(**DB_CONFIG)
  26. def normalize_program_name(name: str) -> str:
  27. text = str(name).strip()
  28. for src, dst in PROGRAM_NAME_REPLACE_RULES.items():
  29. text = text.replace(src, dst)
  30. return text
  31. def make_program_names_key(type_id: str, zone_id: str) -> str:
  32. return f"{PROGRAM_NAMES_KEY_PREFIX}:{type_id}:{zone_id}"
  33. def extract_param_dict(param_json: dict, wanted_names: list[str]):
  34. """
  35. 从 param_json 中提取指定参数名称的字典
  36. 返回格式: {"夜间洗": "开", "风巡航": "护理"}
  37. """
  38. result: dict[str, str] = {}
  39. param_list = param_json.get("param", [])
  40. for item in param_list:
  41. para_name = item.get("paraName", "").strip()
  42. show_value = item.get("showValue")
  43. if (
  44. para_name
  45. and para_name in wanted_names
  46. and show_value is not None
  47. and str(show_value).strip() != ""
  48. ):
  49. result[item["paraName"]] = item["showValue"]
  50. return result
  51. def build_mapping(param_json_list: list[dict], wanted_names: list[str]):
  52. """
  53. 构建 Redis hset 的 mapping
  54. key: 提取的参数字典的JSON字符串
  55. value: 完整的 param_json JSON字符串
  56. """
  57. mapping: dict[str, str] = {}
  58. for param_json in param_json_list:
  59. param_dict = extract_param_dict(param_json, wanted_names)
  60. key_str = json.dumps(param_dict, ensure_ascii=False, sort_keys=True)
  61. value_str = json.dumps(param_json, ensure_ascii=False, sort_keys=True)
  62. mapping[key_str] = value_str
  63. return mapping
  64. #写入程序名称及定义对应的stream
  65. def write_program_names(type_id: str, zone_id: str, program_names: dict[str, str], clear_before_write: bool = True):
  66. redis_key = make_program_names_key(type_id, zone_id)
  67. index_value = f"{type_id}:{zone_id}"
  68. normalized = {str(k): str(v) for k, v in program_names.items()}
  69. if clear_before_write:
  70. redis_client.delete(redis_key)
  71. write_hset(redis_key, normalized)
  72. redis_client.sadd(PROGRAM_NAMES_INDEX_KEY, index_value)
  73. redis_client.xadd(
  74. PROGRAM_NAMES_STREAM_KEY,
  75. {
  76. "action": "upsert",
  77. "type_id": type_id,
  78. "zone_id": zone_id,
  79. },
  80. )
  81. print(f"[program_names] key={redis_key}, fields={len(normalized)}")
  82. def clear_redis_key_pattern(pattern: str) :
  83. for key in redis_client.scan_iter(match=pattern, count=100):
  84. redis_client.delete(key)
  85. def clear_default_commands(type_id: str, zone_id: str) :
  86. clear_redis_key_pattern(f"default-commands:{type_id}:{zone_id}:*")
  87. #获取默认参数
  88. def write_default_params(type_id: str ,test_type_id: str, wash_type: str, function_type: str, batch_num: str, wanted_names: list[str]):
  89. """
  90. 1. 按当前范围写入一次 default-commands
  91. 仅写入默认参数
  92. """
  93. conn = get_db_connection()
  94. try:
  95. cursor = conn.cursor()
  96. cursor.execute(
  97. """
  98. SELECT request_param
  99. FROM ai_card.t_screen_init_data
  100. WHERE type_id = %s AND wash_type = %s AND function_type= %s AND batch_num = %s
  101. ORDER BY id
  102. """,
  103. (type_id, wash_type, function_type, batch_num),
  104. )
  105. print(type_id, wash_type, function_type, batch_num)
  106. param_json_list: list[dict] = []
  107. index = 1
  108. for row in cursor.fetchall():
  109. outer_json = json.loads(row[0])
  110. param_json = outer_json.get("param_json", {})
  111. param_json_list.append(param_json)
  112. if not param_json_list:
  113. print(f"[skip] no rows for {wash_type}-{function_type}, batch_num={batch_num}")
  114. return
  115. # 原有默认参数写入逻辑:保持不变
  116. # type_id = str(outer_json.get("type_id", "")).strip()
  117. zone_id = str(param_json_list[-1].get("wash_type", "")).strip()
  118. program_id = str(param_json_list[-1].get("program_id", "")).strip()
  119. redis_key = f"default-commands:{test_type_id}:{zone_id}:{program_id}"
  120. mapping = build_mapping(param_json_list, wanted_names)
  121. print("============================================================================================")
  122. print(f"default_commands key: {redis_key}")
  123. print(f"index: {index}")
  124. index=index+1
  125. write_hset(redis_key, mapping)
  126. print(f"完成写入,总条数:{len(param_json_list)}")
  127. finally:
  128. conn.close()
  129. def write_program_names_from_range(type_id:str,test_type_id:str, wash_type: str, function_type: str, batch_num: str):
  130. """
  131. 仅从当前范围聚合 program_id / proName,并写入 program-names Redis + stream
  132. """
  133. conn = get_db_connection()
  134. program_names: dict[str, str] = {}
  135. try:
  136. cursor = conn.cursor()
  137. cursor.execute(
  138. """
  139. SELECT request_param
  140. FROM ai_card.t_screen_init_data
  141. WHERE type_id = %s AND wash_type = %s AND function_type= %s AND batch_num = %s
  142. ORDER BY id
  143. """,
  144. (type_id, wash_type, function_type, batch_num),
  145. )
  146. zone_id = wash_type
  147. for (request_param,) in cursor.fetchall():
  148. outer_json = json.loads(request_param)
  149. param_json = outer_json.get("param_json", {})
  150. # type_id = str(outer_json.get("type_id", "")).strip()
  151. # zone_id = str(param_json.get("wash_type", "")).strip()
  152. program_id = str(param_json.get("program_id", "")).strip()
  153. pro_name = str(param_json.get("proName", "")).strip()
  154. if program_id and pro_name:
  155. program_names[program_id] = normalize_program_name(pro_name)
  156. if type_id and zone_id and program_names:
  157. write_program_names(test_type_id, zone_id, program_names, clear_before_write=True)
  158. print("program_names written: "+test_type_id+":"+zone_id )
  159. else:
  160. print(f"[skip] no program_names for {wash_type}-{function_type}, batch_num={batch_num}")
  161. finally:
  162. conn.close()
  163. return program_names
  164. def write_multi_program_names_from_range(type_id:str, wash_type: str, batch_num: str):
  165. """
  166. 仅从当前范围聚合 program_id / proName,并写入 program-names Redis + stream
  167. """
  168. conn = get_db_connection()
  169. program_names: dict[str, str] = {}
  170. try:
  171. cursor = conn.cursor()
  172. cursor.execute(
  173. """
  174. SELECT program_id, program_name, program_desc
  175. FROM ai_card.ai_rec_v2_program_info
  176. WHERE type_id = %s AND wash_type = %s AND batch_num = %s
  177. ORDER BY id
  178. """,
  179. (type_id, wash_type, batch_num),
  180. )
  181. zone_id = wash_type
  182. for (program_id, program_name, program_desc) in cursor.fetchall():
  183. # 将每一行数据转换为指定格式的字符串作为value
  184. value_str = '{"name":"' + str(program_name) + '","desc":"' + str(program_desc) + '"}'
  185. program_names[str(program_id)] = value_str
  186. print(program_names)
  187. if type_id and zone_id and program_names:
  188. write_program_names(type_id, zone_id, program_names, clear_before_write=True)
  189. print("program_names written: "+type_id+":"+zone_id )
  190. else:
  191. print(f"[skip] no program_names for {wash_type}, batch_num={batch_num}")
  192. finally:
  193. conn.close()
  194. return program_names