Skip to content

Commit

Permalink
add month data
Browse files Browse the repository at this point in the history
  • Loading branch information
ARC-MX committed May 14, 2024
1 parent 009cd2a commit 3830135
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 19 deletions.
45 changes: 39 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

<p align="center">
<img src="assets/image-20230730135540291.png" alt="mini-graph-card" width="400">
<img src="assets/image-20240514.jpg" alt="mini-graph-card" width="400">
</p>

本应用可以帮助你将国网的电费、用电量数据接入homeassistant,实现实时追踪家庭用电量情况;并且可以将每日用电量保存到数据库,历史有迹可循。具体提供两类数据:
Expand All @@ -20,6 +21,8 @@
| sensor.electricity_charge_balance | 预付费显示电费余额,反之显示上月应交电费,单位元 |
| sensor.yearly_electricity_usage | 今年总用电量,单位KWH、度。 |
| sensor.yearly_electricity_charge | 今年总用电费用,单位元 |
| sensor.month_electricity_usage | 最近一天用电量,单位KWH、度。属性含present_date(查询电量代表的日期)|
| sensor.month_electricity_charge | 上月总用电费用,单位元 属性含present_date(查询电量代表的日期)| |
2. 可选,近三十天每日用电量数据(mongodb数据库),例如:

![image-20230731094609016](assets/image-20230731111508970.png)
Expand Down Expand Up @@ -162,7 +165,7 @@

```bash
git clone https://github.com/ARC-MX/sgcc_electricity_new.git
cd sgcc_electricity
cd sgcc_electricity_new
```
2. 参考example.env编写.env文件

Expand All @@ -180,7 +183,7 @@

### 3)方法三:不安装docker,安装python环境后直接运行:

克隆仓库之后,参考Dockerfile的命令,`<u>`自行配置安装chrome浏览器和selenium浏览器驱动`</u>`,安装mongodb,将example.env文件复制为.env文件到scripts文件夹下,然后运行main.py文件。
克隆仓库之后,参考Dockerfile的命令,`<u>`自行配置安装chrome浏览器和selenium浏览器驱动 `</u>`,安装mongodb,将example.env文件复制为.env文件到scripts文件夹下,然后运行main.py文件。

### 4)方法四:使用可视化docker管理工具[portainer]([url](https://www.portainer.io/))部署:

Expand All @@ -198,7 +201,6 @@

- 如果你有一个户号,参照以下配置:

```yaml
# Example configuration.yaml entry
# 文件中只能有一个template
template:
Expand All @@ -215,7 +217,7 @@ template:
state_class: total
unit_of_measurement: "CNY"
device_class: monetary

- trigger:
- platform: event
event_type: "state_changed"
Expand All @@ -231,7 +233,39 @@ template:
state_class: measurement
unit_of_measurement: "kWh"
device_class: energy


- trigger:
- platform: event
event_type: "state_changed"
event_data:
entity_id: sensor.month_electricity_usage
sensor:
- name: month_electricity_usage_entity
unique_id: month_electricity_usage_entity
state: "{{ states('sensor.month_electricity_usage') }}"
attributes:
present_date: "{{ state_attr('sensor.month_electricity_usage', 'present_date') }}"
last_updated: "{{ state_attr('sensor.month_electricity_usage', 'month_updated') }}"
state_class: measurement
unit_of_measurement: "kWh"
device_class: energy

- trigger:
- platform: event
event_type: "state_changed"
event_data:
entity_id: sensor.month_electricity_charge
sensor:
- name: month_electricity_charge_entity
unique_id: month_electricity_charge_entity
state: "{{ states('sensor.month_electricity_charge') }}"
attributes:
present_date: "{{ state_attr('sensor.month_electricity_charge', 'present_date') }}"
last_updated: "{{ state_attr('sensor.month_electricity_charge', 'month_updated') }}"
state_class: measurement
unit_of_measurement: "CNY"
device_class: monetary

- trigger:
- platform: event
event_type: "state_changed"
Expand All @@ -257,7 +291,6 @@ template:
state_class: total
unit_of_measurement: "CNY"
device_class: monetary
```

- 如果你有多个户号,每个户号参照[configuration.yaml](template/configuration.yaml)配置。

