'symcon', 'kind' => 'rpc', 'component' => null], \ShellyParser::parseTopic('symcon/events/rpc') ); self::assertSame( ['deviceTopic' => 'building/floor/device-1', 'kind' => 'component_status', 'component' => 'pm1:0'], \ShellyParser::parseTopic('building/floor/device-1/status/pm1:0') ); } public function testNotifyStatusIsFlattenedWithoutKnowingTheDeviceModel(): void { $points = \ShellyParser::pointsFromRpc([ 'src' => 'custom-source', 'method' => 'NotifyStatus', 'params' => [ 'switch:0' => [ 'output' => true, 'apower' => 12.4, 'aenergy' => ['total' => 42.5, 'by_minute' => [1, 2, 3]], ], 'humidity:0' => ['rh' => 56.2], ], ]); self::assertContains(['component' => 'switch:0', 'path' => 'output', 'value' => true], $points); self::assertContains(['component' => 'switch:0', 'path' => 'apower', 'value' => 12.4], $points); self::assertContains(['component' => 'switch:0', 'path' => 'aenergy.total', 'value' => 42.5], $points); self::assertContains(['component' => 'switch:0', 'path' => 'aenergy.by_minute', 'value' => '[1,2,3]'], $points); self::assertContains(['component' => 'humidity:0', 'path' => 'rh', 'value' => 56.2], $points); } public function testGroupsSeparateOutputsMetersAndSensors(): void { self::assertSame('switches', \ShellyParser::groupForPoint('switch:0', 'output')); self::assertSame('power', \ShellyParser::groupForPoint('switch:0', 'apower')); self::assertSame('energy', \ShellyParser::groupForPoint('emdata:0', 'a_total_act_energy')); self::assertSame('humidity', \ShellyParser::groupForPoint('humidity:0', 'rh')); self::assertSame('covers', \ShellyParser::groupForPoint('cover:0', 'current_pos')); self::assertSame('other', \ShellyParser::groupForPoint('future:7', 'new_value')); } public function testNotifyEventsAreMappedToTheirComponent(): void { $points = \ShellyParser::pointsFromRpc([ 'method' => 'NotifyEvent', 'params' => [ 'events' => [[ 'component' => 'input:0', 'event' => 'single_push', 'ts' => 123.5, ]], ], ]); self::assertContains( ['component' => 'input:0', 'path' => 'event.event', 'value' => 'single_push'], $points ); } public function testNumericMeasurementsUseFloatVariables(): void { self::assertSame(2, \ShellyParser::variableType(0, 'apower')); self::assertSame(1, \ShellyParser::variableType(123, 'uptime')); self::assertSame(1, \ShellyParser::variableType(123.5, 'ts')); self::assertSame(0, \ShellyParser::variableType(true, 'output')); self::assertSame(3, \ShellyParser::variableType('open', 'state')); } public function testConfigurationOffersAllDataPointGroups(): void { $json = file_get_contents(__DIR__ . '/../ShellyModul/form.json'); self::assertNotFalse($json); $form = json_decode($json, true, 512, JSON_THROW_ON_ERROR); $encoded = json_encode($form, JSON_THROW_ON_ERROR); foreach ([ 'CreateOnline', 'CreateDeviceInfo', 'CreateInputs', 'CreateSwitches', 'CreateCovers', 'CreateLights', 'CreatePower', 'CreateVoltage', 'CreateCurrent', 'CreateEnergy', 'CreateFrequency', 'CreatePowerFactor', 'CreateMeterDetails', 'CreateTemperature', 'CreateHumidity', 'CreateIlluminance', 'CreateBattery', 'CreateEnvironment', 'CreateSystem', 'CreateOther', ] as $property) { self::assertStringContainsString($property, $encoded); } } }