128 lines
3.1 KiB
PHP
Executable File
128 lines
3.1 KiB
PHP
Executable File
#!/usr/bin/env php
|
|
<?php
|
|
|
|
use Mosquitto\Client;
|
|
use Mosquitto\Message;
|
|
|
|
define("MQTT_HOST", getenv("MQTT_HOST"));
|
|
define("ENERGY_METER_TOPIC", getenv("ENERGY_METER_TOPIC"));
|
|
define("DOOR_TOPIC", getenv("DOOR_TOPIC"));
|
|
define("ENERGY_PRICE", floatval(getenv("ENERGY_PRICE")));
|
|
define("OUTPUT_TOPIC_PREFIX", getenv("OUTPUT_TOPIC_PREFIX"));
|
|
|
|
|
|
echo "using configuration:\n";
|
|
echo " MQTT_HOST: " . MQTT_HOST . "\n";
|
|
echo " ENERGY_METER_TOPIC: " . ENERGY_METER_TOPIC . "\n";
|
|
echo " DOOR_TOPIC: " . DOOR_TOPIC . "\n";
|
|
echo " ENERGY_PRICE: " . ENERGY_PRICE . "\n";
|
|
echo " OUTPUT_TOPIC_PREFIX: " . OUTPUT_TOPIC_PREFIX . "\n";
|
|
|
|
|
|
|
|
$doorStatus = null;
|
|
$energyCounter = null;
|
|
$doorOpenEnergy = null;
|
|
$doorOpenTime = null;
|
|
$lastOutput = 0;
|
|
|
|
function l(){
|
|
#echo implode(" ", func_get_args()) . "\n";
|
|
}
|
|
|
|
$c = new Client();
|
|
|
|
if (getenv("MQTT_USER") && getenv("MQTT_PASS")) {
|
|
echo "using credentials\n";
|
|
echo " MQTT_USER: " . getenv("MQTT_USER") . "\n";
|
|
echo " MQTT_PASS: " . str_repeat("*", strlen(getenv("MQTT_PASS"))) . "\n";
|
|
|
|
$c->setCredentials(getenv("MQTT_USER"), getenv("MQTT_PASS"));
|
|
}
|
|
|
|
$c->connect(MQTT_HOST, 1883, 60);
|
|
$c->subscribe(ENERGY_METER_TOPIC, 2);
|
|
$c->subscribe(DOOR_TOPIC, 2);
|
|
|
|
$c->onMessage(function (Message $message) {
|
|
l("got message", $message->topic, $message->payload);
|
|
switch ($message->topic) {
|
|
case ENERGY_METER_TOPIC:
|
|
energy($message->payload);
|
|
break;
|
|
case DOOR_TOPIC:
|
|
door($message->payload);
|
|
break;
|
|
default:
|
|
l("unknown topic", $message->topic);
|
|
}
|
|
});
|
|
|
|
while (true) {
|
|
while ($lastOutput > time() - 10) {
|
|
$c->loop(1000);
|
|
}
|
|
output();
|
|
}
|
|
|
|
function door($newStatus)
|
|
{
|
|
global $doorStatus, $energyCounter, $doorOpenEnergy, $doorOpenTime;
|
|
|
|
$newStatus = (bool) $newStatus;
|
|
if ($newStatus === $doorStatus) {
|
|
return;
|
|
}
|
|
$doorStatus = $newStatus;
|
|
if (!$newStatus) {
|
|
$doorOpenEnergy = $energyCounter;
|
|
$doorOpenTime = time();
|
|
}
|
|
output();
|
|
}
|
|
function energy($value)
|
|
{
|
|
global $energyCounter,$doorOpenEnergy;
|
|
$energyCounter = (float) $value;
|
|
|
|
if(is_null($doorOpenEnergy)){
|
|
$doorOpenEnergy = $energyCounter;
|
|
}
|
|
|
|
output();
|
|
}
|
|
|
|
function output()
|
|
{
|
|
global $doorStatus,
|
|
$energyCounter,
|
|
$doorOpenEnergy,
|
|
$doorOpenTime,
|
|
$lastOutput,
|
|
$c;
|
|
if ($doorStatus) {
|
|
$myUsage = $energyCounter - $doorOpenEnergy;
|
|
$myCost = $myUsage * ENERGY_PRICE;
|
|
$c->publish(
|
|
OUTPUT_TOPIC_PREFIX . "/used_energy_float",
|
|
strval($myUsage),
|
|
2
|
|
);
|
|
l("cost", $myCost);
|
|
$c->publish(OUTPUT_TOPIC_PREFIX . "/price_float", strval($myCost), 2);
|
|
$c->publish(
|
|
OUTPUT_TOPIC_PREFIX . "/price_string",
|
|
number_format($myCost, 2, ",", "."),
|
|
2
|
|
);
|
|
|
|
} else {
|
|
l("nope");
|
|
$c->publish(OUTPUT_TOPIC_PREFIX . "/used_energy_float", "", 2);
|
|
$c->publish(OUTPUT_TOPIC_PREFIX . "/price_float", "", 2);
|
|
$c->publish(OUTPUT_TOPIC_PREFIX . "/price_string", "", 2);
|
|
}
|
|
$lastOutput = time();
|
|
}
|
|
|