Expand Down
Binary file added assets/image-20240514.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion scripts/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
BALANCE_SENSOR_NAME = "sensor.electricity_charge_balance"
DAILY_USAGE_SENSOR_NAME = "sensor.last_electricity_usage"
YEARLY_USAGE_SENSOR_NAME = "sensor.yearly_electricity_usage"
YEARLY_CHARGE_SENESOR_NAME = "sensor.yearly_electricity_charge"
YEARLY_CHARGE_SENSOR_NAME = "sensor.yearly_electricity_charge"
MONTH_USAGE_SENSOR_NAME = "sensor.month_electricity_usage"
MONTH_CHARGE_SENSOR_NAME = "sensor.month_electricity_charge"
BALANCE_UNIT = "CNY"
USAGE_UNIT = "KWH"

46 changes: 42 additions & 4 deletions scripts/data_fetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,13 @@ def _fetch(self):
balance_list = self._get_electric_balances(driver, user_id_list) #
time.sleep(self.RETRY_WAIT_TIME_OFFSET_UNIT)
### get data except electricity charge balance
last_daily_date_list, last_daily_usage_list, yearly_charge_list, yearly_usage_list = self._get_other_data(driver, user_id_list)
last_daily_date_list, last_daily_usage_list, yearly_charge_list, yearly_usage_list, month_list, month_usage_list, month_charge_list = self._get_other_data(driver, user_id_list)
time.sleep(self.RETRY_WAIT_TIME_OFFSET_UNIT)
driver.quit()

logging.info("Webdriver quit after fetching data successfully.")
logging.info("浏览器已退出")
return user_id_list, balance_list, last_daily_date_list, last_daily_usage_list, yearly_charge_list, yearly_usage_list
return user_id_list, balance_list, last_daily_date_list, last_daily_usage_list, yearly_charge_list, yearly_usage_list, month_list, month_usage_list, month_charge_list

finally:
driver.quit()
Expand Down Expand Up @@ -380,7 +380,9 @@ def _get_other_data(self, driver, user_id_list):
last_daily_usage_list = []
yearly_usage_list = []
yearly_charge_list = []

month_list = []
month_charge_list = []
month_usage_list = []
# swithc to electricity usage page
driver.get(ELECTRIC_USAGE_URL)

Expand All @@ -400,6 +402,14 @@ def _get_other_data(self, driver, user_id_list):
logging.info(
f"Get year power charge for {user_id_list[i - 1]} successfully, yealrly charge is {yearly_charge} CNY")

# get month usage
month, month_usage, month_charge = self._get_month_usage(driver)
if month is None:
logging.error(f"Get month power usage for {user_id_list[i - 1]} failed, pass")
else:
for m in range(len(month)):
logging.info(
f"Get month power charge for {user_id_list[i - 1]} successfully, {month[m]} usage is {month_usage[m]} KWh, charge is {month_charge[m]} CNY.")
# get yesterday usage
last_daily_datetime, last_daily_usage = self._get_yesterday_usage(driver)

Expand All @@ -417,6 +427,9 @@ def _get_other_data(self, driver, user_id_list):
last_daily_usage_list.append(last_daily_usage)
yearly_charge_list.append(yearly_charge)
yearly_usage_list.append(yearly_usage)
month_list.append(month[-1])
month_charge_list.append(month_charge[-1])
month_usage_list.append(month_usage[-1])

# switch to next user id
if i != len(user_id_list):
Expand All @@ -425,7 +438,7 @@ def _get_other_data(self, driver, user_id_list):
self._click_button(driver, By.XPATH,
f"//body/div[@class='el-select-dropdown el-popper']//ul[@class='el-scrollbar__view el-select-dropdown__list']/li[{i + 1}]")

return last_daily_date_list, last_daily_usage_list, yearly_charge_list, yearly_usage_list
return last_daily_date_list, last_daily_usage_list, yearly_charge_list, yearly_usage_list, month_list, month_usage_list, month_charge_list

def _get_user_ids(self, driver):

Expand Down Expand Up @@ -496,6 +509,31 @@ def _get_yesterday_usage(self, driver):
except:
return None

def _get_month_usage(self, driver):
"""获取每月用电量"""

