Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 55 additions & 13 deletions Home Connect Device/module.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ public function Create()

$this->ConnectParent('{CE76810D-B685-9BE0-CC04-38B204DEAD5E}');

$parent = IPS_GetInstance($this->InstanceID)['ConnectionID'];
if (IPS_InstanceExists($parent)) {
$this->RegisterMessage($parent, IM_CHANGESTATUS);
}
$this->RegisterMessage($this->InstanceID, FM_CONNECT);
$this->RegisterMessage($this->InstanceID, FM_DISCONNECT);

$this->RegisterPropertyString('HaID', '');
$this->RegisterPropertyString('DeviceType', '');

Expand Down Expand Up @@ -122,18 +129,37 @@ public function ApplyChanges()
parent::ApplyChanges();

if (IPS_GetKernelRunlevel() === KR_READY) {
if ($this->HasActiveParent() && $this->ReadPropertyString('HaID')) {
$this->SetSummary($this->ReadPropertyString('HaID'));
$this->InitializeDevice();
$this->SetStatus(IS_ACTIVE);
} else {
$this->SetStatus(IS_INACTIVE);
}
$this->refreshDeviceState(true);
}

$this->SetReceiveDataFilter('.*' . $this->ReadPropertyString('HaID') . '.*');
}

public function MessageSink($Timestamp, $SenderID, $MessageID, $Data)
{
//Never delete this line!
parent::MessageSink($Timestamp, $SenderID, $MessageID, $Data);

$parentID = IPS_GetInstance($this->InstanceID)['ConnectionID'];
if ($SenderID == $parentID && $MessageID == IM_CHANGESTATUS) {
$this->refreshDeviceState($Data[0] == IS_ACTIVE);
return;
}

if ($SenderID == $this->InstanceID) {
switch ($MessageID) {
case FM_CONNECT:
$this->RegisterMessage($Data[0], IM_CHANGESTATUS);
$this->refreshDeviceState(true);
return;

case FM_DISCONNECT:
$this->SetStatus(IS_INACTIVE);
return;
}
}
}

public function ReceiveData($String)
{
$this->SendDebug('ReceiveData', $String, 0);
Expand Down Expand Up @@ -412,6 +438,20 @@ public function RequestDataFromParent(string $endpoint, string $payload = '')
return $response;
}

private function refreshDeviceState(bool $initializeDevice): void
{
if ($this->HasActiveParent() && $this->ReadPropertyString('HaID')) {
$this->SetSummary($this->ReadPropertyString('HaID'));
if ($initializeDevice) {
$this->InitializeDevice();
}
$this->SetStatus(IS_ACTIVE);
return;
}

$this->SetStatus(IS_INACTIVE);
}

