From d0249384456c4360d42373dade9c96e4e69a9717 Mon Sep 17 00:00:00 2001 From: Matthew Horwood Date: Sun, 16 Apr 2023 11:26:24 +0100 Subject: [PATCH 1/9] 271/PHP rewrite feat: all new php code --- .dockerignore | 3 + .github/dependabot.yml | 12 + .github/workflows/image-dev.yml | 5 +- .gitignore | 67 ++ Dockerfile-php | 18 + composer.json | 26 + composer.lock | 1920 +++++++++++++++++++++++++++++++ data/.gitignore | 0 data/config.json | 9 + data/foxess_data.json | 32 + docker-compose.yml | 13 +- foxess-data.sh | 22 +- mqtt/mosquitto.conf | 4 + mqtt/users.txt | 1 + run.php | 7 + run.sh | 2 +- src/classes/json.php | 31 + src/controller/foxess_data.php | 98 ++ src/model/data.php | 47 + src/model/login.php | 53 + src/model/mqtt.php | 89 ++ 21 files changed, 2446 insertions(+), 13 deletions(-) create mode 100644 .dockerignore create mode 100644 .github/dependabot.yml create mode 100644 .gitignore create mode 100644 Dockerfile-php create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 data/.gitignore create mode 100644 data/config.json create mode 100644 data/foxess_data.json create mode 100644 mqtt/mosquitto.conf create mode 100644 mqtt/users.txt create mode 100644 run.php create mode 100644 src/classes/json.php create mode 100644 src/controller/foxess_data.php create mode 100644 src/model/data.php create mode 100644 src/model/login.php create mode 100644 src/model/mqtt.php diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f5c5347 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +.git +.github +mqtt diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..6be9639 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/image-dev.yml b/.github/workflows/image-dev.yml index ca28da5..b2ead29 100644 --- a/.github/workflows/image-dev.yml +++ b/.github/workflows/image-dev.yml @@ -2,7 +2,7 @@ name: build our image for dev on: push: - branches: dev + branches: dev-php jobs: build: @@ -19,5 +19,6 @@ jobs: - name: build the image run: | docker buildx build --push \ - --tag mhzawadi/foxess-mqtt:dev \ + --tag mhzawadi/foxess-mqtt:dev-php \ --platform linux/amd64,linux/arm64,linux/arm/v7 . + --file Dockerfile-php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..13f287f --- /dev/null +++ b/.gitignore @@ -0,0 +1,67 @@ +# ---> PhpStorm +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/dictionaries + +# Sensitive or high-churn files: +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.xml +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml + +# Gradle: +.idea/**/gradle.xml +.idea/**/libraries + +# CMake +cmake-build-debug/ + +# Mongo Explorer plugin: +.idea/**/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Ruby plugin and RubyMine +/.rakeTasks + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +.DS_Store + +### PhpStorm Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/sonarlint +vendor diff --git a/Dockerfile-php b/Dockerfile-php new file mode 100644 index 0000000..8242399 --- /dev/null +++ b/Dockerfile-php @@ -0,0 +1,18 @@ +FROM alpine:3.17 +MAINTAINER Matthew Horwood + +# Install required deb packages +RUN apk update && apk upgrade && \ + apk add php81-json php81-curl git php81 php81-phar php81-xml php81-tokenizer \ + php81-sockets curl php81-openssl php81-mbstring php81-dom php81-xmlwriter \ + && rm -f /var/cache/apk/*; \ + php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \ + php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" && \ + php composer-setup.php && \ + php -r "unlink('composer-setup.php');" && \ + mv composer.phar /usr/local/bin/composer; + +COPY . /foxess-mqtt +WORKDIR /foxess-mqtt +RUN composer install; +CMD ["/foxess-mqtt/run.sh"] diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..10558c7 --- /dev/null +++ b/composer.json @@ -0,0 +1,26 @@ +{ + "name": "mhzawadi/foxess-mqtt", + "description": "Foxess Cloud data to MQTT", + "license": "MIT", + "keywords": ["foxess","mqtt"], + "authors": [ + { + "name": "Matthew Horwood", + "email": "matt@horwood.biz" + } + ], + "require" : { + "php-mqtt/client" : "*" + }, + "require-dev": { + "phpunit/phpunit": "9.5.*" + }, + "autoload": { + "psr-4": { + "MHorwood\\foxess_mqtt\\": "src" + }, + "psr-4": { + "MHorwood\\loader\\": "." + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..8438e2a --- /dev/null +++ b/composer.lock @@ -0,0 +1,1920 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "fcd89a445908544403e24209c9142596", + "packages": [ + { + "name": "myclabs/php-enum", + "version": "1.8.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/php-enum.git", + "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/a867478eae49c9f59ece437ae7f9506bfaa27483", + "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "1.*", + "vimeo/psalm": "^4.6.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "MyCLabs\\Enum\\": "src/" + }, + "classmap": [ + "stubs/Stringable.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP Enum contributors", + "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" + } + ], + "description": "PHP Enum implementation", + "homepage": "http://github.com/myclabs/php-enum", + "keywords": [ + "enum" + ], + "support": { + "issues": "https://github.com/myclabs/php-enum/issues", + "source": "https://github.com/myclabs/php-enum/tree/1.8.4" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", + "type": "tidelift" + } + ], + "time": "2022-08-04T09:53:51+00:00" + }, + { + "name": "php-mqtt/client", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/php-mqtt/client.git", + "reference": "99967b4d4f10388c34e82b1881eb8f833ced322c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-mqtt/client/zipball/99967b4d4f10388c34e82b1881eb8f833ced322c", + "reference": "99967b4d4f10388c34e82b1881eb8f833ced322c", + "shasum": "" + }, + "require": { + "myclabs/php-enum": "^1.7", + "php": "^7.4|^8.0", + "psr/log": "^1.1|^2.0|^3.0" + }, + "require-dev": { + "phpunit/php-invoker": "^3.0", + "phpunit/phpunit": "^9.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "suggest": { + "ext-redis": "Required for the RedisRepository" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpMqtt\\Client\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marvin Mall", + "email": "marvin-mall@msn.com", + "role": "developer" + } + ], + "description": "An MQTT client written in and for PHP.", + "keywords": [ + "client", + "mqtt", + "publish", + "subscribe" + ], + "support": { + "issues": "https://github.com/php-mqtt/client/issues", + "source": "https://github.com/php-mqtt/client/tree/v1.8.0" + }, + "time": "2023-02-10T19:37:29+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:23:10+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.15.3", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/570e980a201d8ed0236b0a62ddf2c9cbb2034039", + "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.3" + }, + "time": "2023-01-16T22:05:37+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.24", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2cf940ebc6355a9d430462811b5aaa308b174bed", + "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.14", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.24" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-01-26T08:26:55+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.5.28", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "954ca3113a03bf780d22f07bf055d883ee04b65e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/954ca3113a03bf780d22f07bf055d883ee04b65e", + "reference": "954ca3113a03bf780d22f07bf055d883ee04b65e", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1 || ^2", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.8", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.5", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.2", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.28" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2023-01-14T12:32:24+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:03:51+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T06:03:37+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:07:39+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:13:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/data/.gitignore b/data/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/data/config.json b/data/config.json new file mode 100644 index 0000000..c152492 --- /dev/null +++ b/data/config.json @@ -0,0 +1,9 @@ +{ + "foxess_username": "", + "foxess_password": "", + "device_id": "", + "mqtt_host": "", + "mqtt_port": "", + "mqtt_user": "", + "mqtt_pass": "" +} diff --git a/data/foxess_data.json b/data/foxess_data.json new file mode 100644 index 0000000..d36d136 --- /dev/null +++ b/data/foxess_data.json @@ -0,0 +1,32 @@ +{ + "setup": "", + "token": "", + "variables": { + "0": "generationPower", + "1": "feedinPower", + "2": "batChargePower", + "3": "batDischargePower", + "4": "gridConsumptionPower", + "5": "loadsPower", + "6": "SoC", + "7": "batTemperature", + "8": "pv1Power", + "9": "pv2Power", + "10": "pv3Power", + "11": "pv4Power" + }, + "result": { + "generationPower": 0, + "feedinPower": 0, + "batChargePower": 0, + "batDischargePower": 0, + "gridConsumptionPower": 0, + "loadsPower": 0, + "SoC": 0, + "batTemperature": 0, + "pv1Power": 0, + "pv2Power": 0, + "pv3Power": 0, + "pv4Power": 0 + } +} diff --git a/docker-compose.yml b/docker-compose.yml index 25b7744..040b285 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,22 @@ version: "2.1" services: + mosquitto: + image: eclipse-mosquitto + container_name: mosquitto + volumes: + - /Users/matt/git/foxess-mqtt/mqtt/mosquitto.conf:/mosquitto/config/mosquitto.conf + - /Users/matt/git/foxess-mqtt/mqtt/users.txt:/mosquitto/data/users.txt + foxess-mqtt: image: mho/foxess-mqtt container_name: foxess-mqtt environment: - - MQTT_HOST=127.0.0.1 + - MQTT_HOST=mosquitto - MQTT_USERNAME=username - MQTT_PASSWORD=password - FOXESS_USERNAME=username - FOXESS_PASSWORD=password - - DEVICE_ID=this-is-uuis + - DEVICE_ID=this-is-uuid + volumes: + - /Users/matt/git/foxess-mqtt:/foxess-mqtt diff --git a/foxess-data.sh b/foxess-data.sh index d52913f..069c3f6 100755 --- a/foxess-data.sh +++ b/foxess-data.sh @@ -37,15 +37,21 @@ collect_data(){ https://www.foxesscloud.com/c/v0/device/history/raw | jq > /tmp/raw.json - # Check if we need to login - if [ $(jq -r '.errno' /tmp/raw.json) -eq 41809 ] + if [ -s /tmp/raw.json ] then - ~/bin/foxess-login.sh - collect_data - elif [ $(jq -r '.errno' /tmp/raw.json) -gt 0 ] - then - # if .errno greater then 0 - echo "We have an error getting data, we have logged in fine" + # Check if we need to login + if [ $(jq -r '.errno' /tmp/raw.json) -eq 41809 ] + then + ~/bin/foxess-login.sh + collect_data + elif [ $(jq -r '.errno' /tmp/raw.json) -gt 0 ] + then + # if .errno greater then 0 + echo "We have an error getting data, we have logged in fine" + exit 1 + fi + else + echo "We have an error getting data, the file is empty" exit 1 fi diff --git a/mqtt/mosquitto.conf b/mqtt/mosquitto.conf new file mode 100644 index 0000000..ec4373f --- /dev/null +++ b/mqtt/mosquitto.conf @@ -0,0 +1,4 @@ +log_dest stdout +listener 1883 +protocol mqtt +password_file /mosquitto/data/users.txt diff --git a/mqtt/users.txt b/mqtt/users.txt new file mode 100644 index 0000000..7a6525f --- /dev/null +++ b/mqtt/users.txt @@ -0,0 +1 @@ +foxess:$7$101$z3giBVZOlRumavFu$kfFM7VZPCT13hwedUN1W4OEgCImRJj5f8xCjOIlwEd6Ot3OkdMuQEULc85hDUUBLR7SM1pkCC2zZUPzbTy79+Q== diff --git a/run.php b/run.php new file mode 100644 index 0000000..6cd8af6 --- /dev/null +++ b/run.php @@ -0,0 +1,7 @@ +login = new login(); + $this->data = new data(); + $this->mqtt = new mqtt(); + + echo 'Start of work'."\n"; + # load the json data from file + $this->foxess_data = $this->load_from_file('data/foxess_data.json'); + if($this->foxess_data['setup'] < time()){ + $this->mqtt->setup_mqtt($this->foxess_data); + } + $this->collect_data(); + $this->data->process_data($this->foxess_data, $this->collected_data); + echo 'Work complete'."\n"; + } + + + + /** + * Collect data from Foxess Cloud + * + * use curl to collect the latest data from Foxes Cloud + * + */ + protected function collect_data() { + $config = $this->load_from_file('data/config.json'); + echo 'Collect data from the cloud'."\n"; + $data = '{ + "deviceID": '.$config['device_id'].', + '.json_encode($this->foxess_data['variables']).', + "timespan": "day", + "beginDate": { + "year": '.date("Y").', + "month": '.date("m").', + "day": '.date("d").', + "hour": '.date("H").', + "minute": 0, + "second": 0 + } + }'; + $curl = curl_init(); + curl_setopt($curl, CURLOPT_HTTPHEADER, + array( + 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 OPR/89.0.4447.83', + 'Accept: application/json, text/plain, */*', + 'lang: en', + 'sec-ch-ua-platform: macOS', + 'Sec-Fetch-Site: same-origin', + 'Sec-Fetch-Mode: cors', + 'Sec-Fetch-Dest: empty', + 'Referer: https://www.foxesscloud.com/login?redirect=/', + 'Accept-Language: en-US;q=0.9,en;q=0.8,de;q=0.7,nl;q=0.6', + 'Connection: keep-alive', + 'X-Requested-With: XMLHttpRequest', + "token: ".$this->foxess_data['token'], + "Content-Type: application/json" + ) + ); + curl_setopt($curl, CURLOPT_POST, 1); + curl_setopt($curl, CURLOPT_POSTFIELDS, $data); + curl_setopt_array ( $curl , [ + CURLOPT_URL => "https://www.foxesscloud.com/c/v0/device/history/raw", + CURLOPT_RETURNTRANSFER => true + ] ); + $return_data = json_decode(curl_exec($curl), true); + var_dump($return_data); + if(is_null($return_data) === false){ + if($return_data['errno'] == 41809){ + echo 'we need to login again'."\n"; + $this->login->login(); + $this->collect_data(); + }elseif($return_data['errno'] > 0){ + echo 'We have an error getting data, we have logged in fine'; + exit; + } + }else{ + echo 'We have an error getting data, the file is empty'; + exit; + } + $this->collected_data = $return_data; + echo 'Data collected'."\n"; + } +} diff --git a/src/model/data.php b/src/model/data.php new file mode 100644 index 0000000..8a39f8a --- /dev/null +++ b/src/model/data.php @@ -0,0 +1,47 @@ +mqtt = new mqtt(); + echo 'Start of processing the data'."\n"; + $options_count = count($collected_data['result']); + print_r($options_count); + for( $i = 0 ; $i < $options_count; $i++ ){ + $option = $collected_data['result'][$i]['variable']; + if($collected_data['result'] == 'null'){ + $value_kw = 0; + $value_kwh = $foxess_data['result'][$i]; + }else{ + $value_data = count($collected_data['result'][$i]['data']); + $data = $collected_data['result'][$i][$i]['data'][$value_data]; + if($data['time'] == date('Y-m-d H')){ + $value_kw = $data['value']; + $value_kwh = round(float($foxess_data['result'][$i] + $data['value']), 2); + }else{ + $value_kw = 0; + $value_kwh = $foxess_data['result'][$i]; + } + } + $this->mqtt->post_mqtt('foxesscloud/'.$collected_data['result'][$i]['variable'], $value_kw); + + $foxess_data['result'][$data_name] = $value_kwh; + $this->save_to_file('data/foxess_data.json', $foxess_data); + $this->mqtt->post_mqtt('foxesscloud/'.$data_name.'_kwh', $value_kwh); + } + echo 'Data procssed and posted to MQTT'."\n"; + } +} diff --git a/src/model/login.php b/src/model/login.php new file mode 100644 index 0000000..30b324c --- /dev/null +++ b/src/model/login.php @@ -0,0 +1,53 @@ +load_from_file('data/config.json'); + $foxess_data = $this->load_from_file('data/foxess_data.json'); + echo 'Need to login'."\n"; + $data = '{ + "user": "'.$this->config['foxess_username'].'", + "password": "'.$this->config['foxess_password'].'" + }'; + set_time_limit(0); + $curl = curl_init(); + curl_setopt($curl, CURLOPT_HTTPHEADER, + array( + 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 OPR/89.0.4447.83', + 'Accept: application/json, text/plain, */*', + 'lang: en', + 'sec-ch-ua-platform: macOS', + 'Sec-Fetch-Site: same-origin', + 'Sec-Fetch-Mode: cors', + 'Sec-Fetch-Dest: empty', + 'Referer: https://www.foxesscloud.com/login?redirect=/', + 'Accept-Language: en-US;q=0.9,en;q=0.8,de;q=0.7,nl;q=0.6', + 'Connection: keep-alive', + 'X-Requested-With: XMLHttpRequest', + 'token: ' + ) + ); + curl_setopt($curl, CURLOPT_POST, 1); + curl_setopt($curl, CURLOPT_POSTFIELDS, $data); + curl_setopt_array ( $curl , [ + CURLOPT_URL => "https://www.foxesscloud.com/c/v0/user/login", + CURLOPT_RETURNTRANSFER => true + ] ); + $return_data = json_decode(curl_exec($curl), true); + $foxess_data['token'] = $return_data['result']['token']; + curl_close($curl); + $this->save_to_file('data/foxess_data.json', $foxess_data); + echo 'Logged in and token saved'."\n"; + } +} diff --git a/src/model/mqtt.php b/src/model/mqtt.php new file mode 100644 index 0000000..fabdde2 --- /dev/null +++ b/src/model/mqtt.php @@ -0,0 +1,89 @@ + $value){ + $data = '{ + "name": "foxesscloud '.$name.'", + "device": { + "identifiers": "foxesscloud", + "name": "foxesscloud", + "model": "F5000", + "manufacturer": "FoxEss" + }, + "stat_t": "~'.$name.'", + "uniq_id": "foxesscloud-'.$name.'", + "~": "foxesscloud/", + "unit_of_measurement": "KW", + "dev_cla": "power", + "exp_aft": 86400 + }'; + echo 'Post to MQTT foxesscloud-'.$name."\n"; + $this->post_mqtt('homeassistant/sensor/foxesscloud-'.$name.'/config', $data); + $data = '{ + "name": "foxesscloud '.$name.'_kwh", + "device": { + "identifiers": "foxesscloud", + "name": "foxesscloud", + "model": "F5000", + "manufacturer": "FoxEss" + }, + "stat_t": "~'.$name.'_kwh", + "uniq_id": "foxesscloud-'.$name.'_kwh", + "~": "foxesscloud/", + "unit_of_measurement": "kWh", + "dev_cla": "energy", + "state_class": "total_increasing", + "exp_aft": 86400 + }'; + echo 'Post to MQTT foxesscloud-'.$name.'_kwh'."\n"; + $this->post_mqtt('homeassistant/sensor/foxesscloud-'.$name.'_kwh/config', $data); + } + $date = new \DateTimeImmutable; + $time = $date->add(new \DateInterval("PT1H")); + $foxess_data['setup'] = $time->format('U'); + $this->save_to_file('data/foxess_data.json', $foxess_data); + echo 'Setup complete'."\n"; + } + + /** + * Post to MQTT + * + * Take some data and post to MQTT + * + * @param string topic + * @param string data + * @return return type + */ + protected function post_mqtt($foxess_data, $topic, $data) { + $config = $this->load_from_file('data/config.json'); + $connectionSettings = (new \PhpMqtt\Client\ConnectionSettings) + // The username used for authentication when connecting to the broker. + ->setUsername($config['mqtt_user']) + // The password used for authentication when connecting to the broker. + ->setPassword($config['mqtt_pass']); + $server = $config['mqtt_host']; + $port = $config['mqtt_port']; + $clientId = 'foxess_cloud_mqtt'; + + $mqtt = new \PhpMqtt\Client\MqttClient($server, $port, $clientId); + $mqtt->connect($connectionSettings, false); + $mqtt->publish($topic, $data, 0); + $mqtt->disconnect(); + } +} From b02756e5c50f80e3f3b3483406e62c616f076657 Mon Sep 17 00:00:00 2001 From: Matthew Horwood Date: Sun, 16 Apr 2023 11:33:06 +0100 Subject: [PATCH 2/9] 271/PHP rewrite chor: move shell chor: ignore user data --- .github/workflows/image-dev.yml | 2 +- .gitignore | 1 + foxess-data.sh => shell/foxess-data.sh | 0 foxess-login.sh => shell/foxess-login.sh | 0 foxess-report.sh => shell/foxess-report.sh | 0 foxess-setup.sh => shell/foxess-setup.sh | 0 foxess_data => shell/foxess_data | 0 7 files changed, 2 insertions(+), 1 deletion(-) rename foxess-data.sh => shell/foxess-data.sh (100%) rename foxess-login.sh => shell/foxess-login.sh (100%) rename foxess-report.sh => shell/foxess-report.sh (100%) rename foxess-setup.sh => shell/foxess-setup.sh (100%) rename foxess_data => shell/foxess_data (100%) diff --git a/.github/workflows/image-dev.yml b/.github/workflows/image-dev.yml index b2ead29..d0271de 100644 --- a/.github/workflows/image-dev.yml +++ b/.github/workflows/image-dev.yml @@ -20,5 +20,5 @@ jobs: run: | docker buildx build --push \ --tag mhzawadi/foxess-mqtt:dev-php \ + --file Dockerfile-php \ --platform linux/amd64,linux/arm64,linux/arm/v7 . - --file Dockerfile-php diff --git a/.gitignore b/.gitignore index 13f287f..e8edcbe 100644 --- a/.gitignore +++ b/.gitignore @@ -65,3 +65,4 @@ fabric.properties # Sonarlint plugin .idea/sonarlint vendor +data diff --git a/foxess-data.sh b/shell/foxess-data.sh similarity index 100% rename from foxess-data.sh rename to shell/foxess-data.sh diff --git a/foxess-login.sh b/shell/foxess-login.sh similarity index 100% rename from foxess-login.sh rename to shell/foxess-login.sh diff --git a/foxess-report.sh b/shell/foxess-report.sh similarity index 100% rename from foxess-report.sh rename to shell/foxess-report.sh diff --git a/foxess-setup.sh b/shell/foxess-setup.sh similarity index 100% rename from foxess-setup.sh rename to shell/foxess-setup.sh diff --git a/foxess_data b/shell/foxess_data similarity index 100% rename from foxess_data rename to shell/foxess_data From 1d5c433cb639e2b5b17e07da208b5a5dec32d772 Mon Sep 17 00:00:00 2001 From: Matthew Horwood Date: Thu, 4 May 2023 21:26:31 +0100 Subject: [PATCH 3/9] 271/PHP rewrite This is now a fully working system --- Dockerfile-php | 1 + README.md | 37 ++++++++++++++++--------- composer.json | 4 +-- data/config.json | 9 ------ docker-compose.yml | 15 ++++------ run.sh | 29 +++++++++++++++---- src/classes/json.php | 27 +++++++++++------- src/controller/foxess_data.php | 43 ++++++++++++++++++++--------- src/model/config.php | 38 +++++++++++++++++++++++++ src/model/data.php | 20 +++++++------- src/model/login.php | 33 ++++++++++++++++++---- src/model/mqtt.php | 26 ++++++++++++----- template/config.json | 9 ++++++ {data => template}/foxess_data.json | 0 14 files changed, 206 insertions(+), 85 deletions(-) delete mode 100644 data/config.json create mode 100644 src/model/config.php create mode 100644 template/config.json rename {data => template}/foxess_data.json (100%) diff --git a/Dockerfile-php b/Dockerfile-php index 8242399..149bc67 100644 --- a/Dockerfile-php +++ b/Dockerfile-php @@ -15,4 +15,5 @@ RUN apk update && apk upgrade && \ COPY . /foxess-mqtt WORKDIR /foxess-mqtt RUN composer install; +VOLUME /foxess-mqtt/data CMD ["/foxess-mqtt/run.sh"] diff --git a/README.md b/README.md index 1efb9f4..ccf2ca7 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,32 @@ This is a very simple tool to get the data out of foxesscloud and into MQTT, it ```bash docker run --name foxescloud \ - -e MQTT_HOST=192.168.0.2 \ - -e MQTT_USERNAME=homeassistant \ - -e MQTT_PASSWORD=ASecurePassword \ - -e FOXESS_USERNAME=foxAccount \ - -e FOXESS_PASSWORD=foxPassword \ - -e DEVICE_ID=a-b-d-c-d \ + -e - TIMEZONE=Europe/London \ + -v /home/user/foxess_data:/foxess-mqtt/data \ mhzawadi/foxess-mqtt ``` ## Docker environment variables -- MQTT_HOST the host or IP of your MQTT server -- MQTT_USERNAME - the username for MQTT -- MQTT_PASSWORD - the password for MQTT -- FOXESS_USERNAME - your Foxess Cloud login -- FOXESS_PASSWORD - your Foxess Cloud login -- DEVICE_ID - the UUID that can be found on foxesscloud in the url path on the Inverter Details page. - - Please make sure that this is exact value from inverter details page address between = and & character: +- TIMEZONE - This is the time your in, else use UTC [List of Supported Timezones](https://www.php.net/manual/en/timezones.php) + +## Config file + +The new PHP script uses json for the config, +you can copy the below code and paste into config.josn or run the image and wait for it spit out the files. + +`device_id` - the UUID that can be found on foxesscloud in the url path on the Inverter Details page. +Please make sure that this is exact value from inverter details page address between = and & character: + +The json for the config.json file +``` +{ + "foxess_username": "username", + "foxess_password": "secretPassword", + "device_id": "device_id", + "mqtt_host": "mosquitto", + "mqtt_port": "1883", + "mqtt_user": "foxess", + "mqtt_pass": "foxess" +} +``` diff --git a/composer.json b/composer.json index 10558c7..8e776d6 100644 --- a/composer.json +++ b/composer.json @@ -17,9 +17,7 @@ }, "autoload": { "psr-4": { - "MHorwood\\foxess_mqtt\\": "src" - }, - "psr-4": { + "MHorwood\\foxess_mqtt\\": "src", "MHorwood\\loader\\": "." } } diff --git a/data/config.json b/data/config.json deleted file mode 100644 index c152492..0000000 --- a/data/config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "foxess_username": "", - "foxess_password": "", - "device_id": "", - "mqtt_host": "", - "mqtt_port": "", - "mqtt_user": "", - "mqtt_pass": "" -} diff --git a/docker-compose.yml b/docker-compose.yml index 040b285..f3ac850 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,16 +7,13 @@ services: volumes: - /Users/matt/git/foxess-mqtt/mqtt/mosquitto.conf:/mosquitto/config/mosquitto.conf - /Users/matt/git/foxess-mqtt/mqtt/users.txt:/mosquitto/data/users.txt + ports: + - 1883:1883 foxess-mqtt: - image: mho/foxess-mqtt + image: mhzawadi/foxess-mqtt:dev-php container_name: foxess-mqtt - environment: - - MQTT_HOST=mosquitto - - MQTT_USERNAME=username - - MQTT_PASSWORD=password - - FOXESS_USERNAME=username - - FOXESS_PASSWORD=password - - DEVICE_ID=this-is-uuid volumes: - - /Users/matt/git/foxess-mqtt:/foxess-mqtt + - /Users/matt/data/foxess:/foxess-mqtt/data + environment: + - TIMEZONE=Europe/London diff --git a/run.sh b/run.sh index 6351c8f..ad93722 100755 --- a/run.sh +++ b/run.sh @@ -1,7 +1,26 @@ #!/bin/sh -while true -do - php run.php - sleep 300 -done +# Get the timezone and update PHP +if [ $TIMEZONE ] +then + echo "Setting your timezone to $TIMEZONE" + sed -i'' "s!;date.timezone =!date.timezone = $TIMEZONE!" /etc/php81/php.ini +else + echo "We dont have a timezone, it could UTC" +fi + +if [ ! -f /foxess-mqtt/data/config.json ] +then + cp /foxess-mqtt/template/config.json /foxess-mqtt/data/config.json + cp /foxess-mqtt/template/foxess_data.json /foxess-mqtt/data/foxess_data.json + echo 'Please update to config.json file' + exit 1; +else + echo "first run will sleep for 5 seconds to allow MQTT to get setup" + sleep 5 + while true + do + php run.php + sleep 300 + done +fi diff --git a/src/classes/json.php b/src/classes/json.php index 518e4e6..48756fe 100644 --- a/src/classes/json.php +++ b/src/classes/json.php @@ -4,24 +4,31 @@ class json { - /* - load a file and load to array - */ + /** + * load a file and load to array + */ protected function load_from_file($filename, $array = true){ - $handle = fopen($filename, "r"); - $json = json_decode(fread($handle, filesize($filename)), $array); - fclose($handle); - return $json; + try { + $handle = fopen($filename, "r"); + $json = json_decode(fread($handle, filesize($filename)), $array); + fclose($handle); + return $json; + } catch (Exception $e) { + echo 'Issues upening file: ', $e->getMessage(), "\n"; + return false; + } + } - /* - Save a json blob to file - */ + /** + * Save a json blob to file + */ protected function save_to_file($filename, $json){ try { $fp = fopen($filename, 'w'); fwrite($fp, json_encode($json, JSON_PRETTY_PRINT | JSON_FORCE_OBJECT)); fclose($fp); + sleep(1); return true; } catch (\Exception $e) { echo 'that didnt work'; diff --git a/src/controller/foxess_data.php b/src/controller/foxess_data.php index be888e5..0ffb3f8 100644 --- a/src/controller/foxess_data.php +++ b/src/controller/foxess_data.php @@ -4,6 +4,8 @@ use MHorwood\foxess_mqtt\classes\json; use MHorwood\foxess_mqtt\model\data; use MHorwood\foxess_mqtt\model\mqtt; +use MHorwood\foxess_mqtt\model\login; +use MHorwood\foxess_mqtt\model\config; class foxess_data extends json { @@ -12,11 +14,17 @@ class foxess_data extends json { protected $login; protected $mqtt; protected $data; + protected $config; public function __construct(){ $this->login = new login(); $this->data = new data(); $this->mqtt = new mqtt(); + try { + $this->config = new config(); + } catch (Exception $e) { + echo 'Missing config: ', $e->getMessage(), "\n"; + } echo 'Start of work'."\n"; # load the json data from file @@ -38,17 +46,16 @@ public function __construct(){ * */ protected function collect_data() { - $config = $this->load_from_file('data/config.json'); echo 'Collect data from the cloud'."\n"; $data = '{ - "deviceID": '.$config['device_id'].', - '.json_encode($this->foxess_data['variables']).', - "timespan": "day", + "deviceID": "'.$this->config->device_id.'", + "variables": '.json_encode($this->foxess_data['variables']).', + "timespan": "hour", "beginDate": { "year": '.date("Y").', - "month": '.date("m").', - "day": '.date("d").', - "hour": '.date("H").', + "month": '.date("n").', + "day": '.date("j").', + "hour": '.date("G").', "minute": 0, "second": 0 } @@ -78,18 +85,28 @@ protected function collect_data() { CURLOPT_RETURNTRANSFER => true ] ); $return_data = json_decode(curl_exec($curl), true); - var_dump($return_data); + $this->save_to_file('data/collected.json', $return_data); if(is_null($return_data) === false){ - if($return_data['errno'] == 41809){ + if($return_data['errno'] == 40401){ + echo 'Too many logins'; + exit; + }elseif($return_data['errno'] == 41809){ echo 'we need to login again'."\n"; - $this->login->login(); - $this->collect_data(); + if($this->foxess_data['token'] = $this->login->login()){ + $this->collect_data(); + }else{ + echo 'why are we here'; + exit; + } }elseif($return_data['errno'] > 0){ - echo 'We have an error getting data, we have logged in fine'; + echo 'We have an error getting data, we have logged in fine'."\n"; + echo 'Error: '.$return_data['errno']."\n"; exit; + }else{ + echo 'We have the data, ready to process'."\n"; } }else{ - echo 'We have an error getting data, the file is empty'; + echo 'We have an error getting data, the file is empty'."\n"; exit; } $this->collected_data = $return_data; diff --git a/src/model/config.php b/src/model/config.php new file mode 100644 index 0000000..0717497 --- /dev/null +++ b/src/model/config.php @@ -0,0 +1,38 @@ +load_from_file('data/config.json'); + $this->foxess_username = $config['foxess_username']; + $this->foxess_password = $config['foxess_password']; + $this->device_id = $config['device_id']; + $this->mqtt_host = $config['mqtt_host']; + $this->mqtt_port = $config['mqtt_port']; + $this->mqtt_user = $config['mqtt_user']; + $this->mqtt_pass = $config['mqtt_pass']; + } catch (Exception $e) { + echo 'Missing config: ', $e->getMessage(), "\n"; + } + + + if( $this->foxess_username === 'changeme' && + $this->foxess_password === 'changeme' ){ + throw new Exception('default config found'); + } + } +} diff --git a/src/model/data.php b/src/model/data.php index 8a39f8a..77f98e8 100644 --- a/src/model/data.php +++ b/src/model/data.php @@ -15,32 +15,32 @@ class data extends json { * * @return return type */ - protected function process_data($foxess_data, $collected_data) { + public function process_data($foxess_data, $collected_data) { $this->mqtt = new mqtt(); echo 'Start of processing the data'."\n"; $options_count = count($collected_data['result']); - print_r($options_count); for( $i = 0 ; $i < $options_count; $i++ ){ $option = $collected_data['result'][$i]['variable']; if($collected_data['result'] == 'null'){ $value_kw = 0; $value_kwh = $foxess_data['result'][$i]; }else{ - $value_data = count($collected_data['result'][$i]['data']); - $data = $collected_data['result'][$i][$i]['data'][$value_data]; - if($data['time'] == date('Y-m-d H')){ + $data = end($collected_data['result'][$i]['data']); + $name = $collected_data['result'][$i]['variable']; + if(substr($data['time'], 0, 13) == date('Y-m-d H')){ $value_kw = $data['value']; - $value_kwh = round(float($foxess_data['result'][$i] + $data['value']), 2); + $value_kwh = round(($foxess_data['result'][$name] + $data['value']), 2); }else{ $value_kw = 0; - $value_kwh = $foxess_data['result'][$i]; + $value_kwh = $foxess_data['result'][$name]; } } - $this->mqtt->post_mqtt('foxesscloud/'.$collected_data['result'][$i]['variable'], $value_kw); + $this->mqtt->post_mqtt('foxesscloud/'.$name, $value_kw); - $foxess_data['result'][$data_name] = $value_kwh; + $foxess_data['result'][$name] = $value_kwh; $this->save_to_file('data/foxess_data.json', $foxess_data); - $this->mqtt->post_mqtt('foxesscloud/'.$data_name.'_kwh', $value_kwh); + $this->mqtt->post_mqtt('foxesscloud/'.$name.'_kwh', $value_kwh); + echo 'Posted data to MQTT'."\n"; } echo 'Data procssed and posted to MQTT'."\n"; } diff --git a/src/model/login.php b/src/model/login.php index 30b324c..560b8f7 100644 --- a/src/model/login.php +++ b/src/model/login.php @@ -2,8 +2,19 @@ namespace MHorwood\foxess_mqtt\model; use MHorwood\foxess_mqtt\classes\json; +use MHorwood\foxess_mqtt\model\config; class login extends json { + + protected $config; + public function __construct(){ + try { + $this->config = new config(); + } catch (Exception $e) { + echo 'Missing config: ', $e->getMessage(), "\n"; + } + } + /** * Login to Foxess Cloud * @@ -12,13 +23,12 @@ class login extends json { * @param type var Description * @return return type */ - protected function login() { - $config = $this->load_from_file('data/config.json'); + public function login() { $foxess_data = $this->load_from_file('data/foxess_data.json'); echo 'Need to login'."\n"; $data = '{ - "user": "'.$this->config['foxess_username'].'", - "password": "'.$this->config['foxess_password'].'" + "user": "'.$this->config->foxess_username.'", + "password": "'.$this->config->foxess_password.'" }'; set_time_limit(0); $curl = curl_init(); @@ -47,7 +57,18 @@ protected function login() { $return_data = json_decode(curl_exec($curl), true); $foxess_data['token'] = $return_data['result']['token']; curl_close($curl); - $this->save_to_file('data/foxess_data.json', $foxess_data); - echo 'Logged in and token saved'."\n"; + if($return_data['errno'] === 40401){ + echo 'Too many logins'; + return false; + } + + try { + $this->save_to_file('data/foxess_data.json', $foxess_data); + echo 'Logged in and token saved'."\n"; + return $foxess_data['token']; + } catch (\Exception $e) { + echo 'We got a token, but it didnt save'; + return false; + } } } diff --git a/src/model/mqtt.php b/src/model/mqtt.php index fabdde2..4eac157 100644 --- a/src/model/mqtt.php +++ b/src/model/mqtt.php @@ -2,10 +2,19 @@ namespace MHorwood\foxess_mqtt\model; use MHorwood\foxess_mqtt\classes\json; +use MHorwood\foxess_mqtt\model\config; class mqtt extends json { + protected $config; public function __construct(){ + try { + $this->config = new config(); + } catch (Exception $e) { + echo 'Missing config: ', $e->getMessage(), "\n"; + } + + } /** @@ -52,7 +61,11 @@ public function setup_mqtt($foxess_data) { "exp_aft": 86400 }'; echo 'Post to MQTT foxesscloud-'.$name.'_kwh'."\n"; - $this->post_mqtt('homeassistant/sensor/foxesscloud-'.$name.'_kwh/config', $data); + try { + $this->post_mqtt('homeassistant/sensor/foxesscloud-'.$name.'_kwh/config', $data); + } catch (\Exception $e) { + echo "MQTT not yet ready, need to sleep on first run maybe"; + } } $date = new \DateTimeImmutable; $time = $date->add(new \DateInterval("PT1H")); @@ -70,15 +83,14 @@ public function setup_mqtt($foxess_data) { * @param string data * @return return type */ - protected function post_mqtt($foxess_data, $topic, $data) { - $config = $this->load_from_file('data/config.json'); + public function post_mqtt($topic, $data) { $connectionSettings = (new \PhpMqtt\Client\ConnectionSettings) // The username used for authentication when connecting to the broker. - ->setUsername($config['mqtt_user']) + ->setUsername($this->config->mqtt_user) // The password used for authentication when connecting to the broker. - ->setPassword($config['mqtt_pass']); - $server = $config['mqtt_host']; - $port = $config['mqtt_port']; + ->setPassword($this->config->mqtt_pass); + $server = $this->config->mqtt_host; + $port = $this->config->mqtt_port; $clientId = 'foxess_cloud_mqtt'; $mqtt = new \PhpMqtt\Client\MqttClient($server, $port, $clientId); diff --git a/template/config.json b/template/config.json new file mode 100644 index 0000000..2314708 --- /dev/null +++ b/template/config.json @@ -0,0 +1,9 @@ +{ + "foxess_username": "changeme", + "foxess_password": "changeme", + "device_id": "changeme", + "mqtt_host": "changeme", + "mqtt_port": "changeme", + "mqtt_user": "changeme", + "mqtt_pass": "changeme" +} diff --git a/data/foxess_data.json b/template/foxess_data.json similarity index 100% rename from data/foxess_data.json rename to template/foxess_data.json From 23fcc9cc960f8ea1db7e03475f6e2abdafccd09a Mon Sep 17 00:00:00 2001 From: Matthew Horwood Date: Thu, 4 May 2023 21:33:35 +0100 Subject: [PATCH 4/9] 271/PHP rewrite fix rounding --- src/model/data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model/data.php b/src/model/data.php index 77f98e8..ae7ad65 100644 --- a/src/model/data.php +++ b/src/model/data.php @@ -28,7 +28,7 @@ public function process_data($foxess_data, $collected_data) { $data = end($collected_data['result'][$i]['data']); $name = $collected_data['result'][$i]['variable']; if(substr($data['time'], 0, 13) == date('Y-m-d H')){ - $value_kw = $data['value']; + $value_kw = round($data['value'], 2); $value_kwh = round(($foxess_data['result'][$name] + $data['value']), 2); }else{ $value_kw = 0; From 1ba40e21a11c1b087086269371989bd891743d6f Mon Sep 17 00:00:00 2001 From: Matthew Horwood Date: Thu, 4 May 2023 21:36:02 +0100 Subject: [PATCH 5/9] 271/PHP Rewrite round down --- src/model/data.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/model/data.php b/src/model/data.php index ae7ad65..c71e654 100644 --- a/src/model/data.php +++ b/src/model/data.php @@ -28,8 +28,8 @@ public function process_data($foxess_data, $collected_data) { $data = end($collected_data['result'][$i]['data']); $name = $collected_data['result'][$i]['variable']; if(substr($data['time'], 0, 13) == date('Y-m-d H')){ - $value_kw = round($data['value'], 2); - $value_kwh = round(($foxess_data['result'][$name] + $data['value']), 2); + $value_kw = round($data['value'], 2, PHP_ROUND_HALF_DOWN); + $value_kwh = round(($foxess_data['result'][$name] + $data['value']), 2, PHP_ROUND_HALF_DOWN); }else{ $value_kw = 0; $value_kwh = $foxess_data['result'][$name]; From 191136c85a44f48bc7732d3b0f97457f2472f6f0 Mon Sep 17 00:00:00 2001 From: Matthew Horwood Date: Sun, 7 May 2023 11:27:57 +0100 Subject: [PATCH 6/9] bug: kw to kwh errors --- src/model/data.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/model/data.php b/src/model/data.php index c71e654..3e0a93e 100644 --- a/src/model/data.php +++ b/src/model/data.php @@ -29,7 +29,8 @@ public function process_data($foxess_data, $collected_data) { $name = $collected_data['result'][$i]['variable']; if(substr($data['time'], 0, 13) == date('Y-m-d H')){ $value_kw = round($data['value'], 2, PHP_ROUND_HALF_DOWN); - $value_kwh = round(($foxess_data['result'][$name] + $data['value']), 2, PHP_ROUND_HALF_DOWN); + $sum = round(($data['value']*0.08), 2, PHP_ROUND_HALF_DOWN); + $value_kwh = round(($foxess_data['result'][$name] + $sum), 2, PHP_ROUND_HALF_DOWN); }else{ $value_kw = 0; $value_kwh = $foxess_data['result'][$name]; From ed74a3914d57de2a4dd618f8eefc0814f977521a Mon Sep 17 00:00:00 2001 From: Matthew Horwood Date: Wed, 10 May 2023 17:08:28 +0100 Subject: [PATCH 7/9] test for expired token --- src/controller/foxess_data.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/controller/foxess_data.php b/src/controller/foxess_data.php index 0ffb3f8..d862240 100644 --- a/src/controller/foxess_data.php +++ b/src/controller/foxess_data.php @@ -90,7 +90,8 @@ protected function collect_data() { if($return_data['errno'] == 40401){ echo 'Too many logins'; exit; - }elseif($return_data['errno'] == 41809){ + }elseif($return_data['errno'] == 41809 || + $return_data['errno'] == 41808){ echo 'we need to login again'."\n"; if($this->foxess_data['token'] = $this->login->login()){ $this->collect_data(); From c323073b268d1faaa31d671220ca322da63757cc Mon Sep 17 00:00:00 2001 From: Matthew Horwood Date: Wed, 10 May 2023 20:07:11 +0100 Subject: [PATCH 8/9] chor: add datetime to logging bug: catch no data error --- src/controller/foxess_data.php | 4 ++-- src/model/data.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controller/foxess_data.php b/src/controller/foxess_data.php index d862240..4d81f3a 100644 --- a/src/controller/foxess_data.php +++ b/src/controller/foxess_data.php @@ -26,7 +26,7 @@ public function __construct(){ echo 'Missing config: ', $e->getMessage(), "\n"; } - echo 'Start of work'."\n"; + echo date('Y-m-d H:i:s').' - Start of work'."\n"; # load the json data from file $this->foxess_data = $this->load_from_file('data/foxess_data.json'); if($this->foxess_data['setup'] < time()){ @@ -34,7 +34,7 @@ public function __construct(){ } $this->collect_data(); $this->data->process_data($this->foxess_data, $this->collected_data); - echo 'Work complete'."\n"; + echo date('Y-m-d H:i:s').' - Work complete'."\n"; } diff --git a/src/model/data.php b/src/model/data.php index 3e0a93e..55c4e89 100644 --- a/src/model/data.php +++ b/src/model/data.php @@ -27,7 +27,7 @@ public function process_data($foxess_data, $collected_data) { }else{ $data = end($collected_data['result'][$i]['data']); $name = $collected_data['result'][$i]['variable']; - if(substr($data['time'], 0, 13) == date('Y-m-d H')){ + if(is_array($data) && substr($data['time'], 0, 13) == date('Y-m-d H')){ $value_kw = round($data['value'], 2, PHP_ROUND_HALF_DOWN); $sum = round(($data['value']*0.08), 2, PHP_ROUND_HALF_DOWN); $value_kwh = round(($foxess_data['result'][$name] + $sum), 2, PHP_ROUND_HALF_DOWN); From c4a433d3125dc9a3a798fd17975a3dab9dba4c74 Mon Sep 17 00:00:00 2001 From: Matthew Horwood Date: Thu, 11 May 2023 21:21:18 +0100 Subject: [PATCH 9/9] update workflows for PHP --- .github/workflows/image-latest.yml | 1 + .github/workflows/image-version.yml | 1 + README.md | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/image-latest.yml b/.github/workflows/image-latest.yml index 63770e2..ce17606 100644 --- a/.github/workflows/image-latest.yml +++ b/.github/workflows/image-latest.yml @@ -21,4 +21,5 @@ jobs: run: | docker buildx build --push \ --tag mhzawadi/foxess-mqtt:latest \ + --file Dockerfile-php \ --platform linux/amd64,linux/arm64,linux/arm/v7 . diff --git a/.github/workflows/image-version.yml b/.github/workflows/image-version.yml index ce58fee..0e12802 100644 --- a/.github/workflows/image-version.yml +++ b/.github/workflows/image-version.yml @@ -27,4 +27,5 @@ jobs: run: | docker buildx build --push \ --tag mhzawadi/foxess-mqtt:${{ steps.prepare.outputs.version }} \ + --file Dockerfile-php \ --platform linux/amd64,linux/arm64,linux/arm/v7 . diff --git a/README.md b/README.md index ccf2ca7..ede95b0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Horwoods Foxess Cloud Data collector -This is a very simple tool to get the data out of foxesscloud and into MQTT, it has some very rough edges. +This is a very simple tool to get the data out of FoxEss-cloud and into MQTT, it has some very rough edges. ## Running @@ -20,7 +20,7 @@ docker run --name foxescloud \ The new PHP script uses json for the config, you can copy the below code and paste into config.josn or run the image and wait for it spit out the files. -`device_id` - the UUID that can be found on foxesscloud in the url path on the Inverter Details page. +`device_id` - the UUID that can be found on FoxEss-cloud in the url path on the Inverter Details page. Please make sure that this is exact value from inverter details page address between = and & character: The json for the config.json file