homeassistant获取电费余额2.0

2024-03-01 3,270 28

前言

之前用的大佬的docker也是模拟操作去获取余额元素然后生成ha的实体,获取电网时添加了滑动验证码,原作者不再继续维护,现有千石酱大佬制作的docker,特此感谢千石酱分享,经过我做了延时的优化,目前已稳定运行2个月,此次部署还是以群晖为例,使用此教程前首先部署nodered(百度一大堆,不再重复撰写),通过nodered get控制容器任务运行,抓取余额数值生成实体

docker镜像

okatuloli-electricity-tr...ker(v0-0-1).syno.tar

https://www.alipan.com/s/vcEsWQuqE4e 提取码: y21t

安装部署

1.导入镜像

1)首先有一台可以运行docker的机器

2)导入以上的docker镜像,群晖可通过docker - 映像 - 新增 - 从文件添加

3)导入成功后完成第一步

2.部署docker

1)首先在docker文件夹创建一个映射文件夹,起名electricity,electricity文件夹内创建文件夹debug,用于测试截图放入,把以下文件复制到文件夹内

Electricity-Tracker-master.zip https://www.alipan.com/s/CUeEvG5274e 提取码: mw88

2)放入后,编辑config.ini文件,username/password账号密码填写自己的,保存即可

3)以群晖为例,导入的镜像双击进行部署

存储空间映射本地文件夹,以下为例

容器端口5000,自己对应端口一个即可,默认5000也可以,不要跟群晖或其他服务冲突

4)部署完毕后运行docker

使用方法

1.强制更新电费(get请求):

http://IP:端口/getelectricity

2.获取最新电费(post请求):

http://IP:端口/electricity

nodered

通过接口2获取到电费信息,自己送到ha也可以,这个不局限于nodered,以上是nodered流程图很简单

json 自行替换局域网请求地址

nodered流

[
{
"id": "38779186405936d7",
"type": "tab",
"label": "电费",
"disabled": false,
"info": "",
"env": []
},
{
"id": "38ef0eaf5cb549ca",
"type": "inject",
"z": "38779186405936d7",
"name": "获取金额传送ha",
"props": [],
"repeat": "",
"crontab": "30 12 * * *",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 330,
"y": 320,
"wires": [
[
"7d0f63506e84a788"
]
]
},
{
"id": "7d0f63506e84a788",
"type": "http request",
"z": "38779186405936d7",
"name": "",
"method": "GET",
"ret": "txt",
"paytoqs": "ignore",
"url": "http://10.0.0.101:5000/electricity",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 500,
"y": 320,
"wires": [
[
"ed8f9e6df1266058"
]
]
},
{
"id": "ed8f9e6df1266058",
"type": "json",
"z": "38779186405936d7",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 690,
"y": 320,
"wires": [
[
"9ec9700618b91aef",
"96790ef81083e8e2"
]
]
},
{
"id": "9ec9700618b91aef",
"type": "debug",
"z": "38779186405936d7",
"name": "debug 1",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload.data.expense",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 920,
"y": 240,
"wires": []
},
{
"id": "96790ef81083e8e2",
"type": "ha-sensor",
"z": "38779186405936d7",
"name": "输出电费",
"entityConfig": "493ba168cb0b5e6f",
"version": 0,
"state": "payload.data.expense",
"stateType": "msg",
"attributes": [
{
"property": "consBal",
"value": "payload.data.expense",
"valueType": "msg"
}
],
"inputOverride": "allow",
"outputProperties": [],
"x": 920,
"y": 420,
"wires": [
[]
]
},
{
"id": "fb93ce1b71aab09d",
"type": "inject",
"z": "38779186405936d7",
"name": "强制更新电费",
"props": [],
"repeat": "",
"crontab": "00 12 * * *",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 320,
"y": 180,
"wires": [
[
"6bbefa8981ab9026"
]
]
},
{
"id": "6bbefa8981ab9026",
"type": "http request",
"z": "38779186405936d7",
"name": "",
"method": "POST",
"ret": "txt",
"paytoqs": "ignore",
"url": "http://10.0.0.101:5000/getelectricity",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 500,
"y": 180,
"wires": [
[]
]
},
{
"id": "493ba168cb0b5e6f",
"type": "ha-entity-config",
"server": "4195dd0343dfc562",
"deviceConfig": "",
"name": "电费",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": ""
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_category",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "device_class",
"value": ""
},
{
"property": "unit_of_measurement",
"value": ""
},
{
"property": "state_class",
"value": ""
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "4195dd0343dfc562",
"type": "server",
"name": "Home Assistant",
"version": 5,
"addon": false,
"rejectUnauthorizedCerts": true,
"ha_boolean": "y|yes|true|on|home|open",
"connectionDelay": true,
"cacheJson": true,
"heartbeat": false,
"heartbeatInterval": "30",
"areaSelector": "friendlyName",
"deviceSelector": "friendlyName",
"entitySelector": "friendlyName",
"statusSeparator": "at: ",
"statusYear": "hidden",
"statusMonth": "short",
"statusDay": "numeric",
"statusHourCycle": "h23",
"statusTimeFormat": "h:m",
"enableGlobalContextStore": true
}
]