private function createPrograms()
{
$rawPrograms = json_decode($this->RequestDataFromParent('homeappliances/' . $this->ReadPropertyString('HaID') . '/programs'), true);
Expand Down Expand Up @@ -921,12 +961,12 @@ private function createVariableFromConstraints($profileName, $data, $attribute,
switch ($variableType) {
case VARIABLETYPE_INTEGER:
case VARIABLETYPE_FLOAT:
$constraints = $data['constraints'];
$constraints = isset($data['constraints']) && is_array($data['constraints']) ? $data['constraints'] : [];
if (!IPS_VariableProfileExists($profileName)) {
//Create profile
IPS_CreateVariableProfile($profileName, $variableType);
}
IPS_SetVariableProfileText($profileName, '', ' ' . $data['unit']);
IPS_SetVariableProfileText($profileName, '', isset($data['unit']) ? ' ' . $data['unit'] : '');
$min = isset($constraints['min']) ? $constraints['min'] : 0;
$max = isset($constraints['max']) ? $constraints['max'] : 86340;
IPS_SetVariableProfileValues($profileName, $min, $max, isset($constraints['stepsize']) ? $constraints['stepsize'] : 1);
Expand All @@ -938,17 +978,19 @@ private function createVariableFromConstraints($profileName, $data, $attribute,
break;

default:
$constraints = $data['constraints'];
$constraints = isset($data['constraints']) && is_array($data['constraints']) ? $data['constraints'] : [];
$variableType = VARIABLETYPE_STRING;
if (!IPS_VariableProfileExists($profileName)) {
//Create profile
IPS_CreateVariableProfile($profileName, $variableType);
}
//Add potential new options
$newAssociations = [];
for ($i = 0, $size = count($constraints['allowedvalues']); $i < $size; $i++) {
$displayName = isset($constraints['displayvalues'][$i]) ? $constraints['displayvalues'][$i] : $this->getLastSnippet($constraints['allowedvalues'][$i]);
$newAssociations[$constraints['allowedvalues'][$i]] = $displayName;
$allowedValues = isset($constraints['allowedvalues']) && is_array($constraints['allowedvalues']) ? $constraints['allowedvalues'] : [];
$displayValues = isset($constraints['displayvalues']) && is_array($constraints['displayvalues']) ? $constraints['displayvalues'] : [];
for ($i = 0, $size = count($allowedValues); $i < $size; $i++) {
$displayName = isset($displayValues[$i]) ? $displayValues[$i] : $this->getLastSnippet($allowedValues[$i]);
$newAssociations[$allowedValues[$i]] = $displayName;
}
$newAssociations = $this->sortAssociations($data['key'], $newAssociations);

Expand Down
56 changes: 53 additions & 3 deletions tests/HomeConnectOvenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,18 @@ public function testBaseFunctionality()
IPS_SetProperty($oven, 'HaID', 'SIEMENS-HB676G5S6-68A40E2F702D');
IPS_SetProperty($oven, 'DeviceType', 'Oven');
IPS_ApplyChanges($oven);

$intf = IPS\InstanceManager::getInstanceInterface($oven);
$intf->ReceiveData($this->generateTestData(52));
$initialVar = IPS_GetObjectIDByIdent('CurrentCavityTemperature', $oven);
$this->assertEquals(VARIABLETYPE_INTEGER, $this->getValueType($oven));

$intf = IPS\InstanceManager::getInstanceInterface($oven);
$intf->ReceiveData($this->generateTestData(50.99));
$newFloat = IPS_GetObjectIDByIdent('CurrentCavityTemperature', $oven);
$this->assertNotEquals($newFloat, $initialVar);
$this->assertEquals(VARIABLETYPE_FLOAT, $this->getValueType($oven));

$intf->ReceiveData($this->generateTestData(52));
$intf->ReceiveData($this->generateTestData(54));
$this->assertEquals($newFloat, IPS_GetObjectIDByIdent('CurrentCavityTemperature', $oven));
$this->assertEquals(VARIABLETYPE_FLOAT, $this->getValueType($oven));

Expand All @@ -59,6 +61,54 @@ public function testBaseFunctionality()
$this->assertEquals(VARIABLETYPE_FLOAT, $this->getValueType($oven));
}

public function testReactivatesAfterParentStatusChange()
{
$oven = IPS_CreateInstance('{F29DF312-A62E-9989-1F1A-0D1E1D171AD3}');
$parent = IPS_GetInstance($oven)['ConnectionID'];

IPS\InstanceManager::setStatus($parent, IS_INACTIVE);

IPS_SetProperty($oven, 'HaID', 'SIEMENS-HB676G5S6-68A40E2F702D');
IPS_SetProperty($oven, 'DeviceType', 'Oven');
IPS_ApplyChanges($oven);

$this->assertEquals(IS_INACTIVE, IPS_GetInstance($oven)['InstanceStatus']);

IPS\InstanceManager::setStatus($parent, IS_ACTIVE);
$intf = IPS\InstanceManager::getInstanceInterface($oven);
$intf->MessageSink(0, $parent, IM_CHANGESTATUS, [IS_ACTIVE]);

$this->assertEquals(IS_ACTIVE, IPS_GetInstance($oven)['InstanceStatus']);
}

public function testStringSettingWithoutAllowedValuesDoesNotCrash()
{
$oven = IPS_CreateInstance('{F29DF312-A62E-9989-1F1A-0D1E1D171AD3}');
$intf = IPS\InstanceManager::getInstanceInterface($oven);

$method = new ReflectionMethod($intf, 'createVariableFromConstraints');
$method->setAccessible(true);
$method->invoke(
$intf,
'HomeConnect.Test.StringSetting',
[
'key' => 'Dishcare.Dishwasher.Setting.ProgramInfo',
'name' => 'Program Info',
'type' => 'String',
'constraints' => [
'access' => 'readWrite'
]
],
'Setting',
1
);

$variableID = IPS_GetObjectIDByIdent('ProgramInfo', $oven);
$this->assertNotFalse($variableID);
$this->assertEquals(VARIABLETYPE_STRING, IPS_GetVariable($variableID)['VariableType']);
$this->assertCount(0, IPS_GetVariableProfile('HomeConnect.Test.StringSetting')['Associations']);
}

private function generateTestData($tempValue)
{
$data = [
Expand Down Expand Up @@ -124,4 +174,4 @@ private function getChildrenValues($id)
}
return $result;
}
}
}