Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f571748155 |
@@ -1,4 +1,4 @@
|
||||
DOMAIN = 'state_grid'
|
||||
DOMAIN = "state_grid"
|
||||
PACKAGE_NAME = "custom_components.state_grid"
|
||||
VERSION = "0.0.4"
|
||||
VERSION = "0.1.0"
|
||||
VERSION_STORAGE = 1
|
||||
|
||||
@@ -1,345 +1,350 @@
|
||||
BZ='params4'
|
||||
BY='params3'
|
||||
BX='params1'
|
||||
BW='queryYear'
|
||||
BV='provinceCode'
|
||||
BU='sceneType'
|
||||
BT='consNoSrc'
|
||||
BS='access_token'
|
||||
BR='codeKey'
|
||||
BQ='businessType'
|
||||
BP='Channels'
|
||||
BO='qrCodeSerial'
|
||||
BN='redirect_url'
|
||||
BM='_access_token'
|
||||
BL='is_debug'
|
||||
BK='refresh_interval'
|
||||
BJ='doorAccountDict'
|
||||
BI='refreshToken'
|
||||
BH='accessToken'
|
||||
BG='/osg-web0004/member/c24/f01'
|
||||
BF='BCP_00026'
|
||||
BE='serviceCode_smt'
|
||||
BD='WEBA10070900'
|
||||
BC='serviceType'
|
||||
BB='jM_custType'
|
||||
BA='jM_busiTypeCode'
|
||||
B9='01008183'
|
||||
B8='0101003'
|
||||
B7='submit'
|
||||
B2='consType'
|
||||
B1='constType'
|
||||
B0='powerUserList'
|
||||
A_='publicKey'
|
||||
Az='WEBA10070800'
|
||||
Ay='timeDay'
|
||||
Ax='105'
|
||||
Aw='111'
|
||||
Av='0901'
|
||||
Au='WEBA10070700'
|
||||
At='102'
|
||||
As='0101143'
|
||||
Ar='channelNo'
|
||||
Ae='latestBillMonth'
|
||||
Ad='yearTotalCost'
|
||||
Ac='userAccountId'
|
||||
Ab='0000'
|
||||
Aa='refresh_token'
|
||||
AZ='web'
|
||||
AY='skey'
|
||||
AX='userInfo'
|
||||
AW=True
|
||||
AV='215'
|
||||
AU='0101046'
|
||||
AK='accountBalance'
|
||||
AJ='proCode'
|
||||
AI='loginAccount'
|
||||
AH='keyCode'
|
||||
AG='querytypeCode'
|
||||
AF='01010049'
|
||||
AE='doorNumberManeger'
|
||||
AD='monthBillList'
|
||||
AC='list'
|
||||
AB='userName'
|
||||
AA='acctId'
|
||||
A9='resultCode'
|
||||
A8='quInfo'
|
||||
A7='BCP_000026'
|
||||
A6='app'
|
||||
A5='WEBALIPAY_01'
|
||||
A4='order'
|
||||
A3='state_grid'
|
||||
z=False
|
||||
y='authFlag'
|
||||
x='09'
|
||||
w='0101183'
|
||||
v='stepelect'
|
||||
u='account'
|
||||
t=len
|
||||
s='consNo_dst'
|
||||
r='token'
|
||||
q='0101154'
|
||||
p='getday'
|
||||
n='consNo'
|
||||
m='bizrt'
|
||||
l='clearCache'
|
||||
k='timestamp'
|
||||
i='errmsg'
|
||||
h='promotCode'
|
||||
g='01'
|
||||
f='SGAPP'
|
||||
e='devciceId'
|
||||
d='devciceIp'
|
||||
c='orgNo'
|
||||
b='tenant'
|
||||
a='member'
|
||||
Z=str
|
||||
Y='daily_bill_list'
|
||||
X='proNo'
|
||||
W='promotType'
|
||||
V='target'
|
||||
U='userId'
|
||||
T='srvrt'
|
||||
S='subBusiTypeCode'
|
||||
R='serCat'
|
||||
Q='serialNo'
|
||||
O='0902'
|
||||
N='srvCode'
|
||||
M='uscInfo'
|
||||
L=None
|
||||
K='busiTypeCode'
|
||||
J='code'
|
||||
I='channelCode'
|
||||
H='1'
|
||||
G='source'
|
||||
E='funcCode'
|
||||
D='serviceCode'
|
||||
C='errcode'
|
||||
B='data'
|
||||
A=''
|
||||
import json as AL,time as Af,aiohttp as Ag,urllib.parse,datetime as j
|
||||
from.utils.logger import LOGGER as A0
|
||||
from.utils.store import async_save_to_store as Ba
|
||||
from.utils.crypt import a as AM,b as B3,c as A1,d as AN,e as Ah
|
||||
o='3def6c365d284881bf1a9b2b502ee68c'
|
||||
Ai='ab7357dae64944a197ace37398897f64'
|
||||
F={M:{a:O,d:A,e:A,b:A3},G:f,V:'32101',I:O,Ar:O,'toPublish':g,'siteId':'2012000000033700',N:A,Q:A,E:A,D:{A4:q,'uploadPic':'0101296','pauseSCode':'0101250','pauseTCode':'0101251','listconsumers':'0101093','messageList':'0101343',B7:B8,'sbcMsg':'0101210','powercut':'0104514','BkAuth01':'f15','BkAuth02':'f18','BkAuth03':'f02','BkAuth04':'f17','BkAuth05':'f05','BkAuth06':'f16','BkAuth07':'f01','BkAuth08':'f03'},'electricityArchives':{'servicecode':'0104505',G:O},'subscriptionList':{N:'APP_SGPMS_05_030',Q:'22',I:O,E:'22',V:'-1'},'userInformation':{D:B9,G:f},'userInform':{D:w,G:f},'elesum':{I:O,E:A5,h:H,W:H,D:As,G:A6},u:{I:O,E:'WEBA1007200'},AE:{G:O,V:'-1',I:x,Ar:x,D:AF,E:'WEBA40050000',M:{a:O,d:A,e:A,b:A3}},'doorAuth':{G:f,D:'f04'},'xinZ':{R:'101',BA:'101','fJ_busiTypeCode':At,BB:'03','fJ_custType':'02',BC:g,S:A,E:Au,A4:q,G:f,AG:H},'onedo':{D:AU,G:f,E:Au,'queryType':'03'},'xinHuTongDian':{R:'110',K:'211',S:'21102',E:'WEBA10071200',I:O,G:x,D:w},'company':{R:'104',E:Au,BC:'02',AG:H,y:H,G:f,A4:q},'charge':{I:x,E:'WEBA10071300',Ar:Av,R:At,BB:g,BA:At},'other':{I:x,E:'WEBA10079700',R:'129',K:'999',S:'21501',D:A7,N:A,Q:A},'vatchange':{B7:B8,K:'320',S:A,R:'115',E:'WEBA10074000',y:H},'bill':{l:H,E:A5,W:H,D:A7},v:{I:O,E:A5,W:H,l:x,D:A7,G:A6},p:{I:O,l:'11',E:A5,h:H,W:H,D:A7,G:A6},'mouthOut':{I:O,l:'11',E:A5,h:H,W:H,D:A7,G:A6},'meter':{R:'114',K:'304',E:'WEBA10071000',S:A,D:AU,Q:A},'complaint':{K:'005','srvMode':O,'anonymousFlag':'0','replyMode':g,'retvisitFlag':g},'report':{K:'006'},'tradewinds':{K:'019'},'somesay':{K:'091'},'faultrepair':{E:BD,D:w,R:Aw,K:'001',S:'21505'},'electronicInvoice':{R:Ax,K:'0'},'rename':{D:AU,E:'WEBA10076100',K:'210',R:'109',y:H,'gh_busiTypeCode':'211','gh_subusi':'21101',Q:A,N:A},'pause':{S:A,D:AF,E:'WEBA10073600',R:'107',K:'203','jr_busi':'201',Q:A,N:A},'capacityRecovery':{D:AF,G:f,N:A,Q:A,E:'WEBA10073700','busiTypeCode_stop':'204','busiTypeCode_less':'202',K:'202',S:A,R:'108',Ay:'5',y:H},'electricityPriceChange':{D:w,K:AV,S:'21502',R:'113',y:H,Ay:'15',E:'WEBA10073900WEB',N:A,Q:A},'electricityPriceStrategyChange':{D:B9,K:AV,S:'21506',R:'160',E:'WEBV00000517WEB',N:A,Q:A},'eemandValueAdjustment':{D:w,N:A,Q:A,R:'112',E:'WEBA10073800',K:AV,S:'21504',y:H,Ay:'5','getMonthServiceCode':AU},'businessProgress':{D:w,N:g,E:'WEB01'},'increase':{G:f,Q:A,N:A,BE:AF,D:q,A4:q,E:Az,AG:H,R:'106',K:Aw,S:A},'fjincrea':{R:Ax,K:'110',S:A,G:f,E:Az,Q:A,N:A,BE:AF,D:q,A4:q,AG:H},'persIncrea':{R:Ax,K:'109',A4:q,S:A,G:f,E:Az,AG:H},'fgdChange':{D:w,N:g,I:x,E:BD,K:AV,S:'21505',R:Aw,y:H},'createOrder':{I:O,E:A5,N:'BCP_000001','chargeMode':'02','conType':g,'bizTypeId':'BT_ELEC'},'largePopulation':{K:'383',E:'WEBA10076800',S:A,N:A,W:A,h:A,I:Av,R:'383',D:A,Q:A},'biaoJiCode':{D:'0104507',G:'1704',I:'1704'},'twoGuar':{K:'402',S:'40201',E:'web_twoGuar'},'electTrend':{D:BF,I:O},'emergency':{D:BF,E:'A10000000',I:O},'infoPublic':{D:'2545454',G:A6}}
|
||||
B4='https://www.95598.cn/api'
|
||||
B5='/oauth2/outer/c02/f02'
|
||||
Aj='/osg-open-uc0001/member/c8/f24'
|
||||
Ak='/osg-web0004/open/c50/f02'
|
||||
Al='/osg-uc0013/member/c4/f04'
|
||||
Am='/osg-open-uc0001/member/c8/f04'
|
||||
An='/osg-uc0013/member/c4/f02'
|
||||
B6='/osg-open-uc0001/member/c8/f11'
|
||||
Ao='/oauth2/oauth/authorize'
|
||||
AO='/oauth2/outer/getWebToken'
|
||||
Ap='/oauth2/outer/refresh_web_token'
|
||||
Aq='/osg-open-uc0001/member/c9/f02'
|
||||
AP='/osg-open-bc0001/member/c05/f01'
|
||||
AQ='/osg-open-bc0001/member/c01/f02'
|
||||
AR='/osg-open-bc0001/member/c04/f03'
|
||||
AS=BG
|
||||
AT=BG
|
||||
Bb=[Aj,Ak,Al,Am,An]
|
||||
Bc=[Ak,Al,Am,An,B6,Ao,AO,Ap,Aq,AP,AQ,AR,AS,AT]
|
||||
Bd=[Aq,AP,AQ,AR,AS,AT]
|
||||
Be=[B6,AP,AQ,AR,AS,AT]
|
||||
def A2(data):return AL.dumps(data,separators=(',',':'),ensure_ascii=z)
|
||||
def P(data,key):
|
||||
_Al='constType'
|
||||
_Ak='queryYear'
|
||||
_Aj='provinceCode'
|
||||
_Ai='access_token'
|
||||
_Ah='businessType'
|
||||
_Ag='qrCodeSerial'
|
||||
_Af='redirect_url'
|
||||
_Ae='_access_token'
|
||||
_Ad='refresh_interval'
|
||||
_Ac='doorAccountDict'
|
||||
_Ab='refreshToken'
|
||||
_Aa='accessToken'
|
||||
_AZ='/osg-web0004/member/c24/f01'
|
||||
_AY='BCP_00026'
|
||||
_AX='serviceCode_smt'
|
||||
_AW='WEBA10070900'
|
||||
_AV='serviceType'
|
||||
_AU='jM_custType'
|
||||
_AT='jM_busiTypeCode'
|
||||
_AS='doorNumberManeger'
|
||||
_AR='month'
|
||||
_AQ='consType'
|
||||
_AP='userAccountId'
|
||||
_AO='powerUserList'
|
||||
_AN='publicKey'
|
||||
_AM='WEBA10070800'
|
||||
_AL='timeDay'
|
||||
_AK='WEBA10070700'
|
||||
_AJ='channelNo'
|
||||
_AI='monthBillList'
|
||||
_AH='yearTotalCost'
|
||||
_AG='provinceId'
|
||||
_AF='proCode'
|
||||
_AE='loginAccount'
|
||||
_AD='0000'
|
||||
_AC='refresh_token'
|
||||
_AB='skey'
|
||||
_AA='userInfo'
|
||||
_A9='0101046'
|
||||
_A8='account_balance'
|
||||
_A7='list'
|
||||
_A6='userName'
|
||||
_A5='acctId'
|
||||
_A4='keyCode'
|
||||
_A3='querytypeCode'
|
||||
_A2='01010049'
|
||||
_A1='account'
|
||||
_A0='resultCode'
|
||||
_z='quInfo'
|
||||
_y=True
|
||||
_x='BCP_000026'
|
||||
_w='app'
|
||||
_v='WEBALIPAY_01'
|
||||
_u='order'
|
||||
_t='state_grid'
|
||||
_s='latestBillMonth'
|
||||
_r='consNo_dst'
|
||||
_q='consNo'
|
||||
_p='authFlag'
|
||||
_o='09'
|
||||
_n='0101183'
|
||||
_m='stepelect'
|
||||
_l='daily_bill_list'
|
||||
_k='token'
|
||||
_j=False
|
||||
_i='0101154'
|
||||
_h='getday'
|
||||
_g='bizrt'
|
||||
_f='clearCache'
|
||||
_e='orgNo'
|
||||
_d='timestamp'
|
||||
_c='promotCode'
|
||||
_b='errmsg'
|
||||
_a='01'
|
||||
_Z='SGAPP'
|
||||
_Y='devciceId'
|
||||
_X='devciceIp'
|
||||
_W='proNo'
|
||||
_V='tenant'
|
||||
_U='member'
|
||||
_T='promotType'
|
||||
_S='userId'
|
||||
_R='target'
|
||||
_Q='srvrt'
|
||||
_P='subBusiTypeCode'
|
||||
_O='serialNo'
|
||||
_N='serCat'
|
||||
_M='srvCode'
|
||||
_L='0902'
|
||||
_K='uscInfo'
|
||||
_J='busiTypeCode'
|
||||
_I='channelCode'
|
||||
_H='code'
|
||||
_G=None
|
||||
_F='1'
|
||||
_E='source'
|
||||
_D='funcCode'
|
||||
_C='serviceCode'
|
||||
_B='errcode'
|
||||
_A='data'
|
||||
import json,time,aiohttp,urllib.parse,datetime
|
||||
from.utils.logger import LOGGER
|
||||
from.utils.store import async_save_to_store
|
||||
from.utils.crypt import a,b,c,d,e
|
||||
configuration={_K:{_U:_L,_X:'',_Y:'',_V:_t},_E:_Z,_R:'32101',_I:_L,_AJ:_L,'toPublish':_a,'siteId':'2012000000033700',_M:'',_O:'',_D:'',_C:{_u:_i,'uploadPic':'0101296','pauseSCode':'0101250','pauseTCode':'0101251','listconsumers':'0101093','messageList':'0101343','submit':'0101003','sbcMsg':'0101210','powercut':'0104514','BkAuth01':'f15','BkAuth02':'f18','BkAuth03':'f02','BkAuth04':'f17','BkAuth05':'f05','BkAuth06':'f16','BkAuth07':'f01','BkAuth08':'f03'},'electricityArchives':{'servicecode':'0104505',_E:_L},'subscriptionList':{_M:'APP_SGPMS_05_030',_O:'22',_I:_L,_D:'22',_R:'-1'},'userInformation':{_C:'01008183',_E:_Z},'userInform':{_C:_n,_E:_Z},'elesum':{_I:_L,_D:_v,_c:_F,_T:_F,_C:'0101143',_E:_w},_A1:{_I:_L,_D:'WEBA1007200'},_AS:{_E:_L,_R:'-1',_I:_o,_AJ:_o,_C:_A2,_D:'WEBA40050000',_K:{_U:_L,_X:'',_Y:'',_V:_t}},'doorAuth':{_E:_Z,_C:'f04'},'xinZ':{_N:'101',_AT:'101','fJ_busiTypeCode':'102',_AU:'03','fJ_custType':'02',_AV:_a,_P:'',_D:_AK,_u:_i,_E:_Z,_A3:_F},'onedo':{_C:_A9,_E:_Z,_D:_AK,'queryType':'03'},'xinHuTongDian':{_N:'110',_J:'211',_P:'21102',_D:'WEBA10071200',_I:_L,_E:_o,_C:_n},'company':{_N:'104',_D:_AK,_AV:'02',_A3:_F,_p:_F,_E:_Z,_u:_i},'charge':{_I:_o,_D:'WEBA10071300',_AJ:'0901',_N:'102',_AU:_a,_AT:'102'},'other':{_I:_o,_D:'WEBA10079700',_N:'129',_J:'999',_P:'21501',_C:_x,_M:'',_O:''},'vatchange':{'submit':'0101003',_J:'320',_P:'',_N:'115',_D:'WEBA10074000',_p:_F},'bill':{_f:_F,_D:_v,_T:_F,_C:_x},_m:{_I:_L,_D:_v,_T:_F,_f:_o,_C:_x,_E:_w},_h:{_I:_L,_f:'11',_D:_v,_c:_F,_T:_F,_C:_x,_E:_w},'mouthOut':{_I:_L,_f:'11',_D:_v,_c:_F,_T:_F,_C:_x,_E:_w},'meter':{_N:'114',_J:'304',_D:'WEBA10071000',_P:'',_C:_A9,_O:''},'complaint':{_J:'005','srvMode':_L,'anonymousFlag':'0','replyMode':_a,'retvisitFlag':_a},'report':{_J:'006'},'tradewinds':{_J:'019'},'somesay':{_J:'091'},'faultrepair':{_D:_AW,_C:_n,_N:'111',_J:'001',_P:'21505'},'electronicInvoice':{_N:'105',_J:'0'},'rename':{_C:_A9,_D:'WEBA10076100',_J:'210',_N:'109',_p:_F,'gh_busiTypeCode':'211','gh_subusi':'21101',_O:'',_M:''},'pause':{_P:'',_C:_A2,_D:'WEBA10073600',_N:'107',_J:'203','jr_busi':'201',_O:'',_M:''},'capacityRecovery':{_C:_A2,_E:_Z,_M:'',_O:'',_D:'WEBA10073700','busiTypeCode_stop':'204','busiTypeCode_less':'202',_J:'202',_P:'',_N:'108',_AL:'5',_p:_F},'electricityPriceChange':{_C:_n,_J:'215',_P:'21502',_N:'113',_p:_F,_AL:'15',_D:'WEBA10073900WEB',_M:'',_O:''},'electricityPriceStrategyChange':{_C:'01008183',_J:'215',_P:'21506',_N:'160',_D:'WEBV00000517WEB',_M:'',_O:''},'eemandValueAdjustment':{_C:_n,_M:'',_O:'',_N:'112',_D:'WEBA10073800',_J:'215',_P:'21504',_p:_F,_AL:'5','getMonthServiceCode':_A9},'businessProgress':{_C:_n,_M:_a,_D:'WEB01'},'increase':{_E:_Z,_O:'',_M:'',_AX:_A2,_C:_i,_u:_i,_D:_AM,_A3:_F,_N:'106',_J:'111',_P:''},'fjincrea':{_N:'105',_J:'110',_P:'',_E:_Z,_D:_AM,_O:'',_M:'',_AX:_A2,_C:_i,_u:_i,_A3:_F},'persIncrea':{_N:'105',_J:'109',_u:_i,_P:'',_E:_Z,_D:_AM,_A3:_F},'fgdChange':{_C:_n,_M:_a,_I:_o,_D:_AW,_J:'215',_P:'21505',_N:'111',_p:_F},'createOrder':{_I:_L,_D:_v,_M:'BCP_000001','chargeMode':'02','conType':_a,'bizTypeId':'BT_ELEC'},'largePopulation':{_J:'383',_D:'WEBA10076800',_P:'',_M:'',_T:'',_c:'',_I:'0901',_N:'383',_C:'',_O:''},'biaoJiCode':{_C:'0104507',_E:'1704',_I:'1704'},'twoGuar':{_J:'402',_P:'40201',_D:'web_twoGuar'},'electTrend':{_C:_AY,_I:_L},'emergency':{_C:_AY,_D:'A10000000',_I:_L},'infoPublic':{_C:'2545454',_E:_w}}
|
||||
appKey='3def6c365d284881bf1a9b2b502ee68c'
|
||||
appSecret='ab7357dae64944a197ace37398897f64'
|
||||
baseApi='https://www.95598.cn/api'
|
||||
get_request_key_api='/oauth2/outer/c02/f02'
|
||||
get_qr_code_api='/osg-open-uc0001/member/c8/f24'
|
||||
get_qr_code_status_api='/osg-web0004/open/c50/f02'
|
||||
get_qr_code_token_api='/osg-uc0013/member/c4/f04'
|
||||
send_code_api='/osg-open-uc0001/member/c8/f04'
|
||||
code_login_api='/osg-uc0013/member/c4/f02'
|
||||
getCertificationApi='/osg-open-uc0001/member/c8/f11'
|
||||
get_request_authorize_api='/oauth2/oauth/authorize'
|
||||
get_web_token_api='/oauth2/outer/getWebToken'
|
||||
refresh_web_token_api='/oauth2/outer/refresh_web_token'
|
||||
get_door_number_api='/osg-open-uc0001/member/c9/f02'
|
||||
get_door_balance_api='/osg-open-bc0001/member/c05/f01'
|
||||
get_door_bill_api='/osg-open-bc0001/member/c01/f02'
|
||||
get_door_ladder_api='/osg-open-bc0001/member/c04/f03'
|
||||
getJiaoFeiRecordApi=_AZ
|
||||
get_door_daily_bill_api=_AZ
|
||||
sessionIdControlApiList=[get_qr_code_api,get_qr_code_status_api,get_qr_code_token_api,send_code_api,code_login_api]
|
||||
keyCodeControlApiList=[get_qr_code_status_api,get_qr_code_token_api,send_code_api,code_login_api,getCertificationApi,get_request_authorize_api,get_web_token_api,refresh_web_token_api,get_door_number_api,get_door_balance_api,get_door_bill_api,get_door_ladder_api,getJiaoFeiRecordApi,get_door_daily_bill_api]
|
||||
authControlApiList=[get_door_number_api,get_door_balance_api,get_door_bill_api,get_door_ladder_api,getJiaoFeiRecordApi,get_door_daily_bill_api]
|
||||
tControlApiList=[getCertificationApi,get_door_balance_api,get_door_bill_api,get_door_ladder_api,getJiaoFeiRecordApi,get_door_daily_bill_api]
|
||||
def json_dumps(data):return json.dumps(data,separators=(',',':'),ensure_ascii=_j)
|
||||
def normal_round(num,ndigits=0):
|
||||
A=ndigits
|
||||
if A==0:return int(num+.5)
|
||||
else:B=10**A;return int(num*B+.5)/B
|
||||
def catchFloat(data,key):
|
||||
if key in data:
|
||||
try:return float(data[key])
|
||||
try:return normal_round(float(data[key]),2)
|
||||
except:return 0
|
||||
else:return 0
|
||||
class StateGridDataClient:
|
||||
hass=L;session=L;keyCode=L;publicKey=L;need_login=z;phone=L;codeKey=L;serialNo=L;qrCodeSerial=L;userInfo=L;accountInfo=L;powerUserList=L;doorAccountDict={};cookie=[];timestamp=int(Af.time()*1000);accessToken=L;refreshToken=L;token=L;expirationDate=L;refresh_interval=12;is_debug=z
|
||||
def __init__(A,hass,config=L):
|
||||
B=config;A.hass=hass;C=Ag.TCPConnector(ssl=z);D=Ag.CookieJar(quote_cookie=AW);A.session=Ag.ClientSession(cookie_jar=D,connector=C)
|
||||
if B is not L:
|
||||
try:A.keyCode=B[AH];A.publicKey=B[A_];A.accessToken=B[BH];A.refreshToken=B[BI];A.token=B[r];A.userInfo=B[AX];A.powerUserList=B[B0];A.doorAccountDict=B[BJ];A.refresh_interval=B[BK];A.is_debug=B[BL]
|
||||
except Exception as E:A0.error(E)
|
||||
async def save_data(A):B={};B[AH]=A.keyCode;B[A_]=A.publicKey;B[BH]=A.accessToken;B[BI]=A.refreshToken;B[r]=A.token;B[AX]=A.userInfo;B[B0]=A.powerUserList;B[BJ]=A.doorAccountDict;B[BK]=A.refresh_interval;B[BL]=A.is_debug;await Ba(A.hass,'state_grid.config',B)
|
||||
def encrypt_post_data(B,data):C={BM:B.accessToken[t(B.accessToken)//2:]if B.accessToken else A,'_t':B.token[t(B.token)//2:]if B.token else A,'_data':data,k:B.timestamp};return B.encrypt_wapper_data(C)
|
||||
def encrypt_wapper_data(A,data):C=AM(A2(data),A.keyCode);return{B:C+A1(C+Z(A.timestamp)),AY:AN(A.keyCode,A.publicKey),k:Z(A.timestamp)}
|
||||
def handle_request_result_message(F,api,result):
|
||||
E='message';D='resultMessage';A=result;C=L
|
||||
if B in A and T in A[B]and D in A[B][T]:C=A[B][T][D]
|
||||
elif T in A and D in A[T]:C=A[T][D]
|
||||
elif E in A:C=A[E]
|
||||
else:C=A2(A)
|
||||
if F.is_debug:A0.error(api+': '+C);A0.error(A2(A))
|
||||
return C
|
||||
async def fetch(D,api,data,header=L):
|
||||
Y='encryptData';X='464606a4-184c-4beb-b442-2ab7761d0796';W='key_code';V='state';U='sign';T='grant_type';S='application/json;charset=UTF-8';R='Content-Type';Q=header;P='client_secret';N='client_id';H=api;D.timestamp=int(Af.time()*1000);F=D.timestamp
|
||||
if D.keyCode is L:D.keyCode=Ah(32,16,2)
|
||||
I=D.keyCode;K={'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Mobile Safari/537.36','Accept':S,R:S,'version':'1.0',G:Av,k:Z(F),'wsgwType':AZ,'appKey':o};C=data
|
||||
if H==B5:C={N:o,P:Ai};M=AM(A2(C),I);C={B:M+A1(M+Z(F)),AY:AN(I,'042BC7AD510BF9793B7744C8854C56A8C95DD1027EE619247A332EC6ED5B279F435A23D62441FE861F4B0C963347ECD5792F380B64CA084BE8BE41151F8B8D19C8'),N:o,k:Z(F)}
|
||||
elif H==Aj:C={BM:A,'_t':A,'_data':C,k:F}
|
||||
elif H==Ao:
|
||||
C={N:o,'response_type':J,BN:'/test',k:F,'rsi':D.token};C=urllib.parse.urlencode(C);K[R]='application/x-www-form-urlencoded; charset=UTF-8';K[AH]=I
|
||||
async with D.session.post(B4+H,data=C,headers=K)as O:D.session.cookie_jar.update_cookies(O.cookies);E=await O.json();E=B3(E[B],D.token);E=AL.loads(E);return E
|
||||
elif H==AO:C={T:'authorization_code',U:A1(o+Z(F)),P:Ai,V:X,W:I,N:o,k:F,J:C[J]};M=AM(A2(C),I);C={B:M+A1(M+Z(F)),AY:AN(I,D.publicKey),k:Z(F)}
|
||||
elif H==Ap:C={T:Aa,U:A1(o+Z(F)),P:Ai,V:X,W:I,N:o,k:F,Aa:D.refreshToken};M=AM(A2(C),I);C={B:M+A1(M+Z(F)),AY:AN(I,D.publicKey),k:Z(F)};H=AO
|
||||
else:C=D.encrypt_post_data(C)
|
||||
if Q is not L:K.update(Q)
|
||||
if H in Bb:K['sessionId']=AZ+Z(F)
|
||||
if H in Bc:K[AH]=I
|
||||
if H in Bd:K['Authorization']='Bearer '+D.accessToken[:t(D.accessToken)//2]
|
||||
if H in Be:K['t']=D.token[:t(D.token)//2]
|
||||
async with D.session.post(B4+H,json=C,headers=K)as O:
|
||||
E=await O.text()
|
||||
if E.startswith('{'):
|
||||
E=AL.loads(E)
|
||||
if Y in E:E=B3(E[Y],I);E=AL.loads(E)
|
||||
return E
|
||||
hass=_G;session=_G;keyCode=_G;publicKey=_G;need_login=_j;phone=_G;codeKey=_G;serialNo=_G;qrCodeSerial=_G;userInfo=_G;accountInfo=_G;powerUserList=_G;doorAccountDict={};cookie=[];timestamp=int(time.time()*1000);accessToken=_G;refreshToken=_G;token=_G;expirationDate=_G;refresh_interval=12;is_debug=_j
|
||||
def __init__(A,hass,config=_G):
|
||||
B=config;A.hass=hass;C=aiohttp.TCPConnector(ssl=_j);D=aiohttp.CookieJar(quote_cookie=_y);A.session=aiohttp.ClientSession(cookie_jar=D,connector=C)
|
||||
if B is not _G:
|
||||
try:A.keyCode=B[_A4];A.publicKey=B[_AN];A.accessToken=B[_Aa];A.refreshToken=B[_Ab];A.token=B[_k];A.userInfo=B[_AA];A.powerUserList=B[_AO];A.doorAccountDict=B[_Ac];A.refresh_interval=B[_Ad];A.is_debug=B['is_debug']
|
||||
except Exception as E:LOGGER.error(E)
|
||||
async def save_data(A):B={};B[_A4]=A.keyCode;B[_AN]=A.publicKey;B[_Aa]=A.accessToken;B[_Ab]=A.refreshToken;B[_k]=A.token;B[_AA]=A.userInfo;B[_AO]=A.powerUserList;B[_Ac]=A.doorAccountDict;B[_Ad]=A.refresh_interval;B['is_debug']=A.is_debug;await async_save_to_store(A.hass,'state_grid.config',B)
|
||||
def encrypt_post_data(A,data):B={_Ae:A.accessToken[len(A.accessToken)//2:]if A.accessToken else'','_t':A.token[len(A.token)//2:]if A.token else'','_data':data,_d:A.timestamp};return A.encrypt_wapper_data(B)
|
||||
def encrypt_wapper_data(A,data):B=a(json_dumps(data),A.keyCode);return{_A:B+c(B+str(A.timestamp)),_AB:d(A.keyCode,A.publicKey),_d:str(A.timestamp)}
|
||||
def handle_request_result_message(E,api,result):
|
||||
D='message';C='resultMessage';A=result;B=_G
|
||||
if _A in A and _Q in A[_A]and C in A[_A][_Q]:B=A[_A][_Q][C]
|
||||
elif _Q in A and C in A[_Q]:B=A[_Q][C]
|
||||
elif D in A:B=A[D]
|
||||
else:B=json_dumps(A)
|
||||
if E.is_debug:LOGGER.error(api+': '+B);LOGGER.error(json_dumps(A))
|
||||
return B
|
||||
async def __fetch_safe(C,api,data):
|
||||
B=await C.__fetch(api,data)
|
||||
if _H not in B:return B
|
||||
A=B[_H]
|
||||
if 10015==A or 10108==A or 10009==A or 10207==A or 10005==A or 10010==A or 30010==A or 10002==A:
|
||||
await C.__refresh_token()
|
||||
if C.need_login is _y:return B
|
||||
else:return await C.__fetch(api,data)
|
||||
else:return B
|
||||
async def __fetch(B,api,data,header=_G):
|
||||
T='encryptData';S='464606a4-184c-4beb-b442-2ab7761d0796';R='key_code';Q='state';P='sign';O='grant_type';N='application/json;charset=UTF-8';M='Content-Type';L=header;K='client_secret';I='client_id';E=api;B.timestamp=int(time.time()*1000);D=B.timestamp
|
||||
if B.keyCode is _G:B.keyCode=e(32,16,2)
|
||||
F=B.keyCode;G={'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Mobile Safari/537.36','Accept':N,M:N,'version':'1.0',_E:'0901',_d:str(D),'wsgwType':'web','appKey':appKey};A=data
|
||||
if E==get_request_key_api:A={I:appKey,K:appSecret};H=a(json_dumps(A),F);A={_A:H+c(H+str(D)),_AB:d(F,'042BC7AD510BF9793B7744C8854C56A8C95DD1027EE619247A332EC6ED5B279F435A23D62441FE861F4B0C963347ECD5792F380B64CA084BE8BE41151F8B8D19C8'),I:appKey,_d:str(D)}
|
||||
elif E==get_qr_code_api:A={_Ae:'','_t':'','_data':A,_d:D}
|
||||
elif E==get_request_authorize_api:
|
||||
A={I:appKey,'response_type':_H,_Af:'/test',_d:D,'rsi':B.token};A=urllib.parse.urlencode(A);G[M]='application/x-www-form-urlencoded; charset=UTF-8';G[_A4]=F
|
||||
async with B.session.post(baseApi+E,data=A,headers=G)as J:B.session.cookie_jar.update_cookies(J.cookies);C=await J.json();C=b(C[_A],B.token);C=json.loads(C);return C
|
||||
elif E==get_web_token_api:A={O:'authorization_code',P:c(appKey+str(D)),K:appSecret,Q:S,R:F,I:appKey,_d:D,_H:A[_H]};H=a(json_dumps(A),F);A={_A:H+c(H+str(D)),_AB:d(F,B.publicKey),_d:str(D)}
|
||||
elif E==refresh_web_token_api:A={O:_AC,P:c(appKey+str(D)),K:appSecret,Q:S,R:F,I:appKey,_d:D,_AC:B.refreshToken};H=a(json_dumps(A),F);A={_A:H+c(H+str(D)),_AB:d(F,B.publicKey),_d:str(D)};E=get_web_token_api
|
||||
else:A=B.encrypt_post_data(A)
|
||||
if L is not _G:G.update(L)
|
||||
if E in sessionIdControlApiList:G['sessionId']='web'+str(D)
|
||||
if E in keyCodeControlApiList:G[_A4]=F
|
||||
if E in authControlApiList:G['Authorization']='Bearer '+B.accessToken[:len(B.accessToken)//2]
|
||||
if E in tControlApiList:G['t']=B.token[:len(B.token)//2]
|
||||
async with B.session.post(baseApi+E,json=A,headers=G)as J:
|
||||
C=await J.text()
|
||||
if C.startswith('{'):
|
||||
C=json.loads(C)
|
||||
if T in C:C=b(C[T],F);C=json.loads(C)
|
||||
return C
|
||||
async def __get_request_key(A):
|
||||
A.keyCode=L;D=await A.fetch(B5,{});E=A.handle_request_result_message('get_request_key_api',D)
|
||||
if D[J]==H:A.keyCode=D[B][AH];A.publicKey=D[B][A_];return{C:0}
|
||||
return{C:1,i:E}
|
||||
async def __get_qr_code(E):
|
||||
F={M:{d:A,b:A3,a:O,e:A},A8:{'optType':g,Q:Ah(28,10,1)}};D=await E.fetch(Aj,F);G=E.handle_request_result_message('get_qr_code_api',D)
|
||||
if D[J]==1:
|
||||
if D[B]and D[B][T]and D[B][T][A9]==Ab:E.qrCodeSerial=D[B][m][BO];H=D[B][m]['qrCode'];return{C:0,B:H}
|
||||
return{C:1,i:G}
|
||||
async def __get_qr_code_status(D):
|
||||
E={m:{BO:D.qrCodeSerial}};F={r:'98'+Ah(10,10,1)};A=await D.fetch(Ak,E,F);G=D.handle_request_result_message('get_qr_code_status_api',A)
|
||||
if J in A and A[J]==1:
|
||||
if B in A and A[B]!='null':D.token=A[B];return{C:0}
|
||||
else:return{C:1,i:'未使用网上国网 App 扫码或确认登录'}
|
||||
return{C:1,i:G}
|
||||
A.keyCode=_G;B=await A.__fetch(get_request_key_api,{});C=A.handle_request_result_message('get_request_key_api',B)
|
||||
if B[_H]==_F:A.keyCode=B[_A][_A4];A.publicKey=B[_A][_AN];return{_B:0}
|
||||
return{_B:1,_b:C}
|
||||
async def __get_qr_code(B):
|
||||
C={_K:{_X:'',_V:_t,_U:_L,_Y:''},_z:{'optType':_a,_O:e(28,10,1)}};A=await B.__fetch(get_qr_code_api,C);D=B.handle_request_result_message('get_qr_code_api',A)
|
||||
if A[_H]==1:
|
||||
if A[_A]and A[_A][_Q]and A[_A][_Q][_A0]==_AD:B.qrCodeSerial=A[_A][_g][_Ag];E=A[_A][_g]['qrCode'];return{_B:0,_A:E}
|
||||
return{_B:1,_b:D}
|
||||
async def __get_qr_code_status(B):
|
||||
C={_g:{_Ag:B.qrCodeSerial}};D={_k:'98'+e(10,10,1)};A=await B.__fetch(get_qr_code_status_api,C,D);E=B.handle_request_result_message('get_qr_code_status_api',A)
|
||||
if _H in A and A[_H]==1:
|
||||
if _A in A and A[_A]!='null':B.token=A[_A];return{_B:0}
|
||||
else:return{_B:1,_b:'未使用网上国网 App 扫码或确认登录'}
|
||||
return{_B:1,_b:E}
|
||||
async def __get_qr_code_token(B):
|
||||
D={M:{b:A3,a:O,'isEncrypt':AW},r:B.token};A=await B.fetch(Al,D);E=B.handle_request_result_message('get_qr_code_token_api',A)
|
||||
if T in A and A9 in A[T]and A[T][A9]==Ab:B.userInfo=A[m][AX];return{C:0}
|
||||
return{C:1,i:E}
|
||||
async def __send_code(E,phone):
|
||||
F=phone;E.phone=F;G={M:{d:A,b:A3,a:O,e:A},A8:{'sendType':'0',u:F,BQ:'login','accountType':A},BP:AZ};D=await E.fetch(Am,G);H=E.handle_request_result_message('send_code_api',D)
|
||||
if D[J]==1:
|
||||
if D[B]and D[B][T]and D[B][T][A9]==Ab:E.codeKey=D[B][m][BR];return{C:0}
|
||||
return{C:1,i:H}
|
||||
async def __verfiy_code(B,code):
|
||||
E={M:{d:A,b:A3,a:O,e:A},A8:{u:B.phone,BQ:'login',J:code,'optSys':'ios','pushId':'00000',BR:B.codeKey},BP:AZ};D=await B.fetch(An,E);F=B.handle_request_result_message('code_login_api',D)
|
||||
if T in D and A9 in D[T]and D[T][A9]==Ab:B.token=D[m][r];B.userInfo=D[m][AX][0];return{C:0}
|
||||
return{C:1,i:F}
|
||||
async def __get_request_authorize(D):
|
||||
A=await D.fetch(Ao,{});G=D.handle_request_result_message('get_request_authorize_api',A)
|
||||
if J in A and A[J]==H:E=A[B][BN];F=E.rfind('code=');D.authorizeCode=E[F+5:F+5+32];return{C:0}
|
||||
return{C:1,i:G}
|
||||
C={_K:{_V:_t,_U:_L,'isEncrypt':_y},_k:B.token};A=await B.__fetch(get_qr_code_token_api,C);D=B.handle_request_result_message('get_qr_code_token_api',A)
|
||||
if _Q in A and _A0 in A[_Q]and A[_Q][_A0]==_AD:B.userInfo=A[_g][_AA];return{_B:0}
|
||||
return{_B:1,_b:D}
|
||||
async def __send_code(B,phone):
|
||||
C=phone;B.phone=C;D={_K:{_X:'',_V:_t,_U:_L,_Y:''},_z:{'sendType':'0',_A1:C,_Ah:'login','accountType':''},'Channels':'web'};A=await B.__fetch(send_code_api,D);E=B.handle_request_result_message('send_code_api',A)
|
||||
if A[_H]==1:
|
||||
if A[_A]and A[_A][_Q]and A[_A][_Q][_A0]==_AD:B.codeKey=A[_A][_g]['codeKey'];return{_B:0}
|
||||
return{_B:1,_b:E}
|
||||
async def __verfiy_code(A,code):
|
||||
C={_K:{_X:'',_V:_t,_U:_L,_Y:''},_z:{_A1:A.phone,_Ah:'login',_H:code,'optSys':'ios','pushId':'00000','codeKey':A.codeKey},'Channels':'web'};B=await A.__fetch(code_login_api,C);D=A.handle_request_result_message('code_login_api',B)
|
||||
if _Q in B and _A0 in B[_Q]and B[_Q][_A0]==_AD:A.token=B[_g][_k];A.userInfo=B[_g][_AA][0];return{_B:0}
|
||||
return{_B:1,_b:D}
|
||||
async def __get_request_authorize(B):
|
||||
A=await B.__fetch(get_request_authorize_api,{});E=B.handle_request_result_message('get_request_authorize_api',A)
|
||||
if _H in A and A[_H]==_F:C=A[_A][_Af];D=C.rfind('code=');B.authorizeCode=C[D+5:D+5+32];return{_B:0}
|
||||
return{_B:1,_b:E}
|
||||
async def __get_web_token(A):
|
||||
E={J:A.authorizeCode};D=await A.fetch(AO,E);F=A.handle_request_result_message('get_web_token_api',D)
|
||||
if J in D and D[J]==H:A.accessToken=D[B][BS];A.refreshToken=D[B][Aa];return{C:0}
|
||||
return{C:1,i:F}
|
||||
async def __refresh_web_token(D):
|
||||
A=await D.fetch(Ap,{});E=D.handle_request_result_message('refresh_web_token_api',A)
|
||||
if J in A and A[J]==H:D.accessToken=A[B][BS];D.refreshToken=A[B][Aa];return{C:0}
|
||||
return{C:1,i:E}
|
||||
async def __get_door_number(E):
|
||||
H={D:F[D],G:F[G],V:F[V],M:{a:F[AE][M][a],d:F[AE][M][d],e:F[AE][M][e],b:F[AE][M][b]},A8:{U:E.userInfo[U]},r:E.token};A=await E.fetch(Aq,H);I=E.handle_request_result_message('get_door_number_api',A)
|
||||
if J in A and A[J]==1 and B in A and m in A[B]:E.powerUserList=A[B][m][B0];return{C:0}
|
||||
return{C:1,i:I}
|
||||
async def __get_door_balance(L,door_account):
|
||||
C=door_account;O={B:{N:A,Q:A,I:F[u][I],E:F[u][E],AA:L.userInfo[U],AB:L.userInfo[AI],W:H,h:H,Ac:L.userInfo[U],AC:[{BT:C[s],AJ:C[X],BU:C[B1],n:C[n],c:C[c]}]},D:As,G:F[G],V:C[X]};K=await L.fetch(AP,O);L.handle_request_result_message('get_door_balance_api',K)
|
||||
if J in K and K[J]==1 and B in K and AC in K[B]:
|
||||
M=K[B][AC]
|
||||
if t(M)!=0:C[AK]=M[0]
|
||||
async def __get_door_bill(L,door_account,year):
|
||||
P='dataInfo';M='mothEleList';C=door_account;O={B:{N:A,Q:A,I:F[u][I],E:F[u][E],AA:L.userInfo[U],AB:L.userInfo[AI],W:H,h:H,Ac:L.userInfo[U],AC:[{BT:C[s],AJ:C[X],BU:C['consSortCode'],n:C[n],c:C[c]}]},D:As,G:F[G],V:C[X]};O={B:{AA:L.userInfo[U],I:F[I],l:'11',B2:C[B1],E:'ALIPAY_01',c:C[c],AJ:C[X],h:H,W:H,Q:A,N:A,AB:A,BV:C[X],Ac:L.userInfo[U],n:C[n],BW:year},D:A7,G:A6,V:C[X]};K=await L.fetch(AQ,O);L.handle_request_result_message('get_door_bill_api',K)
|
||||
if J in K and K[J]==1 and B in K:
|
||||
if P in K[B]:C[Ad]=K[B][P]
|
||||
if M in K[B]:C[AD]=K[B][M];C[Ae]=K[B][M][-1]['month']
|
||||
async def __get_door_ladder(H,door_account,month):
|
||||
O='ladder_flag';M=month;C=door_account;P=C[s];R={B:{I:F[v][I],E:F[v][E],W:F[v][W],l:F[v][l],n:C[s],h:C[X],c:C[c],'queryDate':M,BV:C[X],B2:C[B1],Ac:H.userInfo[U],Q:A,N:A,AB:H.userInfo[AI],AA:H.userInfo[U]},D:F[v][D],G:F[v][G],V:C[X]};K=await H.fetch(AR,R);S=H.handle_request_result_message('get_door_ladder_api',K)
|
||||
if J in K and K[J]==1 and B in K and AC in K[B]:
|
||||
L=K[B][AC]
|
||||
if t(L)!=0:
|
||||
L=L[0];L['month']=M
|
||||
if L['electricParticulars']['levelFlag']=='2':C[O]=1
|
||||
else:C[O]=0
|
||||
H.doorAccountDict[P]['ladder']=L
|
||||
async def __get_door_daily_bill(C,door_account,year,start_date,end_date):
|
||||
L='sevenEleList';K=door_account;O={BX:{D:F[D],G:F[G],V:F[V],M:{a:F[M][a],d:F[M][d],e:F[M][e],b:F[M][b]},A8:{U:C.userInfo[U]},r:C.token},BY:{B:{AA:C.userInfo[U],n:K[s],B2:g,'endTime':end_date,c:K[c],BW:year,AJ:K[X],Q:A,N:A,'startTime':start_date,AB:C.userInfo[AI],E:F[p][E],I:F[p][I],l:F[p][l],h:F[p][h],W:F[p][W]},D:F[p][D],G:F[p][G],V:K[X]},BZ:'010103'};H=await C.fetch(AT,O);P=C.handle_request_result_message('get_door_daily_bill_api',H)
|
||||
if J in H and H[J]==1 and B in H and L in H[B]:K[Y]=H[B][L]
|
||||
async def __get_door_pay_record(C,door_account):J=door_account;L=J[s];K={BX:{D:F[D],G:F[G],V:F[V],M:{a:F[M][a],d:F[M][d],e:F[M][e],b:F[M][b]},A8:{U:C.userInfo[U]},r:C.token},BY:{B:{AA:C.userInfo[U],'bgnPayDate':'2023-04-24',I:F[I],n:J[s],'endPayDate':'2024-04-24',E:'webALIPAY_01','number':100,c:J[c],'page':H,AJ:J[X],h:H,W:H,Q:A,N:A,AB:C.userInfo[AI]},D:'0101051',G:g,V:J[X]},BZ:'010104'};O=await C.fetch(AS,K)
|
||||
C={_H:A.authorizeCode};B=await A.__fetch(get_web_token_api,C);D=A.handle_request_result_message('get_web_token_api',B)
|
||||
if _H in B and B[_H]==_F:A.accessToken=B[_A][_Ai];A.refreshToken=B[_A][_AC];return{_B:0}
|
||||
return{_B:1,_b:D}
|
||||
async def __refresh_web_token(B):
|
||||
A=await B.__fetch(refresh_web_token_api,{});C=B.handle_request_result_message('refresh_web_token_api',A)
|
||||
if _H in A and A[_H]==_F:B.accessToken=A[_A][_Ai];B.refreshToken=A[_A][_AC];return{_B:0}
|
||||
return{_B:1,_b:C}
|
||||
async def __get_door_number(C):
|
||||
A=configuration[_AS];D={_C:A[_C],_E:A[_E],_R:A[_R],_K:{_U:A[_K][_U],_X:A[_K][_X],_Y:A[_K][_Y],_V:A[_K][_V]},_z:{_S:C.userInfo[_S]},_k:C.token};B=await C.__fetch_safe(get_door_number_api,D);E=C.handle_request_result_message('get_door_number_api',B)
|
||||
if _H in B and B[_H]==1 and _A in B and _g in B[_A]:C.powerUserList=B[_A][_g][_AO];return{_B:0}
|
||||
return{_B:1,_b:E}
|
||||
async def __get_door_balance(B,door_account):
|
||||
A=door_account;E={_A:{_M:'',_O:'',_I:configuration[_A1][_I],_D:configuration[_A1][_D],_A5:B.userInfo[_S],_A6:B.userInfo.get(_AE,B.userInfo.get('nickname',_G)),_T:_F,_c:_F,_AP:B.userInfo[_S],_A7:[{'consNoSrc':A[_r],_AF:A.get(_W,A.get(_AG,_G)),'sceneType':A.get('consSortCode',A.get('elecTypeCode',_G)),_q:A[_q],_e:A[_e]}]},_C:'0101143',_E:configuration[_E],_R:A.get(_W,A.get(_AG,_G))};C=await B.__fetch_safe(get_door_balance_api,E);B.handle_request_result_message('get_door_balance_api',C)
|
||||
if _H in C and C[_H]==1 and _A in C and _A7 in C[_A]:
|
||||
D=C[_A][_A7]
|
||||
if len(D)!=0:A[_A8]=D[0]
|
||||
async def __get_door_bill(C,door_account,year):
|
||||
E='dataInfo';D='mothEleList';B=door_account;F={_A:{_A5:C.userInfo[_S],_I:configuration[_I],_f:'11',_AQ:B[_Al],_D:'ALIPAY_01',_e:B[_e],_AF:B[_W],_c:_F,_T:_F,_O:'',_M:'',_A6:'',_Aj:B[_W],_AP:C.userInfo[_S],_q:B[_q],_Ak:year},_C:_x,_E:_w,_R:B[_W]};A=await C.__fetch_safe(get_door_bill_api,F);C.handle_request_result_message('get_door_bill_api',A)
|
||||
if _H in A and A[_H]==1 and _A in A:
|
||||
if E in A[_A]:B[_AH]=A[_A][E]
|
||||
if D in A[_A]:
|
||||
B[_AI]=A[_A][D]
|
||||
if len(A[_A][D])!=0:B[_s]=A[_A][D][-1]
|
||||
async def __get_door_ladder(B,door_account,month):
|
||||
F='ladder_flag';E=month;A=door_account;G=A[_r];H={_A:{_I:configuration[_m][_I],_D:configuration[_m][_D],_T:configuration[_m][_T],_f:configuration[_m][_f],_q:A[_r],_c:A[_W],_e:A[_e],'queryDate':E,_Aj:A[_W],_AQ:A[_Al],_AP:B.userInfo[_S],_O:'',_M:'',_A6:B.userInfo[_AE],_A5:B.userInfo[_S]},_C:configuration[_m][_C],_E:configuration[_m][_E],_R:A[_W]};C=await B.__fetch(get_door_ladder_api,H);I=B.handle_request_result_message('get_door_ladder_api',C)
|
||||
if _H in C and C[_H]==1 and _A in C and _A7 in C[_A]:
|
||||
D=C[_A][_A7]
|
||||
if len(D)!=0:
|
||||
D=D[0];D[_AR]=E
|
||||
if D['electricParticulars']['levelFlag']=='2':A[F]=1
|
||||
else:A[F]=0
|
||||
B.doorAccountDict[G]['ladder']=D
|
||||
async def __get_door_daily_bill(B,door_account,year,start_date,end_date):
|
||||
D='sevenEleList';A=door_account;E={'params1':{_C:configuration[_C],_E:configuration[_E],_R:configuration[_R],_K:{_U:configuration[_K][_U],_X:configuration[_K][_X],_Y:configuration[_K][_Y],_V:configuration[_K][_V]},_z:{_S:B.userInfo[_S]},_k:B.token},'params3':{_A:{_A5:B.userInfo[_S],_q:A[_r],_AQ:_a,'endTime':end_date,_e:A[_e],_Ak:year,_AF:A.get(_W,A.get(_AG,_G)),_O:'',_M:'','startTime':start_date,_A6:B.userInfo[_AE],_D:configuration[_h][_D],_I:configuration[_h][_I],_f:configuration[_h][_f],_c:configuration[_h][_c],_T:configuration[_h][_T]},_C:configuration[_h][_C],_E:configuration[_h][_E],_R:A.get(_W,A.get(_AG,_G))},'params4':'010103'};C=await B.__fetch_safe(get_door_daily_bill_api,E);F=B.handle_request_result_message('get_door_daily_bill_api',C)
|
||||
if _H in C and C[_H]==1 and _A in C and D in C[_A]:A[_l]=C[_A][D]
|
||||
async def __get_door_pay_record(A,door_account):B=door_account;D=B[_r];C={'params1':{_C:configuration[_C],_E:configuration[_E],_R:configuration[_R],_K:{_U:configuration[_K][_U],_X:configuration[_K][_X],_Y:configuration[_K][_Y],_V:configuration[_K][_V]},_z:{_S:A.userInfo[_S]},_k:A.token},'params3':{_A:{_A5:A.userInfo[_S],'bgnPayDate':'2023-04-24',_I:configuration[_I],_q:B[_r],'endPayDate':'2024-04-24',_D:'webALIPAY_01','number':100,_e:B[_e],'page':_F,_AF:B[_W],_c:_F,_T:_F,_O:'',_M:'',_A6:A.userInfo[_AE]},_C:'0101051',_E:_a,_R:B[_W]},'params4':'010104'};E=await A.__fetch(getJiaoFeiRecordApi,C)
|
||||
async def get_qr_code(B):
|
||||
A=await B.__get_request_key()
|
||||
if C in A and A[C]!=0:return A
|
||||
if _B in A and A[_B]!=0:return A
|
||||
return await B.__get_qr_code()
|
||||
async def check_qr_code(B):
|
||||
A=await B.__get_qr_code_status()
|
||||
if C in A and A[C]!=0:return A
|
||||
if _B in A and A[_B]!=0:return A
|
||||
A=await B.__get_qr_code_token()
|
||||
if C in A and A[C]!=0:return A
|
||||
if _B in A and A[_B]!=0:return A
|
||||
return await B.__get_token()
|
||||
async def send_phone_code(B,phone):
|
||||
A=await B.__get_request_key()
|
||||
if C in A and A[C]!=0:return A
|
||||
if _B in A and A[_B]!=0:return A
|
||||
return await B.__send_code(phone)
|
||||
async def verfiy_phone_code(B,code):
|
||||
A=await B.__verfiy_code(code)
|
||||
if C in A and A[C]!=0:return A
|
||||
if _B in A and A[_B]!=0:return A
|
||||
return await B.__get_token()
|
||||
async def __get_token(D):
|
||||
A=await D.__get_request_key()
|
||||
if C in A and A[C]!=0:return A
|
||||
A=await D.__get_request_authorize()
|
||||
if C in A and A[C]!=0:return A
|
||||
A=await D.__get_web_token()
|
||||
if C in A and A[C]!=0:return A
|
||||
A=await D.__get_door_number()
|
||||
if C in A and A[C]!=0:return A
|
||||
D.need_login=z;await D.save_data();return{C:0,B:D.powerUserList}
|
||||
async def refresh_data(B,setup=z):
|
||||
q='daily_t_ele_num';p='daily_n_ele_num';o='daily_v_ele_num';n='daily_p_ele_num';m='daily_ele_num';l='last_month_ele_cost';k='last_month_ele_num';i='year_ele_cost';h='year_ele_num';g='monthEleNum';f='thisTPq';e='thisNPq';d='thisVPq';c='thisPPq';T='balance';S='ladder_level_num';R='ladder_level';L='%Y%m%d';K='day';I='dayElePq';r=setup or int(Af.time()*1000)-B.timestamp>B.refresh_interval*3600*1000
|
||||
if r is z:return
|
||||
E=await B.__get_door_number()
|
||||
if C in E and E[C]!=0:
|
||||
A0.warning('刷新 Token');E=await B.__get_request_key()
|
||||
if C in E and E[C]!=0:return
|
||||
E=await B.__refresh_web_token()
|
||||
if C in E and E[C]==0:await B.save_data()
|
||||
else:B.need_login=AW;A0.error('刷新 Token 失败');return
|
||||
E=await B.__get_door_number()
|
||||
if C in E and E[C]!=0:B.need_login=AW;A0.error('重新请求失败');return
|
||||
M=j.datetime.now();J=M-j.timedelta(days=1);u=f"{J.year}-{J.month:02d}-{J.day:02d}";N=J-j.timedelta(days=40);v=f"{N.year}-{N.month:02d}-{N.day:02d}"
|
||||
for A in B.powerUserList:
|
||||
w=A[s];B.doorAccountDict[w]=A;await B.__get_door_balance(A);await B.__get_door_daily_bill(A,M.year,v,u);O=A[Y][0]
|
||||
try:float(O[I])
|
||||
except:A[Y].pop(0)
|
||||
O=A[Y][0];F=j.datetime.strptime(O[K],L);U=0;V=0;W=0;X=0;Z=0
|
||||
for D in A[Y]:
|
||||
H=j.datetime.strptime(D[K],L)
|
||||
if H.month!=F.month:break
|
||||
U+=P(D,I);V+=P(D,c);W+=P(D,d);X+=P(D,e);Z+=P(D,f)
|
||||
Q=F-j.timedelta(days=F.day);a=f"{Q.year}-{Q.month:02d}"
|
||||
if Ae not in A or A[Ae]!=a:await B.__get_door_bill(A,Q.year);await B.__get_door_ladder(A,a)
|
||||
x=j.datetime.strptime(A[Ae],'%Y%m')
|
||||
if x.month==12:
|
||||
G=0
|
||||
for D in A[Y]:
|
||||
H=j.datetime.strptime(D[K],L)
|
||||
if H.month!=12:break
|
||||
G+=P(D,I)
|
||||
async def __get_token(B):
|
||||
A=await B.__get_request_key()
|
||||
if _B in A and A[_B]!=0:return A
|
||||
A=await B.__get_request_authorize()
|
||||
if _B in A and A[_B]!=0:return A
|
||||
A=await B.__get_web_token()
|
||||
if _B in A and A[_B]!=0:return A
|
||||
A=await B.__get_door_number()
|
||||
if _B in A and A[_B]!=0:return A
|
||||
B.need_login=_j;await B.save_data();return{_B:0,_A:B.powerUserList}
|
||||
async def __refresh_token(A):
|
||||
B=await A.__get_request_key()
|
||||
if _B in B and B[_B]!=0:return
|
||||
B=await A.__refresh_web_token()
|
||||
if _B in B and B[_B]==0:A.need_login=_j;await A.save_data()
|
||||
else:A.need_login=_y;LOGGER.error('国家电网刷新 Token 失败')
|
||||
async def refresh_data(C,setup=_j):
|
||||
j='last_month_ele_cost';i='monthEleNum';h='year_ele_cost';g='thisTPq';f='thisNPq';e='thisVPq';d='thisPPq';U=setup;T='ladder_level_num';S='ladder_level';R='last_month_ele_num';Q='year_ele_num';L='%Y%m%d';K='day';I='dayElePq';H='balance'
|
||||
if U is _y:await C.__get_door_number()
|
||||
if C.need_login is _y:LOGGER.error('国家电网需要重新登录!');return
|
||||
k=U or int(time.time()*1000)-C.timestamp>C.refresh_interval*3600*1000
|
||||
if k is _j:return
|
||||
M=datetime.datetime.now();J=M-datetime.timedelta(days=1);l=f"{J.year}-{J.month:02d}-{J.day:02d}";N=J-datetime.timedelta(days=40);m=f"{N.year}-{N.month:02d}-{N.day:02d}"
|
||||
for A in C.powerUserList:
|
||||
n=A[_r];C.doorAccountDict[n]=A;await C.__get_door_balance(A)
|
||||
if _A8 in A:
|
||||
V=catchFloat(A[_A8],'prepayBal');o=catchFloat(A[_A8],'sumMoney')
|
||||
if V==0:A[H]=o
|
||||
else:A[H]=V
|
||||
W=catchFloat(A[_A8],'historyOwe')
|
||||
if W>0:A[H]=-W
|
||||
else:LOGGER.error('国家电网账户余额获取失败!')
|
||||
if H not in A:A[H]=0
|
||||
await C.__get_door_daily_bill(A,M.year,m,l)
|
||||
if _l not in A:LOGGER.error('国家电网无法获取日用电数据!');return
|
||||
O=0
|
||||
for X in range(10):
|
||||
D=A[_l][X]
|
||||
try:float(D[I]);break
|
||||
except:O=O+1
|
||||
for X in range(O):A[_l].pop(0)
|
||||
D=A[_l][0];E=datetime.datetime.strptime(D[K],L);A['daily_ele_num']=catchFloat(D,I);A['daily_p_ele_num']=catchFloat(D,d);A['daily_v_ele_num']=catchFloat(D,e);A['daily_n_ele_num']=catchFloat(D,f);A['daily_t_ele_num']=catchFloat(D,g);Y=0;Z=0;a=0;b=0;c=0
|
||||
for B in A[_l]:
|
||||
G=datetime.datetime.strptime(B[K],L)
|
||||
if G.month!=E.month:break
|
||||
Y+=catchFloat(B,I);Z+=catchFloat(B,d);a+=catchFloat(B,e);b+=catchFloat(B,f);c+=catchFloat(B,g)
|
||||
A['month_ele_num']=normal_round(Y,2);A['month_p_ele_num']=normal_round(Z,2);A['month_v_ele_num']=normal_round(a,2);A['month_n_ele_num']=normal_round(b,2);A['month_t_ele_num']=normal_round(c,2);P=E-datetime.timedelta(days=E.day);p=f"{P.year}-{P.month:02d}"
|
||||
if _s not in A or A[_s][_AR]!=p:await C.__get_door_bill(A,P.year)
|
||||
if _s not in A:LOGGER.error('国家电网无法获取年度用电数据!');return
|
||||
if _AH in A:A[Q]=catchFloat(A[_AH],'totalEleNum');A[h]=catchFloat(A[_AH],'totalEleCost')
|
||||
if Q not in A:A[Q]=0;A[h]=0
|
||||
if _AI in A:A[R]=catchFloat(A[_s],i);A[j]=catchFloat(A[_s],'monthEleCost')
|
||||
if R not in A:A[R]=0;A[j]=0
|
||||
q=datetime.datetime.strptime(A[_s][_AR],'%Y%m')
|
||||
if q.month==12:
|
||||
F=0
|
||||
for B in A[_l]:
|
||||
G=datetime.datetime.strptime(B[K],L)
|
||||
if G.month!=12:break
|
||||
F+=catchFloat(B,I)
|
||||
else:
|
||||
G=0
|
||||
for D in A[AD]:G+=P(D,g)
|
||||
y=t(A[AD])
|
||||
for D in A[Y]:
|
||||
H=j.datetime.strptime(D[K],L)
|
||||
if H.month<=y:break
|
||||
G+=P(D,I)
|
||||
if G<=2760:A[R]='第一阶梯';A[S]=1
|
||||
elif G<=4800:A[R]='第二阶梯';A[S]=2
|
||||
else:A[R]='第三阶梯';A[S]=3
|
||||
if AK in A:
|
||||
A1=P(A[AK],'estiAmt');A2=P(A[AK],'prepayBal');A[T]=A2-A1;b=P(A[AK],'historyOwe')
|
||||
if b>0:A[T]=-b
|
||||
else:A[T]=0
|
||||
if Ad in A:A[h]=P(A[Ad],'totalEleNum');A[i]=P(A[Ad],'totalEleCost')
|
||||
else:A[h]=0;A[i]=0
|
||||
if AD in A:A[k]=P(A[AD][-1],g);A[l]=P(A[AD][-1],'monthEleCost')
|
||||
else:A[k]=0;A[l]=0
|
||||
if Y in A:A[m]=P(A[Y][0],I);A[n]=P(A[Y][0],c);A[o]=P(A[Y][0],d);A[p]=P(A[Y][0],e);A[q]=P(A[Y][0],f)
|
||||
else:A[m]=0;A[n]=0;A[o]=0;A[p]=0;A[q]=0
|
||||
A['month_ele_num']=U;A['month_p_ele_num']=V;A['month_v_ele_num']=W;A['month_n_ele_num']=X;A['month_t_ele_num']=Z;A['daily_lasted_date']=f"{F.year}-{F.month:02d}-{F.day:02d}";A['refresh_time']=j.datetime.strftime(M,'%Y-%m-%d %H:%M:%S')
|
||||
await B.save_data()
|
||||
F=0
|
||||
for B in A[_AI]:F+=catchFloat(B,i)
|
||||
r=len(A[_AI])
|
||||
for B in A[_l]:
|
||||
G=datetime.datetime.strptime(B[K],L)
|
||||
if G.month<=r:break
|
||||
F+=catchFloat(B,I)
|
||||
if F<=2760:A[S]='第一阶梯';A[T]=1
|
||||
elif F<=4800:A[S]='第二阶梯';A[T]=2
|
||||
else:A[S]='第三阶梯';A[T]=3
|
||||
A['daily_lasted_date']=f"{E.year}-{E.month:02d}-{E.day:02d}";A['refresh_time']=datetime.datetime.strftime(M,'%Y-%m-%d %H:%M:%S')
|
||||
await C.save_data()
|
||||
async def get_door_account_list(A):return list(A.doorAccountDict.values())
|
||||
def get_door_account(A):return A.doorAccountDict
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "国家电网",
|
||||
"codeowners": ["@hassbox"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://github.com/hass-box/state-grid",
|
||||
"documentation": "https://hassbox.cn/",
|
||||
"iot_class": "cloud_polling",
|
||||
"version": "0.0.4"
|
||||
"version": "0.1.0"
|
||||
}
|
||||
|
||||
@@ -2,13 +2,11 @@ from homeassistant.components.sensor import (
|
||||
DOMAIN as SENSOR_DOMAIN,
|
||||
SensorDeviceClass,
|
||||
SensorEntity,
|
||||
SensorEntityDescription,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import UnitOfEnergy
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceEntryType
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
@@ -18,132 +16,118 @@ from .const import DOMAIN, VERSION
|
||||
from .data_client import StateGridDataClient
|
||||
from .coordinator import StateGridCoordinator
|
||||
|
||||
CURRENCY_YUAN = "元"
|
||||
UNIT_DU = "度"
|
||||
UNIT_YUAN = "元"
|
||||
|
||||
ENTITY_ID_SENSOR_FORMAT = SENSOR_DOMAIN + ".state_grid_"
|
||||
|
||||
SENSOR_TYPES = (
|
||||
SensorEntityDescription(
|
||||
key="balance",
|
||||
translation_key="balance",
|
||||
native_unit_of_measurement=CURRENCY_YUAN,
|
||||
device_class=SensorDeviceClass.MONETARY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="year_ele_num",
|
||||
translation_key="year_ele_num",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="year_ele_cost",
|
||||
translation_key="year_ele_cost",
|
||||
native_unit_of_measurement=CURRENCY_YUAN,
|
||||
device_class=SensorDeviceClass.MONETARY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="last_month_ele_num",
|
||||
translation_key="last_month_ele_num",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="last_month_ele_cost",
|
||||
translation_key="last_month_ele_cost",
|
||||
native_unit_of_measurement=CURRENCY_YUAN,
|
||||
device_class=SensorDeviceClass.MONETARY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="month_ele_num",
|
||||
translation_key="month_ele_num",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="month_p_ele_num",
|
||||
translation_key="month_p_ele_num",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="month_v_ele_num",
|
||||
translation_key="month_v_ele_num",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="month_n_ele_num",
|
||||
translation_key="month_n_ele_num",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="month_t_ele_num",
|
||||
translation_key="month_t_ele_num",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="daily_ele_num",
|
||||
translation_key="daily_ele_num",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="daily_p_ele_num",
|
||||
translation_key="daily_p_ele_num",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="daily_v_ele_num",
|
||||
translation_key="daily_v_ele_num",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="daily_n_ele_num",
|
||||
translation_key="daily_n_ele_num",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="daily_t_ele_num",
|
||||
translation_key="daily_t_ele_num",
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="daily_lasted_date",
|
||||
translation_key="daily_lasted_date"
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="refresh_time",
|
||||
translation_key="refresh_time"
|
||||
)
|
||||
)
|
||||
SENSOR_TYPES = [
|
||||
{
|
||||
"key":"balance",
|
||||
"name": "账户余额",
|
||||
"unit_of_measurement": UNIT_YUAN,
|
||||
"native_unit_of_measurement": UNIT_YUAN
|
||||
},
|
||||
{
|
||||
"key": "year_ele_num",
|
||||
"name": "年度累计用电",
|
||||
"unit_of_measurement": UNIT_DU,
|
||||
"native_unit_of_measurement": UNIT_DU
|
||||
},
|
||||
{
|
||||
"key": "year_ele_cost",
|
||||
"name": "年度累计电费",
|
||||
"unit_of_measurement": UNIT_YUAN,
|
||||
"native_unit_of_measurement": UNIT_YUAN
|
||||
},
|
||||
{
|
||||
"key": "last_month_ele_num",
|
||||
"name": "上个月用电",
|
||||
"unit_of_measurement": UNIT_DU,
|
||||
"native_unit_of_measurement": UNIT_DU
|
||||
},
|
||||
{
|
||||
"key": "last_month_ele_cost",
|
||||
"name": "上个月电费",
|
||||
"unit_of_measurement": UNIT_YUAN,
|
||||
"native_unit_of_measurement": UNIT_YUAN
|
||||
},
|
||||
{
|
||||
"key": "month_ele_num",
|
||||
"name": "当月累计用电",
|
||||
"unit_of_measurement": UNIT_DU,
|
||||
"native_unit_of_measurement": UNIT_DU
|
||||
},
|
||||
{
|
||||
"key": "month_p_ele_num",
|
||||
"name": "当月累计峰用电",
|
||||
"unit_of_measurement": UNIT_DU,
|
||||
"native_unit_of_measurement": UNIT_DU
|
||||
},
|
||||
{
|
||||
"key": "month_v_ele_num",
|
||||
"name": "当月累计谷用电",
|
||||
"unit_of_measurement": UNIT_DU,
|
||||
"native_unit_of_measurement": UNIT_DU
|
||||
},
|
||||
{
|
||||
"key": "month_n_ele_num",
|
||||
"name": "当月累计平用电",
|
||||
"unit_of_measurement": UNIT_DU,
|
||||
"native_unit_of_measurement": UNIT_DU
|
||||
},
|
||||
{
|
||||
"key": "month_t_ele_num",
|
||||
"name": "当月累计尖用电",
|
||||
"unit_of_measurement": UNIT_DU,
|
||||
"native_unit_of_measurement": UNIT_DU
|
||||
},
|
||||
{
|
||||
"key": "daily_ele_num",
|
||||
"name": "日总用电",
|
||||
"unit_of_measurement": UNIT_DU,
|
||||
"native_unit_of_measurement": UNIT_DU
|
||||
},
|
||||
{
|
||||
"key": "daily_p_ele_num",
|
||||
"name": "日峰用电",
|
||||
"unit_of_measurement": UNIT_DU,
|
||||
"native_unit_of_measurement": UNIT_DU
|
||||
},
|
||||
{
|
||||
"key": "daily_v_ele_num",
|
||||
"name": "日谷用电",
|
||||
"unit_of_measurement": UNIT_DU,
|
||||
"native_unit_of_measurement": UNIT_DU
|
||||
},
|
||||
{
|
||||
"key": "daily_n_ele_num",
|
||||
"name": "日平用电",
|
||||
"unit_of_measurement": UNIT_DU,
|
||||
"native_unit_of_measurement": UNIT_DU
|
||||
},
|
||||
{
|
||||
"key": "daily_t_ele_num",
|
||||
"name": "日尖用电",
|
||||
"unit_of_measurement": UNIT_DU,
|
||||
"native_unit_of_measurement": UNIT_DU
|
||||
},
|
||||
{
|
||||
"key": "daily_lasted_date",
|
||||
"name": "日最新用电日期"
|
||||
},
|
||||
{
|
||||
"key": "refresh_time",
|
||||
"name": "最近刷新时间"
|
||||
}
|
||||
]
|
||||
|
||||
SENSOR_TYPES_FOR_LADDER = (
|
||||
SensorEntityDescription(
|
||||
key="ladder_level",
|
||||
translation_key="ladder_level"
|
||||
),
|
||||
)
|
||||
SENSOR_TYPES_FOR_LADDER = [
|
||||
{
|
||||
"key": "ladder_level",
|
||||
"name": "当前阶梯"
|
||||
},
|
||||
]
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
@@ -154,39 +138,42 @@ async def async_setup_entry(
|
||||
door_account_list = await data_client.get_door_account_list()
|
||||
for door_account in door_account_list:
|
||||
async_add_entities(
|
||||
[StateGridSensor(door_account, description, entry.entry_id, coordinator) for description in SENSOR_TYPES]
|
||||
[StateGridSensor(door_account, sensor_type, entry.entry_id, coordinator) for sensor_type in SENSOR_TYPES]
|
||||
)
|
||||
# if door_account["ladder_flag"] == 1:
|
||||
# async_add_entities(
|
||||
# StateGridSensor(door_account, description, entry.entry_id)
|
||||
# for description in SENSOR_TYPES_FOR_LADDER
|
||||
# StateGridSensor(door_account, sensor_type, entry.entry_id)
|
||||
# for sensor_type in SENSOR_TYPES_FOR_LADDER
|
||||
# )
|
||||
|
||||
class StateGridSensor(CoordinatorEntity[StateGridCoordinator], SensorEntity):
|
||||
|
||||
_attr_has_entity_name = True
|
||||
entity_description: SensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self, door_account, entity_description: SensorEntityDescription, entry_id: str, coordinator: StateGridCoordinator,
|
||||
self, door_account, sensor_type, entry_id: str, coordinator: StateGridCoordinator,
|
||||
) -> None:
|
||||
super().__init__(coordinator)
|
||||
self.entity_description = entity_description
|
||||
self.door_account = door_account
|
||||
self.entity_id = SENSOR_DOMAIN + ".state_grid" + "_" + door_account["consNo_dst"] + "_" + entity_description.key
|
||||
self._attr_translation_key = entity_description.key
|
||||
self._attr_unique_id = entry_id + "-" + door_account["consNo_dst"] + "-" + entity_description.key
|
||||
self.sensor_type = sensor_type
|
||||
self.entity_id = SENSOR_DOMAIN + ".state_grid" + "_" + door_account["consNo_dst"] + "_" + sensor_type["key"]
|
||||
self._attr_name = sensor_type["name"]
|
||||
self._attr_unique_id = entry_id + "-" + door_account["consNo_dst"] + "-" + sensor_type["key"]
|
||||
|
||||
|
||||
if "native_unit_of_measurement" in sensor_type:
|
||||
self._attr_native_unit_of_measurement = sensor_type["native_unit_of_measurement"]
|
||||
|
||||
self._attr_device_info = {
|
||||
"name": door_account["elecAddr_dst"],
|
||||
"identifiers": {(DOMAIN, door_account["consNo_dst"])},
|
||||
"sw_version": VERSION,
|
||||
"manufacturer": "HassBox",
|
||||
"model": "户号:" + door_account["consName_dst"] + " - " + door_account["consNo_dst"],
|
||||
"entry_type": DeviceEntryType.SERVICE,
|
||||
"model": "户号:" + door_account["consName_dst"] + " - " + door_account["consNo_dst"]
|
||||
}
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
data = self.coordinator.data[self.door_account["consNo_dst"]]
|
||||
return data[self.entity_description.key]
|
||||
|
||||
return data[self.sensor_type["key"]]
|
||||
|
||||
@@ -70,63 +70,5 @@
|
||||
"get_qr_code_error": "{errmsg}",
|
||||
"check_qr_code_error": "{errmsg}"
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
"sensor": {
|
||||
"balance": {
|
||||
"name": "账户余额"
|
||||
},
|
||||
"year_ele_num": {
|
||||
"name": "年度累计用电"
|
||||
},
|
||||
"year_ele_cost": {
|
||||
"name": "年度累计电费"
|
||||
},
|
||||
"last_month_ele_num": {
|
||||
"name": "上个月用电"
|
||||
},
|
||||
"last_month_ele_cost": {
|
||||
"name": "上个月电费"
|
||||
},
|
||||
"month_ele_num": {
|
||||
"name": "当月累计用电"
|
||||
},
|
||||
"month_p_ele_num": {
|
||||
"name": "当月累计峰用电"
|
||||
},
|
||||
"month_v_ele_num": {
|
||||
"name": "当月累计谷用电"
|
||||
},
|
||||
"month_n_ele_num": {
|
||||
"name": "当月累计平用电"
|
||||
},
|
||||
"month_t_ele_num": {
|
||||
"name": "当月累计尖用电"
|
||||
},
|
||||
"daily_ele_num": {
|
||||
"name": "日总用电"
|
||||
},
|
||||
"daily_p_ele_num": {
|
||||
"name": "日峰用电"
|
||||
},
|
||||
"daily_v_ele_num": {
|
||||
"name": "日谷用电"
|
||||
},
|
||||
"daily_n_ele_num": {
|
||||
"name": "日平用电"
|
||||
},
|
||||
"daily_t_ele_num": {
|
||||
"name": "日尖用电"
|
||||
},
|
||||
"daily_lasted_date": {
|
||||
"name": "最新日用电日期"
|
||||
},
|
||||
"ladder_level": {
|
||||
"name": "当前阶梯"
|
||||
},
|
||||
"refresh_time": {
|
||||
"name": "最近刷新时间"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "国家电网",
|
||||
"step": {
|
||||
"user": {
|
||||
"title": "国家电网",
|
||||
"description": "集成国家电网可以选择网上国网 App 扫码登录或短信验证码登录。如登录异常,可至 **HassBox全屋智能** 微信公众号联系客服。"
|
||||
},
|
||||
"code_login": {
|
||||
"title": "短信验证码登录",
|
||||
"description": "手机号需先在网上电网 App 注册并绑定户号",
|
||||
"data": {
|
||||
"phone": "请输入手机号"
|
||||
}
|
||||
},
|
||||
"verfiy_code": {
|
||||
"title": "短信验证码登录",
|
||||
"data": {
|
||||
"code": "请输入验证码"
|
||||
}
|
||||
},
|
||||
"check_qr_code": {
|
||||
"title": "网上国网 App 扫码登录",
|
||||
"description": "\n {qr_image} \n\n\n 请使用 网上国网 App 扫码登录,确认登录后再点击提交。"
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"single_instance_allowed": "该集成已经配置过了,且只能配置一次。若要重新配置,请先删除旧集成。",
|
||||
"get_qr_code_error": "{errmsg}",
|
||||
"check_qr_code_error": "{errmsg}"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"debug": {
|
||||
"title": "国家电网",
|
||||
"description": "国家电网当日用电等数据一般隔天才会刷新,且各地区时间不一,可根据情况适当调整接口轮询间隔。",
|
||||
"data": {
|
||||
"refresh_interval": "轮询间隔",
|
||||
"is_debug": "调试模式"
|
||||
},
|
||||
"data_description": {
|
||||
"is_debug": "打开调试开关后,将会打印所有请求日志。可在[配置]-[系统]-[日志]中查看。\n如需反馈异常,可至 **HassBox全屋智能** 微信公众号联系客服。"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"title": "重新登录国家电网",
|
||||
"description": "刷新 Token 异常,需重新登录。\n如需反馈异常,可至 **HassBox全屋智能** 微信公众号联系客服。"
|
||||
},
|
||||
"code_login": {
|
||||
"title": "短信验证码登录",
|
||||
"description": "手机号需先在网上电网 App 注册并绑定户号",
|
||||
"data": {
|
||||
"phone": "请输入手机号"
|
||||
}
|
||||
},
|
||||
"verfiy_code": {
|
||||
"title": "短信验证码登录",
|
||||
"data": {
|
||||
"code": "请输入验证码"
|
||||
}
|
||||
},
|
||||
"check_qr_code": {
|
||||
"title": "网上国网 App 扫码登录",
|
||||
"description": "\n {qr_image} \n\n\n 请使用 网上国网 App 扫码登录,确认登录后再点击提交。"
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"single_instance_allowed": "该集成已经配置过了,且只能配置一次。若要重新配置,请先删除旧集成。",
|
||||
"get_qr_code_error": "{errmsg}",
|
||||
"check_qr_code_error": "{errmsg}"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,63 +70,5 @@
|
||||
"get_qr_code_error": "{errmsg}",
|
||||
"check_qr_code_error": "{errmsg}"
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
"sensor": {
|
||||
"balance": {
|
||||
"name": "账户余额"
|
||||
},
|
||||
"year_ele_num": {
|
||||
"name": "年度累计用电"
|
||||
},
|
||||
"year_ele_cost": {
|
||||
"name": "年度累计电费"
|
||||
},
|
||||
"last_month_ele_num": {
|
||||
"name": "上个月用电"
|
||||
},
|
||||
"last_month_ele_cost": {
|
||||
"name": "上个月电费"
|
||||
},
|
||||
"month_ele_num": {
|
||||
"name": "当月累计用电"
|
||||
},
|
||||
"month_p_ele_num": {
|
||||
"name": "当月累计峰用电"
|
||||
},
|
||||
"month_v_ele_num": {
|
||||
"name": "当月累计谷用电"
|
||||
},
|
||||
"month_n_ele_num": {
|
||||
"name": "当月累计平用电"
|
||||
},
|
||||
"month_t_ele_num": {
|
||||
"name": "当月累计尖用电"
|
||||
},
|
||||
"daily_ele_num": {
|
||||
"name": "日总用电"
|
||||
},
|
||||
"daily_p_ele_num": {
|
||||
"name": "日峰用电"
|
||||
},
|
||||
"daily_v_ele_num": {
|
||||
"name": "日谷用电"
|
||||
},
|
||||
"daily_n_ele_num": {
|
||||
"name": "日平用电"
|
||||
},
|
||||
"daily_t_ele_num": {
|
||||
"name": "日尖用电"
|
||||
},
|
||||
"daily_lasted_date": {
|
||||
"name": "最新日用电日期"
|
||||
},
|
||||
"ladder_level": {
|
||||
"name": "当前阶梯"
|
||||
},
|
||||
"refresh_time": {
|
||||
"name": "最近刷新时间"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 41 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 100 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 77 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 180 KiB |
Reference in New Issue
Block a user