常见问题

待完善~

相关文章

homeassistant接入国家电网电费余额(理论已经是支持全国)
docker node-red无法安装节点
群晖搭建Pushdeer消息推送

评论(28)

  1. 不知道为啥群晖DOCKER 镜像导入失败,从本地或者上传到DSM再导入都提示 无法执行此操作

        1. @111 那看来是docker版本的问题 7.2的docker和7.1不一致 直接用ssh拉一下 命令:docker pull okatuloli/electricity-tracker:v0.0.1

      1. @zyx Docker部署完,使用方法网页咋打不开呢,咋样确认我已经部署好可用了。有视频教程么啊,大佬!!

  2. 强制更新电费(get 请求): 提示服务器无反应;
    还有就是 HA中node没有生产实体是怎么回事啊

    1. @ 1.get以后docker回去执行,看docker日志看一下有没有抓有输出日志
      2.node对接ha 先去百度一下怎么创建然后再传余额

  3. root@Docker:~# docker run -it –name=xxxxx -v /opt/docker/electricity-tracker/config.ini:/usr/scr/app/config.ini -v /opt/docker/electricity-tracker/electricity_scraper.py:/usr/scr/app/scraper/electricity_scraper.py -v /opt/docker/electricity-tracker/main.py:/usr/scr/app/main.py -v /opt/docker/electricity-tracker/debug/:/usr/scr/app/debug electricity-tracker /bin/bash
    root@7f57f15b1844:/usr/src/app# ls
    __pycache__ config debug.png main.py requirements.txt
    app.py config.ini.example electricity.db notifier scraper
    为啥映射config.ini文件还是没有呢,文件权限也给了,现在就报找不到配置文件的time参数,也起不来,大神有没有遇到过这种情况呢?

  4. 测了下可以用,不过有时候会定位不到坐标位置,建议在fetch_data增加一个循环,定位不到位置就刷新一下验证码,然后重新定位,稳定性会提高不少 def fetch_data(self): “”” ……. “”” self.loading_slide() self.page.wait_for_selector(‘canvas’) for i in range(5): #增加定位循环 slide_bg_img = self.page.evaluate(“() => document.querySelector(‘canvas’).toDataURL(‘image/png’)”) slide_block_img = self.page.evaluate( “() => document.querySelector(‘.slide-verify-block’).toDataURL(‘image/png’)”) print(“2”) # with open(‘slide_bg_img.png’, ‘wb’) as f: # f.write(base64.b64decode(str(slide_bg_img).split(‘,’)[-1], altchars=None, validate=False)) # with open(‘slide_block_img.png’, ‘wb’) as f: # f.write(base64.b64decode(str(slide_block_img).split(‘,’)[-1], altchars=None, validate=False)) slide_bg_img = sip.base64_to_img(slide_bg_img) slide_block_img = sip.cutting_transparent_block(sip.base64_to_img(slide_block_img), offset=65) Loc = sip.identify_gap(slide_bg_img, slide_block_img) print(“3-“,Loc) if Loc[0] == 0: self.page.screenshot(path=’debug/debug_error_loc_{}.png’.format(i), full_page=True) print(“3-获取坐标有误,重新获取”) # 等待元素加载并可见 self.page.locator(“.slide-verify-refresh-icon”).wait_for(state=”visible”) # 点击刷新验证码 self.page.locator(“.slide-verify-refresh-icon”).click() time.sleep(1) else: print(“3-获取成功”) break

      1. @zyx 另外要把滑动距离+6,现在是打不到位置,差一点,距离公式没研究,就直接加了下

发布评论