remove CounterTable and CounterClient modules; add CounterServer and update library version
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"elements": [
|
||||
{
|
||||
"type": "SelectCategory",
|
||||
"name": "CounterCategoryID",
|
||||
"caption": "Counter Kategorie"
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "JsonOutputVariableID",
|
||||
"caption": "JSON Ausgabe Variable",
|
||||
"validVariableTypes": [3]
|
||||
},
|
||||
{
|
||||
"type": "ExpansionPanel",
|
||||
"caption": "MQTT (optional)",
|
||||
"items": [
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "EnableMQTT",
|
||||
"caption": "MQTT senden"
|
||||
},
|
||||
{
|
||||
"type": "SelectInstance",
|
||||
"name": "MqttClientID",
|
||||
"caption": "MQTT Client",
|
||||
"visible": "EnableMQTT",
|
||||
"validModules": ["{C6D2AEB3-6E1F-4B2E-8D6E-2F0A6C4C2A7F}"]
|
||||
},
|
||||
{
|
||||
"type": "ValidationTextBox",
|
||||
"name": "MqttTopic",
|
||||
"caption": "MQTT Topic",
|
||||
"visible": "EnableMQTT",
|
||||
"placeholder": "clients/counters/json"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "UpdateTime",
|
||||
"caption": "Aktualisierungszeit (Sekunden)",
|
||||
"digits": 0
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"type": "Button",
|
||||
"caption": "Testlauf (JSON erzeugen)",
|
||||
"onClick": "SECC_BuildAndStorePayload($id);"
|
||||
}
|
||||
],
|
||||
"status": [
|
||||
{
|
||||
"code": 101,
|
||||
"icon": "active",
|
||||
"caption": "Aktiv"
|
||||
},
|
||||
{
|
||||
"code": 102,
|
||||
"icon": "inactive",
|
||||
"caption": "Keine Kategorie gewählt"
|
||||
},
|
||||
{
|
||||
"code": 103,
|
||||
"icon": "inactive",
|
||||
"caption": "Keine JSON Variable gewählt"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"id": "{EF2E22EE-67DE-EF4F-42D0-C83C6E5E37C7}",
|
||||
"name": "CounterClient",
|
||||
"type": 3,
|
||||
"vendor": "J.H. Artworks",
|
||||
"aliases":
|
||||
[
|
||||
],
|
||||
"url": "https://jh-artworks.com",
|
||||
"parentRequirements": [],
|
||||
"childRequirements": [],
|
||||
"implemented": [],
|
||||
"prefix": "SECC"
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
<?php
|
||||
|
||||
class CounterClient extends IPSModule
|
||||
{
|
||||
public function Create()
|
||||
{
|
||||
parent::Create();
|
||||
|
||||
$this->RegisterPropertyInteger('CounterCategoryID', 0);
|
||||
$this->RegisterPropertyInteger('JsonOutputVariableID', 0);
|
||||
$this->RegisterPropertyInteger('UpdateTime', 60);
|
||||
|
||||
$this->RegisterTimer('Update', 0, 'SECC_BuildAndStorePayload($_IPS[\'TARGET\']);');
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
|
||||
$updateTime = $this->ReadPropertyInteger('UpdateTime');
|
||||
if ($updateTime < 1) {
|
||||
$updateTime = 60;
|
||||
}
|
||||
|
||||
$this->SetTimerInterval('Update', $updateTime * 1000);
|
||||
}
|
||||
|
||||
public function BuildAndStorePayload()
|
||||
{
|
||||
$json = $this->BuildPayload();
|
||||
if ($json === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$targetVarId = $this->ReadPropertyInteger('JsonOutputVariableID');
|
||||
if ($targetVarId > 0 && IPS_VariableExists($targetVarId)) {
|
||||
SetValueString($targetVarId, $json);
|
||||
}
|
||||
|
||||
IPS_LogMessage('CounterClient', $json);
|
||||
}
|
||||
|
||||
public function BuildPayload()
|
||||
{
|
||||
$counterCategoryId = $this->ReadPropertyInteger('CounterCategoryID');
|
||||
if ($counterCategoryId <= 0 || !IPS_ObjectExists($counterCategoryId)) {
|
||||
IPS_LogMessage('CounterClient', 'Ungültige CounterCategoryID');
|
||||
return '';
|
||||
}
|
||||
|
||||
$counterIds = IPS_GetChildrenIDs($counterCategoryId);
|
||||
$payload = [
|
||||
'timestamp' => date('Y-m-d H:i:s'),
|
||||
'counters' => []
|
||||
];
|
||||
|
||||
foreach ($counterIds as $counterObjectId) {
|
||||
$obj = IPS_GetObject($counterObjectId);
|
||||
|
||||
if ($obj['ObjectType'] != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$counterName = IPS_GetName($counterObjectId);
|
||||
$counterId = $this->makeSlug($counterName);
|
||||
|
||||
$varIds = $this->CollectVariablesRecursive($counterObjectId);
|
||||
if (count($varIds) === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$counterData = [
|
||||
'id' => $counterId,
|
||||
'name' => $counterName
|
||||
];
|
||||
|
||||
$tempSlots = [];
|
||||
$pressureSlots = [];
|
||||
|
||||
foreach ($varIds as $varId) {
|
||||
$classified = $this->ClassifyVariable($varId);
|
||||
if ($classified === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$field = $classified['field'];
|
||||
$value = $classified['value'];
|
||||
$unit = $classified['unit'];
|
||||
|
||||
if ($field === 'temperature_auto') {
|
||||
$tempSlots[] = $classified;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($field === 'pressure_auto') {
|
||||
$pressureSlots[] = $classified;
|
||||
continue;
|
||||
}
|
||||
|
||||
$counterData[$field] = $value;
|
||||
|
||||
if ($field === 'total_value' && !isset($counterData['unit']) && $unit !== '') {
|
||||
$counterData['unit'] = $unit;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assignInOutValues($counterData, $tempSlots, 'temperature_in_value', 'temperature_out_value');
|
||||
$this->assignInOutValues($counterData, $pressureSlots, 'pressure_in_value', 'pressure_out_value');
|
||||
|
||||
$counterData['type'] = $this->DetectCounterType($counterData);
|
||||
|
||||
if (!isset($counterData['unit'])) {
|
||||
$counterData['unit'] = $this->inferDefaultUnit($counterData);
|
||||
}
|
||||
|
||||
if (count($counterData) > 3) {
|
||||
$payload['counters'][] = $counterData;
|
||||
}
|
||||
}
|
||||
|
||||
return json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
|
||||
private function CollectVariablesRecursive(int $objectId): array
|
||||
{
|
||||
$result = [];
|
||||
$children = IPS_GetChildrenIDs($objectId);
|
||||
|
||||
foreach ($children as $childId) {
|
||||
if (IPS_LinkExists($childId)) {
|
||||
$link = IPS_GetLink($childId);
|
||||
$targetId = (int) $link['TargetID'];
|
||||
|
||||
if (IPS_VariableExists($targetId)) {
|
||||
$result[$targetId] = $targetId;
|
||||
} elseif (IPS_ObjectExists($targetId)) {
|
||||
foreach ($this->CollectVariablesRecursive($targetId) as $subVarId) {
|
||||
$result[$subVarId] = $subVarId;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IPS_VariableExists($childId)) {
|
||||
$result[$childId] = $childId;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IPS_ObjectExists($childId)) {
|
||||
foreach ($this->CollectVariablesRecursive($childId) as $subVarId) {
|
||||
$result[$subVarId] = $subVarId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($result);
|
||||
}
|
||||
|
||||
private function ClassifyVariable(int $varId): ?array
|
||||
{
|
||||
if (!IPS_VariableExists($varId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$var = IPS_GetVariable($varId);
|
||||
$type = (int) $var['VariableType'];
|
||||
|
||||
if ($type !== 1 && $type !== 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$profileName = '';
|
||||
if ($var['VariableCustomProfile'] !== '') {
|
||||
$profileName = $var['VariableCustomProfile'];
|
||||
} elseif ($var['VariableProfile'] !== '') {
|
||||
$profileName = $var['VariableProfile'];
|
||||
}
|
||||
|
||||
if ($profileName === '' || !IPS_VariableProfileExists($profileName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$profile = IPS_GetVariableProfile($profileName);
|
||||
$suffix = trim((string) $profile['Suffix']);
|
||||
$prefix = trim((string) $profile['Prefix']);
|
||||
$unit = trim($prefix . ' ' . $suffix);
|
||||
|
||||
if ($unit === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$value = GetValue($varId);
|
||||
if (!is_numeric($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$value = round((float) $value, 3);
|
||||
$varName = mb_strtolower(IPS_GetName($varId));
|
||||
$unitNorm = $this->normalizeUnit($unit);
|
||||
|
||||
if (in_array($unitNorm, ['kwh', 'wh', 'mwh', 'm3', 'l'], true)) {
|
||||
return [
|
||||
'field' => 'total_value',
|
||||
'value' => $value,
|
||||
'unit' => $suffix !== '' ? trim($suffix) : $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
if (in_array($unitNorm, ['kw', 'w', 'mw'], true)) {
|
||||
return [
|
||||
'field' => 'power_value',
|
||||
'value' => $value,
|
||||
'unit' => $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
if (in_array($unitNorm, ['m3/h', 'l/h', 'l/min'], true)) {
|
||||
return [
|
||||
'field' => 'flow_value',
|
||||
'value' => $value,
|
||||
'unit' => $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
if ($unitNorm === 'a') {
|
||||
return [
|
||||
'field' => 'current_value',
|
||||
'value' => $value,
|
||||
'unit' => $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
if ($unitNorm === 'v') {
|
||||
return [
|
||||
'field' => 'voltage_value',
|
||||
'value' => $value,
|
||||
'unit' => $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
if ($unitNorm === 'hz') {
|
||||
return [
|
||||
'field' => 'frequency_value',
|
||||
'value' => $value,
|
||||
'unit' => $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
if (in_array($unitNorm, ['bar', 'mbar', 'pa'], true)) {
|
||||
if ($this->looksLikeIn($varName)) {
|
||||
return [
|
||||
'field' => 'pressure_in_value',
|
||||
'value' => $value,
|
||||
'unit' => $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->looksLikeOut($varName)) {
|
||||
return [
|
||||
'field' => 'pressure_out_value',
|
||||
'value' => $value,
|
||||
'unit' => $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'field' => 'pressure_auto',
|
||||
'value' => $value,
|
||||
'unit' => $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
if (in_array($unitNorm, ['°c', 'c', 'k'], true)) {
|
||||
if ($this->looksLikeIn($varName)) {
|
||||
return [
|
||||
'field' => 'temperature_in_value',
|
||||
'value' => $value,
|
||||
'unit' => $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->looksLikeOut($varName)) {
|
||||
return [
|
||||
'field' => 'temperature_out_value',
|
||||
'value' => $value,
|
||||
'unit' => $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'field' => 'temperature_auto',
|
||||
'value' => $value,
|
||||
'unit' => $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
if ($unitNorm === 'cos' || $unitNorm === 'cosphi' || $unitNorm === 'pf') {
|
||||
return [
|
||||
'field' => 'power_factor',
|
||||
'value' => $value,
|
||||
'unit' => $unitNorm,
|
||||
'name' => $varName
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function assignInOutValues(array &$counterData, array $items, string $fieldIn, string $fieldOut): void
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
if ($this->looksLikeIn($item['name']) && !isset($counterData[$fieldIn])) {
|
||||
$counterData[$fieldIn] = $item['value'];
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->looksLikeOut($item['name']) && !isset($counterData[$fieldOut])) {
|
||||
$counterData[$fieldOut] = $item['value'];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($items as $item) {
|
||||
if (!isset($counterData[$fieldIn])) {
|
||||
$counterData[$fieldIn] = $item['value'];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($counterData[$fieldOut])) {
|
||||
$counterData[$fieldOut] = $item['value'];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function DetectCounterType(array $counterData): string
|
||||
{
|
||||
$unit = isset($counterData['unit']) ? $this->normalizeUnit((string) $counterData['unit']) : '';
|
||||
|
||||
if (isset($counterData['voltage_value']) || isset($counterData['current_value']) || isset($counterData['frequency_value']) || isset($counterData['power_factor'])) {
|
||||
return 'electricity';
|
||||
}
|
||||
|
||||
if (isset($counterData['temperature_in_value']) || isset($counterData['temperature_out_value'])) {
|
||||
return 'heat';
|
||||
}
|
||||
|
||||
if ($unit === 'm3' || $unit === 'l') {
|
||||
return 'water';
|
||||
}
|
||||
|
||||
if ($unit === 'kwh' || $unit === 'mwh' || $unit === 'wh') {
|
||||
if (isset($counterData['temperature_in_value']) || isset($counterData['flow_value'])) {
|
||||
return 'heat';
|
||||
}
|
||||
|
||||
return 'electricity';
|
||||
}
|
||||
|
||||
return 'other';
|
||||
}
|
||||
|
||||
private function inferDefaultUnit(array $counterData): string
|
||||
{
|
||||
if (isset($counterData['total_value'])) {
|
||||
if ($counterData['type'] === 'water') {
|
||||
return 'm3';
|
||||
}
|
||||
|
||||
return 'kWh';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private function looksLikeIn(string $name): bool
|
||||
{
|
||||
return strpos($name, 'vorlauf') !== false
|
||||
|| strpos($name, 'vl') !== false
|
||||
|| strpos($name, 'flow') !== false
|
||||
|| strpos($name, 'ein') !== false
|
||||
|| strpos($name, 'in') !== false;
|
||||
}
|
||||
|
||||
private function looksLikeOut(string $name): bool
|
||||
{
|
||||
return strpos($name, 'ruecklauf') !== false
|
||||
|| strpos($name, 'rücklauf') !== false
|
||||
|| strpos($name, 'rl') !== false
|
||||
|| strpos($name, 'return') !== false
|
||||
|| strpos($name, 'aus') !== false
|
||||
|| strpos($name, 'out') !== false;
|
||||
}
|
||||
|
||||
private function normalizeUnit(string $unit): string
|
||||
{
|
||||
$unit = mb_strtolower(trim($unit));
|
||||
$unit = str_replace([' ', '°'], ['', '°'], $unit);
|
||||
$unit = str_replace(['m³', '㎥'], 'm3', $unit);
|
||||
return $unit;
|
||||
}
|
||||
|
||||
private function makeSlug(string $text): string
|
||||
{
|
||||
$text = mb_strtolower($text);
|
||||
$text = str_replace(['ä', 'ö', 'ü', 'ß'], ['ae', 'oe', 'ue', 'ss'], $text);
|
||||
$text = preg_replace('/[^a-z0-9]+/u', '_', $text);
|
||||
$text = trim($text, '_');
|
||||
|
||||
if ($text === '') {
|
||||
$text = 'counter_' . time();
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"elements": [
|
||||
{
|
||||
"type": "SelectInstance",
|
||||
"name": "Connector",
|
||||
"caption": "DB-Connector",
|
||||
"validModules": ["{7B420C9A-F0FF-4C65-925D-6FEE0D8F1A55}"]
|
||||
},
|
||||
{
|
||||
"type": "SelectVariable",
|
||||
"name": "SourceJSON",
|
||||
"caption": "JSON-Datenquelle",
|
||||
"validVariableTypes": [3]
|
||||
},
|
||||
{
|
||||
"type": "NumberSpinner",
|
||||
"name": "UpdateTime",
|
||||
"caption": "Aktualisierungszeit (Sekunden)",
|
||||
"digits": 0
|
||||
}
|
||||
],
|
||||
"actions": [],
|
||||
"status": []
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "{D0DA85AB-1BAD-C36C-A3FD-1C2660F96F1C}",
|
||||
"name": "CounterTable",
|
||||
"name": "CounterServer",
|
||||
"type": 3,
|
||||
"vendor": "J.H. Artworks",
|
||||
"aliases":
|
||||
@@ -10,5 +10,5 @@
|
||||
"parentRequirements": [],
|
||||
"childRequirements": [],
|
||||
"implemented": [],
|
||||
"prefix": "CT"
|
||||
"prefix": "SECS"
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
class CounterServer extends IPSModule
|
||||
{
|
||||
public function Create()
|
||||
{
|
||||
parent::Create();
|
||||
|
||||
$this->RegisterPropertyInteger('Connector', 0);
|
||||
$this->RegisterPropertyInteger('SourceJSON', 0);
|
||||
$this->RegisterPropertyInteger('UpdateTime', 60);
|
||||
|
||||
$this->RegisterTimer('Update', 0, 'SECT_checkTable($_IPS[\'TARGET\']);');
|
||||
}
|
||||
|
||||
public function ApplyChanges()
|
||||
{
|
||||
parent::ApplyChanges();
|
||||
|
||||
$updateTime = $this->ReadPropertyInteger('UpdateTime');
|
||||
if ($updateTime < 1) {
|
||||
$updateTime = 60;
|
||||
}
|
||||
|
||||
$this->SetTimerInterval('Update', $updateTime * 1000);
|
||||
$this->checkTable();
|
||||
}
|
||||
|
||||
public function checkTable()
|
||||
{
|
||||
$sqlId = $this->ReadPropertyInteger('Connector');
|
||||
$jsonVar = $this->ReadPropertyInteger('SourceJSON');
|
||||
|
||||
if ($sqlId <= 0 || $jsonVar <= 0) {
|
||||
IPS_LogMessage('CounterTable', 'Config fehlt.');
|
||||
return;
|
||||
}
|
||||
|
||||
$jsonString = GetValueString($jsonVar);
|
||||
if ($jsonString === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$payload = json_decode($jsonString, true);
|
||||
if (!is_array($payload)) {
|
||||
IPS_LogMessage('CounterTable', 'JSON Fehler');
|
||||
return;
|
||||
}
|
||||
|
||||
$clientId = (string)$this->InstanceID;
|
||||
$clientName = IPS_GetName($this->InstanceID);
|
||||
|
||||
$timestamp = $payload['timestamp'] ?? date('Y-m-d H:i:s');
|
||||
$counters = $payload['counters'] ?? [];
|
||||
|
||||
foreach ($counters as $c) {
|
||||
|
||||
$counterId = $c['id'] ?? '';
|
||||
if ($counterId === '') continue;
|
||||
|
||||
$counterName = $c['name'] ?? $counterId;
|
||||
$type = $c['type'] ?? 'other';
|
||||
$unit = $c['unit'] ?? 'kWh';
|
||||
$projectId = isset($c['project_id']) ? (int)$c['project_id'] : 'NULL';
|
||||
|
||||
// ---------- UPSERT ----------
|
||||
$sql = "
|
||||
INSERT INTO meter_devices
|
||||
(project_id, client_id, counter_id, meter_uuid, meter_name, external_id, meter_type, billing_unit, description, is_active)
|
||||
VALUES
|
||||
(
|
||||
" . ($projectId === 'NULL' ? 'NULL' : $projectId) . ",
|
||||
'" . $this->esc($clientId) . "',
|
||||
'" . $this->esc($counterId) . "',
|
||||
'" . $this->esc($clientId . '_' . $counterId) . "',
|
||||
'" . $this->esc($counterName) . "',
|
||||
'" . $this->esc($counterId) . "',
|
||||
'" . $this->esc($type) . "',
|
||||
'" . $this->esc($unit) . "',
|
||||
'" . $this->esc('Client: ' . $clientName) . "',
|
||||
1
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
meter_name = VALUES(meter_name),
|
||||
meter_type = VALUES(meter_type),
|
||||
billing_unit = VALUES(billing_unit),
|
||||
is_active = 1
|
||||
";
|
||||
|
||||
MySQL_ExecuteSimple($sqlId, $sql);
|
||||
|
||||
// ---------- GET meter_id ----------
|
||||
$sqlGet = "
|
||||
SELECT id FROM meter_devices
|
||||
WHERE client_id = '" . $this->esc($clientId) . "'
|
||||
AND counter_id = '" . $this->esc($counterId) . "'
|
||||
LIMIT 1
|
||||
";
|
||||
|
||||
$res = MySQL_ExecuteSimple($sqlId, $sqlGet);
|
||||
|
||||
if (!is_array($res) || count($res) === 0) {
|
||||
IPS_LogMessage('CounterTable', 'Kein meter_id gefunden');
|
||||
continue;
|
||||
}
|
||||
|
||||
$meterId = (int)$res[0]['id'];
|
||||
|
||||
// ---------- INSERT measurement ----------
|
||||
$sqlInsert = "
|
||||
INSERT INTO meter_measurements
|
||||
(
|
||||
meter_id, measured_at,
|
||||
total_value, consumption_value,
|
||||
power_value, flow_value,
|
||||
current_value, voltage_value,
|
||||
temperature_in_value, temperature_out_value,
|
||||
pressure_in_value, pressure_out_value,
|
||||
frequency_value, power_factor
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
" . $meterId . ",
|
||||
'" . $this->esc($timestamp) . "',
|
||||
" . $this->f($c, 'total_value') . ",
|
||||
" . $this->f($c, 'consumption_value') . ",
|
||||
" . $this->f($c, 'power_value') . ",
|
||||
" . $this->f($c, 'flow_value') . ",
|
||||
" . $this->f($c, 'current_value') . ",
|
||||
" . $this->f($c, 'voltage_value') . ",
|
||||
" . $this->f($c, 'temperature_in_value') . ",
|
||||
" . $this->f($c, 'temperature_out_value') . ",
|
||||
" . $this->f($c, 'pressure_in_value') . ",
|
||||
" . $this->f($c, 'pressure_out_value') . ",
|
||||
" . $this->f($c, 'frequency_value') . ",
|
||||
" . $this->f($c, 'power_factor') . "
|
||||
)
|
||||
";
|
||||
|
||||
MySQL_ExecuteSimple($sqlId, $sqlInsert);
|
||||
}
|
||||
}
|
||||
|
||||
private function f($arr, $key)
|
||||
{
|
||||
if (!isset($arr[$key]) || $arr[$key] === '' || $arr[$key] === null) {
|
||||
return 'NULL';
|
||||
}
|
||||
|
||||
if (is_numeric($arr[$key])) {
|
||||
return str_replace(',', '.', (string)$arr[$key]);
|
||||
}
|
||||
|
||||
return 'NULL';
|
||||
}
|
||||
|
||||
private function esc($v)
|
||||
{
|
||||
return str_replace(
|
||||
['\\', "'", '"'],
|
||||
['\\\\', "\\'", '\\"'],
|
||||
$v
|
||||
);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,89 +0,0 @@
|
||||
{
|
||||
"elements":
|
||||
[
|
||||
{ "type": "NumberSpinner", "Name": "Price", "caption": "Strompreis", "digits": 2},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "Counters",
|
||||
"caption": "Zählerliste",
|
||||
"add": true,
|
||||
"delete": true,
|
||||
"sort": {
|
||||
"column": "Name",
|
||||
"direction": "ascending"
|
||||
},
|
||||
"columns": [
|
||||
{
|
||||
"caption": "Name",
|
||||
"name": "Name",
|
||||
"width": "100px",
|
||||
"edit": {
|
||||
"type": "ValidationTextBox"
|
||||
},
|
||||
"add": ""
|
||||
},
|
||||
{
|
||||
"caption": "Gesamtverbrauch",
|
||||
"name": "Total",
|
||||
"width": "100px",
|
||||
"edit": {
|
||||
"type": "SelectVariable",
|
||||
"validVariableTypes": [2]
|
||||
},
|
||||
"add": 0
|
||||
},
|
||||
{
|
||||
"caption": "Monatsverbrauch",
|
||||
"name": "Monthly",
|
||||
"width": "100px",
|
||||
"edit": {
|
||||
"type": "SelectVariable",
|
||||
"validVariableTypes": [2]
|
||||
},
|
||||
"add": 0
|
||||
},
|
||||
{
|
||||
"caption": "Wochenverbrauch",
|
||||
"name": "Weekly",
|
||||
"width": "100px",
|
||||
"edit": {
|
||||
"type": "SelectVariable",
|
||||
"validVariableTypes": [2]
|
||||
},
|
||||
"add": 0
|
||||
},
|
||||
{
|
||||
"caption": "Tagesverbrauch",
|
||||
"name": "Daily",
|
||||
"width": "100px",
|
||||
"edit": {
|
||||
"type": "SelectVariable",
|
||||
"validVariableTypes": [2]
|
||||
},
|
||||
"add": 0
|
||||
},
|
||||
{
|
||||
"caption": "Limit",
|
||||
"name": "Limit",
|
||||
"width": "100px",
|
||||
"edit": {
|
||||
"type": "NumberSpinner",
|
||||
"digits": 2
|
||||
},
|
||||
"add": 0.1
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
],
|
||||
"actions":
|
||||
[
|
||||
|
||||
],
|
||||
"status":
|
||||
[
|
||||
|
||||
]
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
<?
|
||||
// Klassendefinition
|
||||
class CounterTable extends IPSModule {
|
||||
// Überschreibt die interne IPS_Create($id) Funktion
|
||||
public function Create() {
|
||||
// Diese Zeile nicht löschen.
|
||||
parent::Create();
|
||||
|
||||
|
||||
$this->RegisterPropertyFloat("Price",0.23);
|
||||
$this->RegisterPropertyString("Counters","");
|
||||
|
||||
$this->RegisterVariableString("htmlOutput", "Zählerübersicht",["PRESENTATION"=> VARIABLE_PRESENTATION_LEGACY, "PROFILE" => "~HTMLBox"],0);
|
||||
|
||||
}
|
||||
|
||||
// Überschreibt die intere IPS_ApplyChanges($id) Funktion
|
||||
public function ApplyChanges() {
|
||||
// Diese Zeile nicht löschen
|
||||
parent::ApplyChanges();
|
||||
$this->checkTable();
|
||||
|
||||
|
||||
}
|
||||
public function RequestAction($Ident, $Value) {
|
||||
$varid = $this->GetIDForIdent($Ident);
|
||||
SetValue($varid, $Value);
|
||||
}
|
||||
|
||||
|
||||
public function checkTable(){
|
||||
$price = $this->ReadPropertyFloat("Price");
|
||||
|
||||
|
||||
$arrString = $this->ReadPropertyString("Counters");
|
||||
$arr = json_decode($arrString);
|
||||
|
||||
|
||||
$dataoutput = "";
|
||||
/// print_r($arr);
|
||||
|
||||
if($arr != NULL){
|
||||
foreach($arr as $cnt){
|
||||
|
||||
$cost = 0.0;
|
||||
$cost = $cnt->Monthly * $price;
|
||||
$style ='';
|
||||
if ($cnt->Monthly > $cnt->Limit){
|
||||
$style = 'style="background-color:yellow;"';
|
||||
}
|
||||
|
||||
$dataoutput .= '
|
||||
<tr '.$style.'>
|
||||
|
||||
<td style="text-align:left;">
|
||||
'.$cnt->Name.'
|
||||
</td>
|
||||
|
||||
<td>
|
||||
'.$cnt->Total.' kWh
|
||||
</td>
|
||||
|
||||
<td>
|
||||
'.$cnt->Monthly.' kWh
|
||||
</td>
|
||||
|
||||
<td>
|
||||
'.$cnt->Weekly.' kWh
|
||||
</td>
|
||||
|
||||
<td>
|
||||
'.$cnt->Daily.' kWh
|
||||
</td>
|
||||
|
||||
<td>
|
||||
'.$cost.'€
|
||||
</td>
|
||||
|
||||
</tr>';
|
||||
|
||||
}
|
||||
}
|
||||
$this->createTable($dataoutput);
|
||||
|
||||
/*
|
||||
|
||||
Array
|
||||
(
|
||||
[0] => stdClass Object
|
||||
(
|
||||
[Name] => Blub
|
||||
[Total] => 49294
|
||||
[Monthly] => 49294
|
||||
[Weekly] => 49294
|
||||
[Daily] => 49294
|
||||
[Limit] => 0.1
|
||||
)
|
||||
|
||||
)
|
||||
(Code: -32603)
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function createTable($data)
|
||||
{
|
||||
$htmlprefix =' <html>
|
||||
<style>
|
||||
table, td {
|
||||
|
||||
border-collapse: separate;
|
||||
border-spacing: 5px;
|
||||
}
|
||||
|
||||
td {
|
||||
color:#000000;
|
||||
font-family:Arial;
|
||||
font-size:14pt;
|
||||
width:150px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
th {
|
||||
color:#000000;
|
||||
font-family:Arial;
|
||||
font-size:14pt;
|
||||
width:150px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<table style="hight:100%;background-color:lightgrey;border:2px solid green;">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="">
|
||||
Name:
|
||||
</th>
|
||||
|
||||
<th>
|
||||
Gesamt:
|
||||
</th>
|
||||
|
||||
<th>
|
||||
Monat:
|
||||
</th>
|
||||
|
||||
<th>
|
||||
Woche:
|
||||
</th>
|
||||
|
||||
<th>
|
||||
Tag:
|
||||
</th>
|
||||
|
||||
<th>
|
||||
Kosten:
|
||||
</th>
|
||||
|
||||
|
||||
|
||||
|
||||
</tr>
|
||||
|
||||
</thead>
|
||||
';
|
||||
|
||||
$htmlsuffix = '
|
||||
|
||||
|
||||
<tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
';
|
||||
|
||||
SetValueString($this->GetIDForIdent("htmlOutput"),$htmlprefix.$data.$htmlsuffix);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
+1
-1
@@ -8,6 +8,6 @@
|
||||
"date": 1491343200
|
||||
},
|
||||
"version": "1.0",
|
||||
"build": 9,
|
||||
"build": 0,
|
||||
"date": 0
|
||||
}
|
||||
Reference in New Issue
Block a user