diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 1b85129..07476b2 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -1,11 +1,11 @@ -name: Docker Image CI +name: Docker Image Build on: workflow_dispatch: inputs: - username: + version: description: 'version of this branch' - default: 'v1.6.2' + default: 'v1.6.3' required: true type: string paths: @@ -34,11 +34,33 @@ jobs: run: | PLATFORMS=linux/arm64,linux/amd64 DOCKER_IMAGE=arcw/sgcc_electricity - docker buildx build --build-arg VERSION=${{ inputs.username }} --platform $PLATFORMS -t $DOCKER_IMAGE:latest -t $DOCKER_IMAGE:${{ inputs.username }} --file Dockerfile-for-github-action --push . + ARCH_TAGS="arm64 amd64" + VERSION=${{ inputs.version }} + docker buildx build --build-arg VERSION=${VERSION} --platform $PLATFORMS -t $DOCKER_IMAGE:latest -t $DOCKER_IMAGE:${VERSION} --file Dockerfile-for-github-action --push . + + for ARCH in $ARCH_TAGS; do + if [ "$ARCH" == "arm64" ]; then + TAG_ARCH="aarch64" + else + TAG_ARCH=$ARCH + fi + docker buildx build --build-arg VERSION=${VERSION} --platform linux/${ARCH} -t ${DOCKER_IMAGE}-${TAG_ARCH}:latest -t ${DOCKER_IMAGE}-${TAG_ARCH}:${VERSION} -t ${DOCKER_IMAGE}:latest-${ARCH} -t ${DOCKER_IMAGE}:${VERSION}-${ARCH} --file Dockerfile-for-github-action --push . + done - name: Log into Aliyun hub registry and push Docker image run: | echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.ALIYUN_USERNAME }} --password-stdin registry.cn-hangzhou.aliyuncs.com PLATFORMS=linux/arm64,linux/amd64 - DOCKER_IMAGE=registry.cn-hangzhou.aliyuncs.com/arcw/sgcc_electricity - docker buildx build --build-arg VERSION=${{ inputs.username }} --platform $PLATFORMS -t $DOCKER_IMAGE:latest -t $DOCKER_IMAGE:${{ inputs.username }} --file Dockerfile-for-github-action --push . \ No newline at end of file + DOCKER_IMAGE=arcw/sgcc_electricity + ARCH_TAGS="arm64 amd64" + VERSION=${{ inputs.version }} + docker buildx build --build-arg VERSION=${VERSION} --platform $PLATFORMS -t $DOCKER_IMAGE:latest -t $DOCKER_IMAGE:${VERSION} --file Dockerfile-for-github-action --push . + + for ARCH in $ARCH_TAGS; do + if [ "$ARCH" == "arm64" ]; then + TAG_ARCH="aarch64" + else + TAG_ARCH=$ARCH + fi + docker buildx build --build-arg VERSION=${VERSION} --platform linux/${ARCH} -t ${DOCKER_IMAGE}-${TAG_ARCH}:latest -t ${DOCKER_IMAGE}-${TAG_ARCH}:${VERSION} -t ${DOCKER_IMAGE}:latest-${ARCH} -t ${DOCKER_IMAGE}:${VERSION}-${ARCH} --file Dockerfile-for-github-action --push . + done \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 11f6e0c..71b9ae0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,9 @@ -FROM arcw/sgcc_electricity:latest +ARG BUILD_FROM +FROM $BUILD_FROM -COPY run.sh /run.sh -RUN chmod +x /run.sh +ENV SET_CONTAINER_TIMEZONE true +ENV CONTAINER_TIMEZONE Asia/Shanghai -ENV LANG C.UTF-8 -ENTRYPOINT ["/bin/bash", "/run.sh"] +WORKDIR /app + +CMD ["python3", "main.py"] diff --git a/Dockerfile-for-github-action b/Dockerfile-for-github-action index 652bb8d..263ab8d 100644 --- a/Dockerfile-for-github-action +++ b/Dockerfile-for-github-action @@ -2,6 +2,10 @@ FROM python:3.11.11-slim-bookworm as build ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 +ENV SET_CONTAINER_TIMEZONE=true +ENV CONTAINER_TIMEZONE=Asia/Shanghai +ENV TZ=Asia/Shanghai + ARG TARGETARCH ARG VERSION @@ -13,7 +17,8 @@ WORKDIR /app RUN apt-get --allow-releaseinfo-change update \ && apt-get install -y --no-install-recommends jq chromium chromium-driver tzdata \ - && ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ + && echo $TZ > /etc/timezone \ && dpkg-reconfigure --frontend noninteractive tzdata \ && rm -rf /var/lib/apt/lists/* \ && apt-get clean @@ -34,4 +39,4 @@ RUN mkdir /data \ ENV LANG=C.UTF-8 -CMD ["python"] \ No newline at end of file +CMD ["python3","main.py"] \ No newline at end of file diff --git a/build.yaml b/build.yaml index 1e8fe6d..d4a1308 100644 --- a/build.yaml +++ b/build.yaml @@ -1,7 +1,6 @@ build_from: - aarch64: registry.cn-hangzhou.aliyuncs.com/arcw/sgcc_electricity:latest - amd64: registry.cn-hangzhou.aliyuncs.com/arcw/sgcc_electricity:latest -labels: - org.opencontainers.image.title: "SGCC Electricity Add-on" - org.opencontainers.image.description: "State Grid Electric Data" - org.opencontainers.image.source: "https://github.com/ARC-MX/sgcc_electricity_new" + aarch64: registry.cn-hangzhou.aliyuncs.com/arcw/sgcc_electricity-arm64:latest + amd64: registry.cn-hangzhou.aliyuncs.com/arcw/sgcc_electricity-amd64:latest +codenotary: + base_image: ARC-MX@github.com + signer: ARC-MX@github.com diff --git a/config.yaml b/config.yaml index dbcdf0b..a7d5e48 100644 --- a/config.yaml +++ b/config.yaml @@ -1,7 +1,7 @@ -name: "SGCC Electricity New" -version: "latest" -slug: "sgcc_electricity_new" -description: "获取国网电费数据的插件(新版)" +name: "SGCC Electricity" +version: "v0.1.0" +slug: "sgcc_electricity" +description: "获取国网电费数据的插件" url: "https://github.com/ARC-MX/sgcc_electricity_new" arch: - aarch64 @@ -10,12 +10,13 @@ host_network: true startup: application boot: auto init: false -#image: "{arch}-sgcc_electricity_new" +# image: "registry.cn-hangzhou.aliyuncs.com/arcw/sgcc_electricity-{arch}" map: - config:rw options: phone: "" - password: "" + password: "" + ignore_user_id: "xxxx,xxxx" enable_database_storage: false db_name: "homeassistant.db" hass_url: "http://homeassistant.local:8123/" @@ -29,11 +30,11 @@ options: data_retention_days: 7 recharge_notify: false balance: 5.0 - pushplus_token: "" + pushplus_token: "xxxx,xxxx" schema: phone: str password: password - IGNORE_USER_ID: "str?" + ignore_user_id: str enable_database_storage: bool db_name: str hass_url: str @@ -47,11 +48,11 @@ schema: data_retention_days: int recharge_notify: bool balance: float - pushplus_token: "str?" + pushplus_token: str environment: PHONE_NUMBER: "${phone}" PASSWORD: "${password}" - IGNORE_USER_ID: "${IGNORE_USER_ID}" + IGNORE_USER_ID: "${ignore_user_id}" ENABLE_DATABASE_STORAGE: "${enable_database_storage}" DB_NAME: "${db_name}" HASS_URL: "${hass_url}" @@ -63,6 +64,6 @@ environment: RETRY_WAIT_TIME_OFFSET_UNIT: "${retry_wait_time_offset_unit}" LOG_LEVE: "${log_level}" DATA_RETENTION_DAYS: "${data_retention_days}" - RECHARGE_NOTIFY: "${IGNORE_USER_ID}" + RECHARGE_NOTIFY: "${recharge_notify}" BALANCE: "${balance}" PUSHPLUS_TOKEN: "${pushplus_token}" \ No newline at end of file diff --git a/repository.yaml b/repository.yaml index cba2bde..800cb90 100644 --- a/repository.yaml +++ b/repository.yaml @@ -1,3 +1,3 @@ -name: sgcc_electricity_new add-on repository +name: sgcc_electricity add-on repository url: 'https://github.com/ARC-MX/sgcc_electricity_new' -maintainer: sgcc_electricity_new +maintainer: sgcc_electricity diff --git a/run.sh b/run.sh deleted file mode 100644 index df2cbb4..0000000 --- a/run.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash -# Read configuration from options.json -CONFIG_PATH="/data/options.json" -if [ ! -f "$CONFIG_PATH" ]; then - echo "Error: Configuration file not found $CONFIG_PATH" - exit 1 -fi -# Use jq to read config and set environment variables -export PHONE_NUMBER=$(jq -r '.phone // empty' "$CONFIG_PATH") -export PASSWORD=$(jq -r '.password // empty' "$CONFIG_PATH") -export IGNORE_USER_ID=$(jq -r '.IGNORE_USER_ID // empty' "$CONFIG_PATH") -export ENABLE_DATABASE_STORAGE=$(jq -r '.enable_database_storage // "false"' "$CONFIG_PATH") -export DB_NAME=$(jq -r '.db_name // "homeassistant.db"' "$CONFIG_PATH") -export HASS_URL=$(jq -r '.hass_url // empty' "$CONFIG_PATH") -export HASS_TOKEN=$(jq -r '.hass_token // empty' "$CONFIG_PATH") -export JOB_START_TIME=$(jq -r '.job_start_time // "00:00"' "$CONFIG_PATH") -export DRIVER_IMPLICITLY_WAIT_TIME=$(jq -r '.driver_implicitly_wait_time // "10"' "$CONFIG_PATH") -export RETRY_TIMES_LIMIT=$(jq -r '.retry_times_limit // "3"' "$CONFIG_PATH") -export LOGIN_EXPECTED_TIME=$(jq -r '.login_expected_time // "60"' "$CONFIG_PATH") -export RETRY_WAIT_TIME_OFFSET_UNIT=$(jq -r '.retry_wait_time_offset_unit // "5"' "$CONFIG_PATH") -export LOG_LEVEL=$(jq -r '.log_level // "INFO"' "$CONFIG_PATH") -export DATA_RETENTION_DAYS=$(jq -r '.data_retention_days // "30"' "$CONFIG_PATH") -export RECHARGE_NOTIFY=$(jq -r '.recharge_notify // "false"' "$CONFIG_PATH") -export BALANCE=$(jq -r '.balance // "50"' "$CONFIG_PATH") -export PUSHPLUS_TOKEN=$(jq -r '.pushplus_token // empty' "$CONFIG_PATH") -# Check required environment variables -if [ -z "$PHONE_NUMBER" ]; then - echo "Error: Phone number not set" - exit 1 -fi -if [ -z "$PASSWORD" ]; then - echo "Error: Password not set" - exit 1 -fi -if [ -z "$HASS_URL" ]; then - echo "Error: Home Assistant URL not set" - exit 1 -fi -if [ -z "$HASS_TOKEN" ]; then - echo "Error: Home Assistant Token not set" - exit 1 -fi -# Output environment variables log -echo "Environment variables setup completed:" -echo "Phone Number: ${PHONE_NUMBER:-Not Set}" -echo "Home Assistant URL: ${HASS_URL:-Not Set}" -echo "Job Start Time: ${JOB_START_TIME:-Not Set}" -echo "Log Level: ${LOG_LEVEL:-Not Set}" -echo "Data Retention Days: ${DATA_RETENTION_DAYS:-Not Set}" -# Start main program -python3 /app/main.py \ No newline at end of file diff --git a/scripts/data_fetcher.py b/scripts/data_fetcher.py index 906d106..8da63e3 100644 --- a/scripts/data_fetcher.py +++ b/scripts/data_fetcher.py @@ -83,6 +83,7 @@ class DataFetcher: def __init__(self, username: str, password: str): if 'PYTHON_IN_DOCKER' not in os.environ: + import dotenv dotenv.load_dotenv(verbose=True) self._username = username self._password = password @@ -390,10 +391,18 @@ def _get_all_data(self, driver, user_id, userid_index): # 按月获取数据 month, month_usage, month_charge = self._get_month_usage(driver) - + if month is None: + logging.error(f"Get month power usage for {user_id} failed, pass") + else: + for m in range(len(month)): + logging.info(f"Get month power charge for {user_id} successfully, {month[m]} usage is {month_usage[m]} KWh, charge is {month_charge[m]} CNY.") # get yesterday usage last_daily_date, last_daily_usage = self._get_yesterday_usage(driver) - + if last_daily_usage is None: + logging.error(f"Get daily power consumption for {user_id} failed, pass") + else: + logging.info( + f"Get daily power consumption for {user_id} successfully, , {last_daily_date} usage is {last_daily_usage} kwh.") if month is None: logging.error(f"Get month power usage for {user_id} failed, pass") @@ -407,11 +416,6 @@ def _get_all_data(self, driver, user_id, userid_index): else: logging.info("enable_database_storage is false, we will not store the data to the database.") - if last_daily_usage is None: - logging.error(f"Get daily power consumption for {user_id} failed, pass") - else: - logging.info( - f"Get daily power consumption for {user_id} successfully, , {last_daily_date} usage is {last_daily_usage} kwh.") if month_charge: month_charge = month_charge[-1] diff --git a/scripts/main.py b/scripts/main.py index 9de10cf..524276f 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -12,6 +12,7 @@ def main(): if 'PYTHON_IN_DOCKER' not in os.environ: # 读取 .env 文件 + import dotenv dotenv.load_dotenv(verbose=True) global RETRY_TIMES_LIMIT try: @@ -28,6 +29,8 @@ def main(): logger_init(LOG_LEVEL) logging.info(f"The current repository version is {VERSION}, and the repository address is https://github.com/ARC-MX/sgcc_electricity_new.git") + current_datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + logging.info(f"The current date is {current_datetime}.") fetcher = DataFetcher(PHONE_NUMBER, PASSWORD) logging.info(f"The current logged-in user name is {PHONE_NUMBER}, the homeassistant address is {HASS_URL}, and the program will be executed every day at {JOB_START_TIME}.") diff --git a/scripts/sensor_updator.py b/scripts/sensor_updator.py index 7875948..234b4dd 100644 --- a/scripts/sensor_updator.py +++ b/scripts/sensor_updator.py @@ -76,8 +76,12 @@ def update_month_data(self, postfix: str, sensorState: float, usage=False): if usage else MONTH_CHARGE_SENSOR_NAME + postfix ) - last_updated = datetime.now().month - 1 - last_reset = datetime.now().replace(month=last_updated).strftime("%Y-%m") + if datetime.now().month == 1: + last_year = datetime.now().year -1 + last_reset = datetime.now().replace(year=last_year, month=12).strftime("%Y-%m") + else: + last_updated = datetime.now().month - 1 + last_reset = datetime.now().replace(month=last_updated).strftime("%Y-%m") request_body = { "state": sensorState, "unique_id": sensorName,