try:
self._click_button(driver, By.XPATH, "//div[@class='el-tabs__nav is-top']/div[@id='tab-first']")
time.sleep(self.RETRY_WAIT_TIME_OFFSET_UNIT)
# wait for month displayed
target = driver.find_element(By.CLASS_NAME, "total")
WebDriverWait(driver, self.DRIVER_IMPLICITY_WAIT_TIME).until(EC.visibility_of(target))
month_element = driver.find_element(By.XPATH, "//*[@id='pane-first']/div[1]/div[2]/div[2]/div/div[3]/table/tbody").text
month_element = month_element.split("\n")
month_element.remove("MAX")
month_element = np.array(month_element).reshape(-1, 3)
# 将每月的用电量保存为List
month = []
usage = []
charge = []
for i in range(len(month_element)):
month.append(month_element[i][0])
usage.append(month_element[i][1])
charge.append(month_element[i][2])
return month, usage, charge
except:
return None,None,None

# 增加储存30天用电量的到mongodb的函数
def save_30_days_usage(self, driver, user_id):
"""储存30天用电量"""
Expand Down
14 changes: 8 additions & 6 deletions scripts/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,22 @@ def main():

def run_task(data_fetcher: DataFetcher, sensor_updator: SensorUpdator):
try:
user_id_list, balance_list, last_daily_date_list, last_daily_usage_list, yearly_charge_list, yearly_usage_list = data_fetcher.fetch()

user_id_list, balance_list, last_daily_date_list, last_daily_usage_list, yearly_charge_list, yearly_usage_list, month_list, month_usage_list, month_charge_list = data_fetcher.fetch()
# user_id_list, balance_list, last_daily_date_list, last_daily_usage_list, yearly_charge_list, yearly_usage_list, month_list, month_usage_list, month_charge_list = ['123456'],[58.1],['2024-05-12'],[3.0],['239.1'],['533'],['2024-04-01-2024-04-30'],['118'],['52.93']
for i in range(0, len(user_id_list)):
profix = f"_{user_id_list[i]}" if len(user_id_list) > 1 else ""
if balance_list[i] is not None:
sensor_updator.update(BALANCE_SENSOR_NAME + profix, None, balance_list[i], BALANCE_UNIT)
if last_daily_usage_list[i] is not None:
sensor_updator.update(DAILY_USAGE_SENSOR_NAME + profix, last_daily_date_list[i],
last_daily_usage_list[i], USAGE_UNIT)
sensor_updator.update(DAILY_USAGE_SENSOR_NAME + profix, last_daily_date_list[i], last_daily_usage_list[i], USAGE_UNIT)
if yearly_usage_list[i] is not None:
sensor_updator.update(YEARLY_USAGE_SENSOR_NAME + profix, None, yearly_usage_list[i], USAGE_UNIT)
if yearly_charge_list[i] is not None:
sensor_updator.update(YEARLY_CHARGE_SENESOR_NAME + profix, None, yearly_charge_list[i], BALANCE_UNIT)

sensor_updator.update(YEARLY_CHARGE_SENSOR_NAME + profix, None, yearly_charge_list[i], BALANCE_UNIT)
if month_charge_list[i] is not None:
sensor_updator.update(MONTH_CHARGE_SENSOR_NAME + profix, month_list[i], month_charge_list[i], BALANCE_UNIT, month=True)
if month_usage_list[i] is not None:
sensor_updator.update(MONTH_USAGE_SENSOR_NAME + profix, month_list[i], month_usage_list[i], USAGE_UNIT, month=True)
logging.info("state-refresh task run successfully!")
except Exception as e:
logging.error(f"state-refresh task failed, reason is {e}")
Expand Down
7 changes: 5 additions & 2 deletions scripts/sensor_updator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def __init__(self, base_url: str, token: str):
self.base_url = base_url[:-1] if base_url.endswith("/") else base_url
self.token = token

def update(self, sensorName: str, present_date: str or None, sensorState: float, sensorUnit: str):
def update(self, sensorName: str, present_date: str or None, sensorState: float, sensorUnit: str, month=False):
"""
Update the sensor state
:param sensorName: 此为id,不是name
Expand All @@ -28,7 +28,10 @@ def update(self, sensorName: str, present_date: str or None, sensorState: float,
"Authorization": "Bearer " + token

}
last_updated = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f%z")
if month:
last_updated = datetime.now().strftime("%Y-%m")
else:
last_updated = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f%z")
if present_date:
request_body = {
"state": sensorState,
Expand Down

0 comments on commit 3830135

Please sign in to comment.