update
This commit is contained in:
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
8
.idea/hik_push.iml
generated
Normal file
8
.idea/hik_push.iml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
7
.idea/misc.xml
generated
Normal file
7
.idea/misc.xml
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="Poetry (hik_push)" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Poetry (hik_push)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/hik_push.iml" filepath="$PROJECT_DIR$/.idea/hik_push.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
0
hik_push/__init__.py
Normal file
0
hik_push/__init__.py
Normal file
BIN
hik_push/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
hik_push/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
hik_push/__pycache__/custom_exception.cpython-312.pyc
Normal file
BIN
hik_push/__pycache__/custom_exception.cpython-312.pyc
Normal file
Binary file not shown.
BIN
hik_push/__pycache__/main.cpython-312.pyc
Normal file
BIN
hik_push/__pycache__/main.cpython-312.pyc
Normal file
Binary file not shown.
2
hik_push/custom_exception.py
Normal file
2
hik_push/custom_exception.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
class FeishuAuthException(Exception):
|
||||||
|
pass
|
34
hik_push/main.py
Normal file
34
hik_push/main.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import asyncio
|
||||||
|
import json
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
from redis import asyncio as aioredis
|
||||||
|
import uvicorn
|
||||||
|
from fastapi import FastAPI, BackgroundTasks, UploadFile
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
|
async def add_stream(data: dict):
|
||||||
|
redis = await aioredis.Redis(host="127.0.0.1", port=6379)
|
||||||
|
await redis.lpush("hik-sub-event", json.dumps(data))
|
||||||
|
await redis.close()
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
async def root():
|
||||||
|
return {"message": "Hello World"}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/eventRcv")
|
||||||
|
async def event_rcv(data: dict, background_tasks: BackgroundTasks):
|
||||||
|
background_tasks.add_task(add_stream, data)
|
||||||
|
return {"msg": "success"}
|
||||||
|
|
||||||
|
|
||||||
|
def run_app():
|
||||||
|
uvicorn.run("main:app", host="0.0.0.0", port=8000)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
run_app()
|
0
hik_push/mapping/__init__.py
Normal file
0
hik_push/mapping/__init__.py
Normal file
BIN
hik_push/mapping/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
hik_push/mapping/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
hik_push/mapping/__pycache__/device_map.cpython-312.pyc
Normal file
BIN
hik_push/mapping/__pycache__/device_map.cpython-312.pyc
Normal file
Binary file not shown.
BIN
hik_push/mapping/__pycache__/event_map_mapping.cpython-312.pyc
Normal file
BIN
hik_push/mapping/__pycache__/event_map_mapping.cpython-312.pyc
Normal file
Binary file not shown.
15
hik_push/mapping/device_map.py
Normal file
15
hik_push/mapping/device_map.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
device_map = {
|
||||||
|
"192.168.1.12": "4GB-供油站",
|
||||||
|
"192.168.1.13": "T2变电所",
|
||||||
|
"192.168.1.14": "二厂平台~西",
|
||||||
|
"192.168.1.15": "二厂平台~中o1",
|
||||||
|
"192.168.1.16": "T1变电所",
|
||||||
|
"192.168.1.17": "二厂平台~东",
|
||||||
|
"192.168.1.18": "二厂平台~中o2",
|
||||||
|
"192.168.1.19": "T3变电所",
|
||||||
|
"192.168.1.20": "T11变电所",
|
||||||
|
"192.168.1.21": "4GA-供油站",
|
||||||
|
"192.168.1.22": "T9-变压器",
|
||||||
|
"192.168.1.23": "T6-变压器",
|
||||||
|
"192.168.1.24": "4DB-供油站",
|
||||||
|
}
|
45
hik_push/mapping/event_map_mapping.py
Normal file
45
hik_push/mapping/event_map_mapping.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
mapping = {
|
||||||
|
131329: '视频丢失',
|
||||||
|
131330: '视频遮挡',
|
||||||
|
131331: '移动侦测',
|
||||||
|
131612: '场景变更',
|
||||||
|
131613: '虚焦',
|
||||||
|
589825: '报警输入',
|
||||||
|
196355: '可视域事件',
|
||||||
|
851969: 'GPS采集',
|
||||||
|
131588: '区域入侵',
|
||||||
|
131585: '越界侦测',
|
||||||
|
131586: '进入区域',
|
||||||
|
131587: '离开区域',
|
||||||
|
131590: '徘徊侦测',
|
||||||
|
131593: '人员聚集',
|
||||||
|
131592: '快速移动',
|
||||||
|
131591: '停车侦测',
|
||||||
|
131594: '物品遗留',
|
||||||
|
131595: '物品拿取',
|
||||||
|
131664: '人数异常',
|
||||||
|
131665: '间距异常',
|
||||||
|
131596: '剧烈运动',
|
||||||
|
131603: '岗位值守',
|
||||||
|
131605: '倒地',
|
||||||
|
131597: '攀高',
|
||||||
|
131666: '人员站立',
|
||||||
|
131609: '防风场滞留',
|
||||||
|
131598: '起身',
|
||||||
|
131599: '人靠近ATM',
|
||||||
|
131600: '操作超时',
|
||||||
|
131601: '贴纸条',
|
||||||
|
131602: '安装读卡器',
|
||||||
|
131604: '尾随',
|
||||||
|
131606: '声强突变',
|
||||||
|
131607: '折线攀高',
|
||||||
|
131611: '折线警戒面',
|
||||||
|
192518: '温差报警',
|
||||||
|
192517: '温度报警',
|
||||||
|
192516: '船只检测',
|
||||||
|
192515: '火点检测',
|
||||||
|
192514: '烟火检测',
|
||||||
|
192513: '烟雾检测',
|
||||||
|
930335: '高空抛物',
|
||||||
|
889196545: '监控点离线',
|
||||||
|
}
|
17
hik_push/mapping/user_map.py
Normal file
17
hik_push/mapping/user_map.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
user_map = {
|
||||||
|
"192.168.1.12": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"192.168.1.13": [],
|
||||||
|
"192.168.1.14": [],
|
||||||
|
"192.168.1.15": [],
|
||||||
|
"192.168.1.16": [],
|
||||||
|
"192.168.1.17": [],
|
||||||
|
"192.168.1.18": [],
|
||||||
|
"192.168.1.19": [],
|
||||||
|
"192.168.1.20": [],
|
||||||
|
"192.168.1.21": [],
|
||||||
|
"192.168.1.22": [],
|
||||||
|
"192.168.1.23": [],
|
||||||
|
"192.168.1.24": [],
|
||||||
|
}
|
111
hik_push/read_event.py
Normal file
111
hik_push/read_event.py
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import asyncio
|
||||||
|
import json
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from custom_exception import FeishuAuthException
|
||||||
|
from mapping.event_map_mapping import mapping
|
||||||
|
from mapping.device_map import device_map
|
||||||
|
from mapping.user_map import user_map
|
||||||
|
|
||||||
|
from redis import asyncio as aioredis
|
||||||
|
|
||||||
|
app_id = "cli_a525f3d78e3e500c"
|
||||||
|
app_secret = "JVhnbKfXifddjHVwcTqbEfn1rDQBYqDD"
|
||||||
|
|
||||||
|
headers = {"Authorization": ""}
|
||||||
|
|
||||||
|
|
||||||
|
def get_access_token(api_id, secret):
|
||||||
|
url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"
|
||||||
|
data = {
|
||||||
|
"app_id": api_id,
|
||||||
|
"app_secret": secret
|
||||||
|
}
|
||||||
|
resp = requests.post(url, data=data).content.decode('utf-8')
|
||||||
|
return json.loads(resp)['tenant_access_token']
|
||||||
|
|
||||||
|
|
||||||
|
# 获取事件的图片
|
||||||
|
def get_image_url(event):
|
||||||
|
analysis_key = mapping.get(event['eventType'])['detection_key']
|
||||||
|
if analysis_key is None:
|
||||||
|
return None
|
||||||
|
images = []
|
||||||
|
for el in event['data'][analysis_key]:
|
||||||
|
images.append(el['imageUrl'])
|
||||||
|
if len(images) == 0:
|
||||||
|
return None
|
||||||
|
return images
|
||||||
|
|
||||||
|
|
||||||
|
def get_value_by_nested_key(my_dict, nested_key):
|
||||||
|
ret = my_dict
|
||||||
|
for key in nested_key:
|
||||||
|
ret = ret[key]
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
# 上次图片到飞书
|
||||||
|
def upload_image(url):
|
||||||
|
image_content = requests.get(url).content
|
||||||
|
payload = {'image_type': 'message'}
|
||||||
|
files = [
|
||||||
|
('image', ('file', BytesIO(image_content), 'application/octet-stream'))
|
||||||
|
]
|
||||||
|
image = requests.request("POST", "https://open.feishu.cn/open-apis/im/v1/images", data=payload,
|
||||||
|
files=files, headers=headers).content.decode('utf-8')
|
||||||
|
data = json.loads(image)
|
||||||
|
code = data['code']
|
||||||
|
if code == 99991663:
|
||||||
|
raise FeishuAuthException
|
||||||
|
image_key = json.loads(image)['data']['image_key']
|
||||||
|
return image_key
|
||||||
|
|
||||||
|
|
||||||
|
# 推送到飞书
|
||||||
|
def push_to_feishu(data):
|
||||||
|
push_url = "https://open.feishu.cn/open-apis/message/v4/batch_send/"
|
||||||
|
data = json.dumps(data)
|
||||||
|
r = requests.post(push_url, data=data, headers=headers).content.decode('utf-8')
|
||||||
|
data = json.loads(r)
|
||||||
|
code = data['code']
|
||||||
|
if code == 99991663:
|
||||||
|
raise FeishuAuthException
|
||||||
|
print(r)
|
||||||
|
|
||||||
|
|
||||||
|
async def read_event():
|
||||||
|
redis_client = await aioredis.Redis(host="127.0.0.1", port=6379)
|
||||||
|
while True:
|
||||||
|
data = await redis_client.brpop("hik-sub-event")
|
||||||
|
sub_json = json.loads(data[1].decode('utf-8'))
|
||||||
|
try:
|
||||||
|
events = sub_json["params"]["events"]
|
||||||
|
for event in events:
|
||||||
|
# 将eventType ID 替换为中文字符串
|
||||||
|
event_type = event['eventType']
|
||||||
|
event_type_str = mapping.get(event_type, "未知事件类型")
|
||||||
|
event['eventType'] = event_type_str
|
||||||
|
# ip address
|
||||||
|
ip_address = event["data"]["ipAddress"]
|
||||||
|
# 根据 ip_address 获取对应设备名称
|
||||||
|
device_name = device_map.get(ip_address, "未知设备")
|
||||||
|
event['deviceName'] = device_name
|
||||||
|
# print(event['data'][event['data']['eventType']])
|
||||||
|
# TODO: 根据 ip_address 获取对应 userid
|
||||||
|
user_ids = user_map.get(ip_address, [])
|
||||||
|
event['userIds'] = user_ids
|
||||||
|
# TODO: 请求推送 api
|
||||||
|
#
|
||||||
|
print(event, device_name)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("error: ", e)
|
||||||
|
continue
|
||||||
|
await asyncio.sleep(0.5)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(read_event())
|
36
hik_push/requirements.txt
Normal file
36
hik_push/requirements.txt
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
annotated-types==0.6.0
|
||||||
|
anyio==4.2.0
|
||||||
|
certifi==2023.11.17
|
||||||
|
charset-normalizer==3.3.2
|
||||||
|
click==8.1.7
|
||||||
|
colorama==0.4.6
|
||||||
|
dnspython==2.5.0
|
||||||
|
email-validator==2.1.0.post1
|
||||||
|
fastapi==0.109.0
|
||||||
|
h11==0.14.0
|
||||||
|
-e git+http://101.43.70.124:3000/cxc/hik-push.git@6b679957040979034a03da39c78011a26285dc7e#egg=hik_push
|
||||||
|
httpcore==1.0.2
|
||||||
|
httptools==0.6.1
|
||||||
|
httpx==0.26.0
|
||||||
|
idna==3.6
|
||||||
|
itsdangerous==2.1.2
|
||||||
|
Jinja2==3.1.3
|
||||||
|
MarkupSafe==2.1.4
|
||||||
|
orjson==3.9.12
|
||||||
|
pydantic==2.5.3
|
||||||
|
pydantic-extra-types==2.4.1
|
||||||
|
pydantic-settings==2.1.0
|
||||||
|
pydantic_core==2.14.6
|
||||||
|
python-dotenv==1.0.0
|
||||||
|
python-multipart==0.0.6
|
||||||
|
PyYAML==6.0.1
|
||||||
|
redis==5.0.1
|
||||||
|
requests==2.31.0
|
||||||
|
sniffio==1.3.0
|
||||||
|
starlette==0.35.1
|
||||||
|
typing_extensions==4.9.0
|
||||||
|
ujson==5.9.0
|
||||||
|
urllib3==2.1.0
|
||||||
|
uvicorn==0.26.0
|
||||||
|
watchfiles==0.21.0
|
||||||
|
websockets==12.0
|
BIN
hik_push/temp.jpg
Normal file
BIN
hik_push/temp.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 MiB |
14
hik_push/test.py
Normal file
14
hik_push/test.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import io
|
||||||
|
import json
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
image_content = requests.get(
|
||||||
|
"http://47.102.206.10:8086/api/uploads/image/20231101/5bedf085-841a-48cc-bca2-9c9b2c751b48.jpeg").content
|
||||||
|
image_bytes = io.BytesIO(image_content)
|
||||||
|
# files = {"file": image_bytes}
|
||||||
|
data = {"file": "67tgby6y67tg", "file_bytes": "fsfadfsdffadf"}
|
||||||
|
resp = requests.post("http://localhost:8000/upload",
|
||||||
|
files={"file": image_bytes}).content.decode('utf-8')
|
||||||
|
print(resp)
|
1165
poetry.lock
generated
Normal file
1165
poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
21
pyproject.toml
Normal file
21
pyproject.toml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
[tool.poetry]
|
||||||
|
name = "hik-push"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
authors = ["quantulr <35954003+quantulr@users.noreply.github.com>"]
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = "^3.12"
|
||||||
|
fastapi = { extras = ["all"], version = "^0.109.0" }
|
||||||
|
redis = "^5.0.1"
|
||||||
|
requests = "^2.31.0"
|
||||||
|
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
|
|
||||||
|
[tool.poetry.scripts]
|
||||||
|
hik-push = 'hik_push.main:run_app'
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
Reference in New Issue
Block a user