功能实现远程读取非智能电表的用电量,并记录到Excel,每月15号定时统计计算,发送电量到微信,
上代码,功能有打开浏览器并截图,ocr识别电表读数,记录到Excel,和上个月做对比,计算出一个月的用电量。
import datetime
from paddleocr import PaddleOCR, draw_ocr
from PIL import Image, ImageGrab
import openpyxl
from openpyxl import Workbook
import pygetwindow as gw
from pywinauto import Application
import time
import requests
import json
import re
from requests.exceptions import HTTPError, RequestException
def send_request(method, url, headers=None, data=None, json_data=None):
"""通用请求函数"""
try:
response = requests.request(method, url, headers=headers, data=data, json=json_data, allow_redirects=False)
response.raise_for_status()
return response
except HTTPError as http_err:
print(f'HTTP error occurred: {http_err}')
except RequestException as req_err:
print(f'Request error occurred: {req_err}')
return None
def send_wx_message(content, contenttype):
"""发送微信消息"""
url = "http://127.0.0.1:5555/api/sendATMsg"
payload = {
"para": {
"id": "{{date_time}}",
"roomid": "null",
"wxid": "12298079682@chatroom",
#"wxid": "38950634091@chatroom",
"content": content,
"type": contenttype,
"nickname": "三块钱",
"ext": "null"
}
}
headers = {'Content-Type': 'application/json'}
response = requests.post(url, headers=headers, data=json.dumps(payload))
if response:
print(response.text)
def capture_window_by_keyword(keyword, region=None, output_file='selected_window_screenshot.png'):
windows = gw.getAllWindows()
matched_windows = [window for window in windows if keyword.lower() in window.title.lower()]
if not matched_windows:
print(f'No windows found with the keyword: {keyword}')
return
selected_window = matched_windows[0]
app = Application().connect(handle=selected_window._hWnd)
app.top_window().set_focus()
time.sleep(1)
x1, y1 = selected_window.left, selected_window.top
x2, y2 = selected_window.right, selected_window.bottom
if region:
region_x1, region_y1, region_x2, region_y2 = region
x1 += region_x1
y1 += region_y1
x2 = x1 + (region_x2 - region_x1)
y2 = y1 + (region_y2 - region_y1)
bbox = (x1, y1, x2, y2)
screenshot = ImageGrab.grab(bbox)
screenshot.save(output_file)
print(f'Screenshot saved to {output_file}')
def extract_numbers(string):
numbers = re.findall(r'\d+', string)
return ''.join(numbers)
def perform_ocr(img_path):
ocr = PaddleOCR(use_angle_cls=True, lang="ch")
result = ocr.ocr(img_path, cls=True)
for idx in range(len(result)):
res = result[idx]
for line in res:
print(line)
result2 = result[0]
image = Image.open(img_path).convert('RGB')
boxes = [line[0] for line in result2]
txts = [line[1][0] for line in result2]
scores = [line[1][1] for line in result2]
im_show = draw_ocr(image, boxes, txts, scores, font_path='./fonts/simfang.ttf')
im_show = Image.fromarray(im_show)
#im_show.save('3.jpg')
count = len(result[0])
print(count)
start_index = None
end_index = None
target_text = None
for i, line in enumerate(result[0]):
text = line[1][0]
if text == '十':
start_index = i
elif text == '★':
end_index = i
elif start_index is not None and end_index is None:
target_text = text
box = line[0]
score = line[1][1]
break
if target_text:
print(f"识别文本: {target_text}, 置信度: {score}")
print(f"识别文本: {extract_numbers(target_text)}, 置信度: {score}")
im_show = draw_ocr(image, [box], [target_text], [score], font_path='./fonts/simfang.ttf')
im_show = Image.fromarray(im_show)
im_show.save('extracted_target_text.png')
#im_show.show()
return extract_numbers(target_text)
else:
print("未找到目标文本")
return None
def read_meter(file_path):
try:
wb = openpyxl.load_workbook(file_path)
sheet = wb.active
if sheet.max_row > 1:
last_row = sheet[sheet.max_row]
last_date = last_row[0].value
last_reading = last_row[1].value
if last_date and last_reading is not None:
last_reading = int(last_reading)
return last_date, last_reading
else:
return None, 0
else:
return None, 0
except FileNotFoundError:
return None, 0
def write_meter(file_path, date, reading):
try:
wb = openpyxl.load_workbook(file_path)
except FileNotFoundError:
wb = Workbook()
sheet = wb.active
sheet.append(["日期", "读数"])
sheet = wb.active
sheet.append([date, reading])
wb.save(file_path)
def calculate_usage(file_path, current_date, current_reading):
last_date, last_reading = read_meter(file_path)
usage = current_reading - last_reading
write_meter(file_path, current_date, current_reading)
return last_date, last_reading, current_date, current_reading, usage
# 主程序
img_path = 'D:\电表\selected_window_screenshot.png'
file_path = 'D:\电表\meter_readings.xlsx'
# 从图像中提取电表读数
text = perform_ocr(img_path)
if text is not None:
try:
current_reading = int(text)
current_date = datetime.datetime.now()
last_date, last_reading, current_date, current_reading, usage = calculate_usage(file_path, current_date, current_reading)
print(f"上次读数是在 {last_date.strftime('%Y-%m-%d')},读数为 {last_reading} 度。")
print(f"当前读数是在 {current_date.strftime('%Y-%m-%d')},读数为 {current_reading} 度。")
print(f"这段时间的用量为 {usage } 度。")
send_wx_message(f"上次读数是在 {last_date.strftime('%Y-%m-%d')},读数为 {last_reading} 度。\n当前读数是在 {current_date.strftime('%Y-%m-%d')},读数为 {current_reading} 度。\n这段时间的用量为 {usage } 度。电费费用为:{usage*1}元" ,555)
send_wx_message(f"D:/电表/3.jpg" ,500)
except ValueError:
print("无法将识别结果转换为整数。")
萤石云摄像头,申请appKey和appSecret 获取摄像头直播地址,如何生成html文件,预览视频
import requests
import json
def getysyTaken():
url = "https://open.ys7.com/api/lapp/token/get?appKey=6980b***************d72b&appSecret=7ab3*********0b72"
payload = {}
files={}
headers = {}
response = requests.request("POST", url, headers=headers, data=payload, files=files, allow_redirects=False)
print(response.text)
response = response.json()
return (response['data']['accessToken'])
access_token = getysyTaken()
html_content = f'''<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>摄像头</title>
<script src="ezuikit.js"></script>
<style>
html,body {{
padding: 0;
margin: 0;
text-align: center;
background: #00000080;
overflow: hidden;
}}
</style>
</head>
<body>
<div id="playWind"></div>
<script>
var domain = "https://open.ys7.com";
var EZOPENDemo;
window.EZOPENDemo = EZOPENDemo;
var width = document.documentElement.clientWidth;
var height = document.documentElement.clientHeight;
const ezopenInit = () => {{
EZOPENDemo = new EZUIKit.EZUIKitPlayer({{
id: 'playWind',
width: '800',
height: '500',
template: "simple",
url: "ezopen://open.ys7.com/798797360/1.live",
accessToken: "{access_token}"
}});
}}
ezopenInit();
</script>
</body>
</html>
'''
# 将HTML内容写入文件
with open('index.html', 'w', encoding='utf-8') as file:
file.write(html_content)
print("index.html 文件已生成")