scale_spot_welding_current.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. # -*- coding: utf-8 -*-
  2. """
  3. 一次性把历史点焊电流放大 10 倍,与当前入库规则对齐。
  4. 已放大过的记录(电流绝对值 >= 3)会跳过,可重复执行。
  5. """
  6. import argparse
  7. import json
  8. import sys
  9. from decimal import Decimal
  10. import pymysql
  11. from pymysql.cursors import SSCursor
  12. SCALE_THRESHOLD = Decimal("3")
  13. CURRENT_KEYS = ("robot1Current", "robot2Current")
  14. def to_decimal(value):
  15. if value is None or value == "":
  16. return None
  17. try:
  18. return Decimal(str(value))
  19. except Exception:
  20. return None
  21. def scale_content(content):
  22. if not content:
  23. return None
  24. try:
  25. payload = json.loads(content)
  26. except Exception:
  27. return None
  28. if not isinstance(payload, dict) or payload.get("weldingType") != "spot":
  29. return None
  30. samples = payload.get("samples") or []
  31. if not isinstance(samples, list) or not samples:
  32. return None
  33. max_current = Decimal("0")
  34. for sample in samples:
  35. if not isinstance(sample, dict):
  36. continue
  37. for key in CURRENT_KEYS:
  38. current = to_decimal(sample.get(key))
  39. if current is not None and abs(current) > max_current:
  40. max_current = abs(current)
  41. if max_current <= 0 or max_current >= SCALE_THRESHOLD:
  42. return None
  43. for sample in samples:
  44. if not isinstance(sample, dict):
  45. continue
  46. for key in CURRENT_KEYS:
  47. current = to_decimal(sample.get(key))
  48. if current is None:
  49. continue
  50. scaled = current * 10
  51. if scaled == scaled.to_integral_value():
  52. sample[key] = int(scaled)
  53. else:
  54. sample[key] = float(scaled)
  55. return json.dumps(payload, ensure_ascii=False, separators=(",", ":"))
  56. def main():
  57. parser = argparse.ArgumentParser(description="Scale historical spot welding current by 10")
  58. parser.add_argument("--host", default="127.0.0.1")
  59. parser.add_argument("--port", type=int, default=3306)
  60. parser.add_argument("--user", default="root")
  61. parser.add_argument("--password", required=True)
  62. parser.add_argument("--database", default="mes_cloud_ahdy")
  63. parser.add_argument("--dry-run", action="store_true")
  64. args = parser.parse_args()
  65. read_conn = pymysql.connect(
  66. host=args.host, port=args.port, user=args.user, password=args.password,
  67. database=args.database, charset="utf8mb4", autocommit=False
  68. )
  69. write_conn = pymysql.connect(
  70. host=args.host, port=args.port, user=args.user, password=args.password,
  71. database=args.database, charset="utf8mb4", autocommit=False
  72. )
  73. scanned = 0
  74. updated = 0
  75. skipped = 0
  76. failed = 0
  77. try:
  78. read_cur = read_conn.cursor(SSCursor)
  79. write_cur = write_conn.cursor()
  80. read_cur.execute(
  81. "SELECT id, create_date, content FROM mes_product_arc_welding "
  82. "WHERE content LIKE %s",
  83. ('%"weldingType":"spot"%',)
  84. )
  85. for row_id, create_date, content in read_cur:
  86. scanned += 1
  87. try:
  88. new_content = scale_content(content)
  89. except Exception as ex:
  90. failed += 1
  91. print("parse fail id=%s date=%s err=%s" % (row_id, create_date, ex))
  92. continue
  93. if not new_content:
  94. skipped += 1
  95. elif not args.dry_run:
  96. write_cur.execute(
  97. "UPDATE mes_product_arc_welding SET content=%s WHERE id=%s AND create_date=%s",
  98. (new_content, row_id, create_date)
  99. )
  100. updated += 1
  101. if updated % 200 == 0:
  102. write_conn.commit()
  103. print("updated %s / scanned %s" % (updated, scanned))
  104. else:
  105. updated += 1
  106. if updated % 200 == 0:
  107. print("dry-run would update %s / scanned %s" % (updated, scanned))
  108. if not args.dry_run:
  109. write_conn.commit()
  110. print("done scanned=%s updated=%s skipped=%s failed=%s dry_run=%s"
  111. % (scanned, updated, skipped, failed, args.dry_run))
  112. finally:
  113. read_conn.close()
  114. write_conn.close()
  115. if __name__ == "__main__":
  116. sys.exit(main())