就是简单Mark一下,最近电费感觉略微有点异常,于是写了各监控看看电量情况。
对于电费啥水平,看两天我再回来写写。
电量获取 你OUC电量有这么个网页:http://10.128.13.25/expensesManager/feeManager/searchPower.jsp
上面的电量更新比较及时,比海大e卡通上面的及时。
通过抓包,可以发现接口http://10.128.13.25/feemanager/findSurplusElectricByMeterSearchPower.action
进行POST请求,再携带上我们的电费id即可,这里写了一段代码用来获取,由于有时候获取会失败,加了5次重试。
import requestsdef get_df (code ): url = "http://10.128.13.25/feemanager/findSurplusElectricByMeterSearchPower.action" i = 0 while i < 5 : response = requests.request( "POST" , url, data={"equipmentInfoId" : "10.150.132.63#" + code} ).json() i += 1 print (response) if response.get('equipmentList' ): break equipmentList = response['equipmentList' ] return { 'surplus' : float (equipmentList['roomSurplusBuyElecNum' ]), 'give' : float (equipmentList['roomSurplusGiveElecNum' ]), 'total' : float (equipmentList['roomSurplusBuyElecNum' ]) + float (equipmentList['roomSurplusGiveElecNum' ]), 'voltage' : equipmentList['line1Voltage' ], 'electricity' : equipmentList['line1Electricity' ], }
记录数据到数据库 光获取还不行,那肯定得把数据写入数据库吧,选择MyQql数据库,于是找了一个简单的ORM框架peewee,u1s1还确实挺好用的。
没有啥特殊的,记个电量,记个时间就行。
from peewee import *import datetimedb = MySQLDatabase('dianfei' , host="localhost" , user='root' , passwd='123456' , port=3306 ) class ChaZuo (Model ): charge = DecimalField() time = DateTimeField() class Meta : database = db class KongTiao (Model ): charge = DecimalField() time = DateTimeField() class Meta : database = db response = get_df('' ) print ('插座: ' , response)ChaZuo.create(charge=response['total' ], time=datetime.datetime.now()) response = get_df('' ) print ('空调: ' ,response)KongTiao.create(charge=response['total' ], time=datetime.datetime.now())
然后看自己情况,每隔一段时间跑一下脚本就行,我10分钟跑一次。写个cron就是
*/10 * * * * python dianfei.py
可视化 本来想着做个前后端分离,或者直接拿一个Web框架模板渲染得了,等等,又得写前端,nonono。
这玩意我就图一乐,写那么多代码干嘛,于是搜搜有没有什么现成的低代码Web框架,然后搜到了Streamlit,总体感觉还行,就是手机端交互有点差,凑活着用吧。
import streamlit as stimport pandas as pdimport altair as altfrom peewee import MySQLDatabase, Model, DecimalField, DateTimeFieldfrom playhouse.shortcuts import model_to_dictdb = MySQLDatabase('dianfei' , host="192.168.1.190" , user='root' , passwd='123456' , port=3306 ) class ChaZuo (Model ): charge = DecimalField() time = DateTimeField() class Meta : database = db class KongTiao (Model ): charge = DecimalField() time = DateTimeField() class Meta : database = db def get_data (model ): query = model.select() data = pd.DataFrame(list (map (model_to_dict, query))) data['time' ] = pd.to_datetime(data['time' ]) return data def web (title='插座' , model=ChaZuo ): data = get_data(model) data.set_index('time' , inplace=True ) st.markdown(f"### {title} 耗电" ) time_interval = st.selectbox( "选择时间间隔" , ["10分钟" , "半小时" , "小时" , "天" ], index=0 , key=title ) if time_interval == "10分钟" : resampled_data = data.resample("10T" ).last() elif time_interval == "半小时" : resampled_data = data.resample("30T" ).last() elif time_interval == "天" : resampled_data = data.resample("D" ).last() else : resampled_data = data.resample("H" ).last() resampled_data['charge_diff' ] = resampled_data['charge' ].diff().fillna(resampled_data['charge' ]).abs () resampled_data['charge_diff' ] = resampled_data['charge_diff' ].astype(float ) resampled_data = resampled_data.reset_index() x_format = "%m-%d %H:%M" line_chart = alt.Chart(resampled_data[1 :]).mark_line(point=True ).encode( x=alt.X("time:T" ,timeUnit='monthdatehoursminutes' , axis=alt.Axis(format =x_format), title="时间" ), y=alt.Y("charge_diff:Q" , axis=alt.Axis(format =".3f" ), title="使用电费" ), tooltip=[alt.Tooltip("time:T" ,timeUnit='monthdatehoursminutes' , title="时间" , format =x_format), alt.Tooltip("charge_diff:Q" , format =".3f" , title="使用电费" )] ).interactive() st.altair_chart(line_chart, use_container_width=True ) web('插座' , ChaZuo) web('空调' , KongTiao)
直接运行一个streamlit run dianfei_web.py
就跑起来了,访问localhost:8501
就可以看到结果了。
还凑活吧,代码都是ai写的,确实比我自己写前端快。
不过也学到不少,pandas确实强大,diff和resample用的恰到好处,要我自己写的话,估计得捣鼓一阵子了,还是得善于用一些现代的工具啊。
电费水平 目前母鸡,等我过两天观察观察。