This commit is contained in:
quantulr
2024-01-26 11:34:46 +08:00
commit 8128bfb5f9
27 changed files with 1503 additions and 0 deletions

8
.idea/.gitignore generated vendored Normal file
View 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
View 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>

View 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
View 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
View 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
View 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
README.md Normal file
View File

0
hik_push/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,2 @@
class FeishuAuthException(Exception):
pass

34
hik_push/main.py Normal file
View 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()

View File

Binary file not shown.

View 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-供油站",
}

View 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: '监控点离线',
}

View 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
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

14
hik_push/test.py Normal file
View 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

File diff suppressed because it is too large Load Diff

21
pyproject.toml Normal file
View 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
View File