Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
E
ems_collector
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ZZH
ems_collector
Commits
9c924a49
Commit
9c924a49
authored
Jun 25, 2026
by
ZZH
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add share sub 2026-6-25 16:14
parent
66ebb5f8
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
224 additions
and
0 deletions
+224
-0
meter_3rd2.py
src/ems_water_grp/meter_3rd2.py
+224
-0
No files found.
src/ems_water_grp/meter_3rd2.py
0 → 100644
View file @
9c924a49
# -*- coding:utf-8 -*-
"""
DATE:2026/6/25 16:02
"""
import
json
import
asyncio
import
signal
import
pendulum
import
argparse
from
utils.time_format
import
CST
,
YMD_Hms
from
gmqtt
import
Client
as
MQTTClient
from
ems_water_grp.constants
import
SCADA_FIELDS_MAP
from
utils.utils
import
admin_client_id
,
mqtt_pwd
from
ems_water_grp.helper
import
load_mtype_from_sm
from
infra.config.settings
import
SETTING
from
infra.logger.logger
import
Logger
class
Meter3rdForward
:
sub_host
=
"172.18.4.82"
sub_uname
=
"nyconsumer"
sub_pwd
=
"nyconsumer!321"
# sub_topic = "factory/data"
sub_topic
=
"$share/qkup/factory/data"
pub_username
=
"pot_emqx_super"
pub_topic_pfx
=
"eems/td/"
def
__init__
(
self
,
worker_id
):
self
.
worker_id
=
worker_id
self
.
client_sub
=
None
self
.
client_pub
=
None
self
.
stop_event
=
asyncio
.
Event
()
self
.
d_last_msg
=
{}
@
property
def
pub_pwd
(
self
):
return
mqtt_pwd
(
self
.
pub_username
)
@
staticmethod
def
on_sub_subscribe
(
client
,
mid
,
qos
,
properties
):
logger
.
info
(
f
"Sub to {Meter3rdForward.sub_topic} success, mid: {mid}"
)
@
staticmethod
def
on_sub_connect
(
client
,
flags
,
rc
,
properties
):
logger
.
info
(
f
"Connected to {Meter3rdForward.sub_host} success rc:{rc}"
)
client
.
subscribe
(
Meter3rdForward
.
sub_topic
,
qos
=
1
)
@
staticmethod
def
on_sub_disconnect
(
client
,
packet
,
exc
=
None
):
logger
.
warning
(
f
"Disconnected from {Meter3rdForward.sub_host} {exc}"
)
@
staticmethod
def
on_pub_connect
(
client
,
flags
,
rc
,
properties
):
logger
.
info
(
f
"Connected to {SETTING.mqtt_host} success, rc: {rc}"
)
@
staticmethod
def
on_pub_disconnect
(
client
,
packet
,
exc
=
None
):
logger
.
warning
(
f
"Disconnected from EMQX {SETTING.mqtt_host} exc {exc}"
)
def
on_sub_message
(
self
,
client
,
topic
,
payload
,
qos
,
properties
):
try
:
msg_str
=
payload
.
decode
(
"utf-8"
)
data
=
json
.
loads
(
msg_str
)
fId
=
data
.
get
(
"fId"
)
if
fId
:
self
.
d_last_msg
[
fId
]
=
msg_str
except
Exception
as
e
:
logger
.
error
(
f
"Decode msg:{payload} error: {e}"
)
@
staticmethod
async
def
parse_topic
(
sid
):
m_type
=
await
load_mtype_from_sm
(
sid
)
if
m_type
:
if
m_type
==
137
:
return
"pcc_ele"
elif
m_type
==
136
:
return
"load_ele"
return
""
async
def
parse_and_forward
(
self
,
fid
,
raw_payload
):
""" 重新封装消息,推送至EMQX """
try
:
d_pyds
=
{}
data
=
json
.
loads
(
raw_payload
)
ts
=
pendulum
.
from_timestamp
(
data
[
"time"
],
tz
=
CST
)
.
format
(
YMD_Hms
)
for
item
in
data
[
"items"
]:
try
:
scada_id
=
item
[
"n"
]
if
scada_id
in
SCADA_FIELDS_MAP
[
fid
]:
tmp
=
SCADA_FIELDS_MAP
[
fid
][
scada_id
]
mid
=
tmp
[
"sid"
]
tag
=
{
tmp
[
"field"
]:
item
[
"v"
]}
if
mid
in
d_pyds
:
d_pyds
[
mid
][
"images"
][
0
][
"tags"
]
.
update
(
tag
)
else
:
d_pyds
[
mid
]
=
{
"cid"
:
fid
,
"mid"
:
mid
,
"nm"
:
mid
,
"images"
:
[{
"t"
:
ts
,
"tags"
:
tag
}]}
except
Exception
as
e
:
continue
cnt
=
0
for
sid
,
payload
in
d_pyds
.
items
():
# logger.info(f"{sid}: {payload}")
topic
=
await
self
.
parse_topic
(
sid
)
if
not
topic
:
logger
.
error
(
f
"Parse topic {sid} failed, pyd:{payload}"
)
continue
topic
=
f
"{self.pub_topic_pfx}{topic}/{sid}"
self
.
client_pub
.
publish
(
topic
,
json
.
dumps
(
payload
),
qos
=
1
)
cnt
+=
1
logger
.
info
(
f
"forward fid:{fid} {cnt} msgs"
)
except
Exception
as
e
:
logger
.
error
(
f
"parse_and_forward error: {e}"
)
async
def
snapshot_sampler
(
self
):
while
not
self
.
stop_event
.
is_set
():
try
:
if
self
.
d_last_msg
:
cur_batch
=
dict
(
self
.
d_last_msg
)
self
.
d_last_msg
.
clear
()
for
fid
,
raw_msg
in
cur_batch
.
items
():
if
fid
in
SCADA_FIELDS_MAP
:
await
self
.
parse_and_forward
(
fid
,
raw_msg
)
await
asyncio
.
sleep
(
1
)
except
Exception
as
e
:
logger
.
error
(
f
"Processing loop error: {e}"
)
await
asyncio
.
sleep
(
1
)
async
def
stop
(
self
):
logger
.
info
(
"Shutting down Meter3rdForward Service..."
)
self
.
stop_event
.
set
()
try
:
if
self
.
client_sub
:
await
self
.
client_sub
.
disconnect
()
except
Exception
:
pass
try
:
if
self
.
client_pub
:
await
self
.
client_pub
.
disconnect
()
except
Exception
:
pass
async
def
start
(
self
):
client_id
=
admin_client_id
(
f
"Meter3rdForward{self.worker_id}"
)
self
.
client_sub
=
MQTTClient
(
client_id
)
self
.
client_sub
.
set_auth_credentials
(
self
.
sub_uname
,
self
.
sub_pwd
)
self
.
client_sub
.
on_connect
=
self
.
on_sub_connect
self
.
client_sub
.
on_subscribe
=
self
.
on_sub_subscribe
self
.
client_sub
.
on_disconnect
=
self
.
on_sub_disconnect
self
.
client_sub
.
on_message
=
self
.
on_sub_message
self
.
client_pub
=
MQTTClient
(
admin_client_id
(
"Meter3rdForward"
))
self
.
client_pub
.
set_auth_credentials
(
self
.
pub_username
,
self
.
pub_pwd
)
self
.
client_pub
.
on_connect
=
self
.
on_pub_connect
self
.
client_pub
.
on_disconnect
=
self
.
on_pub_disconnect
loop
=
asyncio
.
get_running_loop
()
for
sig
in
(
signal
.
SIGINT
,
signal
.
SIGTERM
):
loop
.
add_signal_handler
(
sig
,
self
.
stop_event
.
set
)
while
not
self
.
stop_event
.
is_set
():
try
:
await
asyncio
.
gather
(
self
.
client_sub
.
connect
(
self
.
sub_host
,
1883
),
self
.
client_pub
.
connect
(
SETTING
.
mqtt_host
,
SETTING
.
mqtt_port
)
)
logger
.
info
(
"双向 MQTT 服务初始连接全部成功!"
)
break
except
Exception
as
e
:
logger
.
error
(
f
"MQTT 初始连接失败,30秒后重试:{e}"
)
await
asyncio
.
sleep
(
30
)
if
self
.
stop_event
.
is_set
():
return
asyncio
.
create_task
(
self
.
snapshot_sampler
())
logger
.
info
(
"Meter3rdForward 核心服务启动,等待退出信号..."
)
try
:
await
self
.
stop_event
.
wait
()
finally
:
await
self
.
stop
()
async
def
main
(
worker_id
):
while
True
:
try
:
srv
=
Meter3rdForward
(
worker_id
)
await
srv
.
start
()
break
except
Exception
as
e
:
logger
.
error
(
f
"转发服务发生致命异常,10秒后尝试重新初始化: {e}"
)
await
asyncio
.
sleep
(
10
)
if
__name__
==
'__main__'
:
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
"log_num"
,
metavar
=
"log_num"
,
type
=
str
,
help
=
"log file number"
)
args
=
parser
.
parse_args
()
log_num
=
args
.
log_num
log_name
=
f
"meter3rd_forward_{log_num}"
Logger
.
init_logger_path
(
f
"./ems_water_grp"
,
f
"{log_name}.log"
,
log_name
)
logger
=
Logger
.
getLogger
(
log_name
)
try
:
asyncio
.
run
(
main
(
log_num
))
except
KeyboardInterrupt
:
pass
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment