├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── build.xml ├── composer.json ├── composer.lock ├── phpunit.xml ├── src ├── APS │ └── APSFrame.php ├── AbstractFrame.php ├── Buffer.php ├── Exception │ └── ZigbeeException.php ├── IFrame.php ├── SMS │ ├── SMSFrame.php │ └── SMSTazBlock.php ├── ZCL │ ├── AbstractCluster.php │ ├── Cluster.php │ ├── ClusterFactory.php │ ├── General │ │ ├── AttributeIdentifier.php │ │ ├── AttributeInformation.php │ │ ├── AttributeRecord.php │ │ ├── AttributeReport.php │ │ ├── AttributeReportingConfigurationRecord.php │ │ ├── AttributeReportingConfigurationStatusRecord.php │ │ ├── AttributeStatusRecord.php │ │ ├── ConfigureReportingCommand.php │ │ ├── ConfigureReportingResponseCommand.php │ │ ├── DefaultResponseCommand.php │ │ ├── DiscoverAttributesCommand.php │ │ ├── DiscoverAttributesResponseCommand.php │ │ ├── GeneralCommand.php │ │ ├── ReadAttributesCommand.php │ │ ├── ReadAttributesResponseCommand.php │ │ ├── ReadAttributesStatusRecord.php │ │ ├── ReadAttributesStructuredCommand.php │ │ ├── ReadReportingConfigurationCommand.php │ │ ├── ReadReportingConfigurationResponseCommand.php │ │ ├── ReportAttributesCommand.php │ │ ├── WriteAttributeRecord.php │ │ ├── WriteAttributeStatusRecord.php │ │ ├── WriteAttributesCommand.php │ │ ├── WriteAttributesResponseCommand.php │ │ ├── WriteAttributesStructuredCommand.php │ │ ├── WriteAttributesStructuredResponseCommand.php │ │ └── WriteAttributesUndividedCommand.php │ ├── IAS_Zone │ │ ├── IAS_Zone.php │ │ ├── ZoneStatus.php │ │ └── ZoneStatusChangeNotificationCommand.php │ ├── IZCLCommandFrame.php │ ├── ZCLFrame.php │ └── ZCLStatus.php └── ZDP │ ├── Command.php │ ├── Discovery │ ├── AbstractAddrRspCommand.php │ ├── AbstractNWKAddrOfInterestReqCommand.php │ ├── ActiveEPReqCommand.php │ ├── ActiveEPRspCommand.php │ ├── ExtendedSimpleDescReqCommand.php │ ├── ExtendedSimpleDescRspCommand.php │ ├── IEEEAddrReqCommand.php │ ├── IEEEAddrRspCommand.php │ ├── NodeDescReqCommand.php │ ├── NodeDescRspCommand.php │ ├── NodeDescriptor.php │ ├── NodePowerDescriptor.php │ ├── NwkAddrReqCommand.php │ ├── NwkAddrRspCommand.php │ ├── PowerDescReqCommand.php │ ├── PowerDescRspCommand.php │ ├── SimpleDescReqCommand.php │ ├── SimpleDescRspCommand.php │ ├── SimpleDescriptor.php │ ├── UserDescConfCommand.php │ ├── UserDescReqCommand.php │ ├── UserDescRspCommand.php │ ├── UserDescSetCommand.php │ └── UserDescriptor.php │ ├── IZDPCommandFrame.php │ ├── Network │ ├── AbstractStartIndexReqCommand.php │ ├── MgmtBindReqCommand.php │ ├── MgmtCacheReqCommand.php │ ├── MgmtLqiReqCommand.php │ ├── MgmtLqiRspCommand.php │ ├── MgmtRtgReqCommand.php │ ├── MgmtRtgRspCommand.php │ ├── NeighborDescriptor.php │ └── RoutingDescriptor.php │ ├── Status.php │ └── ZDPFrame.php └── tests ├── APS └── APSFrameTest.php ├── ZCL ├── ClusterFactoryTest.php ├── General │ ├── AttributeInformationTest.php │ ├── AttributeRecordTest.php │ ├── AttributeReportingConfigurationRecordTest.php │ ├── AttributeReportingConfigurationStatusRecordTest.php │ ├── ConfigureReportingCommandTest.php │ ├── ConfigureReportingResponseCommandTest.php │ ├── DiscoverAttributesCommandTest.php │ ├── DiscoverAttributesResponseCommandTest.php │ ├── GeneralCommandTest.php │ ├── ReadAttributesCommandTest.php │ ├── ReadAttributesResponseCommandTest.php │ ├── ReadReportingConfigurationCommandTest.php │ ├── WriteAttributesCommandTest.php │ └── WriteAttributesResponseCommandTest.php ├── IAS_Zone │ ├── ZoneStatusChangeNotificationCommandTest.php │ └── ZoneStatusTest.php ├── ZCLFrameTest.php └── ZCLStatusTest.php └── ZDP ├── Discovery ├── ActiveEPRspCommandTest.php ├── ExtendedSimpleDescReqCommandTest.php ├── ExtendedSimpleDescRspCommandTest.php ├── IEEEAddrReqCommandTest.php ├── IEEEAddrRspCommandTest.php ├── NodeDescReqCommandTest.php ├── NodeDescRspCommandTest.php ├── NodeDescriptorTest.php ├── NodePowerDescriptorTest.php ├── NwkAddrReqCommandTest.php ├── NwkAddrRspCommandTest.php ├── PowerDescRspCommandTest.php ├── SimpleDescReqCommandTest.php ├── SimpleDescRspCommandTest.php ├── SimpleDescriptorTest.php ├── UserDescConfCommandTest.php ├── UserDescRspCommandTest.php ├── UserDescSetCommandTest.php └── UserDescriptorTest.php ├── Network ├── MgmtBindReqCommandTest.php ├── MgmtCacheReqCommandTest.php ├── MgmtLqiReqCommandTest.php ├── MgmtLqiRspCommandTest.php ├── MgmtRtgReqCommandTest.php ├── MgmtRtgRspCommandTest.php ├── NeighborDescriptorTest.php └── RoutingDescriptorTest.php └── ZDPFrameTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | *.svn* 2 | vendor/ 3 | .idea/ 4 | .build/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.4 5 | - 5.5 6 | - 5.6 7 | 8 | install: 9 | - composer install --no-interaction 10 | 11 | script: 12 | - ./vendor/bin/phpunit --coverage-text -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Munisense Zigbee Library 2 | 3 | ## PHP library for encoding and decoding ZigBee Frames 4 | This library contains classes that map to the various ZigBee frames. Each of those classes 5 | can be either constructed using a bytestring or using the getters/setters and static constructors. 6 | 7 | ### Using the library 8 | #### Installation 9 | The easiest way to use the library is to add it as dependency in the [composer.json](http://getcomposer.org) of your project. 10 | 11 | "require": { 12 | "munisense/zigbee": "~2.4", 13 | } 14 | 15 | Then run `composer update` and include the `vendor/autoload.php` in your project files, if not already. 16 | 17 | #### Use the ZigBee library to unpack ZigBee frames 18 | The library can be used to unpack a zigbee frame (for instance encoded in a base64 string) to the object model. 19 | 20 | $input = base64_decode("AP8AAAA="); 21 | $frame = new Munisense\Zigbee\ZCL\ZCLFrame($input); 22 | echo $frame; 23 | 24 | gives 25 | 26 | ZCLFrame (length: 5) 27 | |- FrameControl : 0b00000000 28 | | |- FrameType : Profile Wide (0x00) 29 | | |- ManufIdPres : Not Present (0x00) 30 | | |- Direction : Server->Client (0x00) 31 | | `- DefaultResp : Enabled (0x00) 32 | |- TransactionId : 0x8e 33 | |- CommandId : Read Attributes 34 | |- Payload (length: 2) 35 | `- Munisense\Zigbee\ZCL\General\ReadAttributesCommand (count: 1, length: 2) 36 | `- AttributeId: 0x0000 37 | 38 | #### Use the ZigBee library to pack ZigBee frames 39 | It is also possible to build a ZigBee frame using the objects, and extract the actual frame payload to send to the ZigBee network. 40 | 41 | $zcl = ReadAttributesCommand::construct([ 42 | AttributeIdentifier::construct(0x02), 43 | AttributeIdentifier::construct(0x0809) 44 | ]); 45 | 46 | $output = $zcl->getFrame(); 47 | 48 | ### Running the tests 49 | To run the tests you need phpunit installed. Instead of downloading the library as requirement for a project using Composer (and Packagist) you should have a clone of the library itself. Make sure you've ran `composer install`. 50 | 51 | After that it is as simple as calling `phpunit` in the root folder everytime you want to run the tests. 52 | 53 | ### Travis Continuous Integration 54 | * Master [![Build Status](https://travis-ci.org/munisense/zigbee.svg?branch=master)](https://travis-ci.org/munisense/zigbee) 55 | * Stable [![Build Status](https://travis-ci.org/munisense/zigbee.svg?branch=stable)](https://travis-ci.org/munisense/zigbee) 56 | 57 | ### Revision History 58 | #### 2.4.0 59 | Added ZDP Discovery Commands 60 | * ExtendedSimpleDescReq and Rsp Command 61 | * UserDescConf and Set Command 62 | 63 | Added ZDP Network Commands 64 | * MgmtBindReq, MgmtCacheReqCommand 65 | * MmtLqiReq and Rsp Command, with NeighborDescriptor structure 66 | * MmtRtgReq and Rsp Command, with RoutingDescriptor structure 67 | 68 | #### 2.3.0 69 | Minor code organisation changes and added more ZDP Discovery functionality. 70 | * Renamed MuniZigbeeException to ZigbeeException 71 | * Removed Munisense specific frames 72 | * Added Node Descriptor + Commands 73 | * Added Power Descriptor + Commands 74 | * Added User Descriptor + Commands 75 | 76 | #### 2.2.0 77 | Added the following ZDP Commands: 78 | 79 | * ActiveEP Req and Rsp 80 | * IEEEAddr Req and Rsp 81 | * NodeDesc Req 82 | * NWKAddr Req and Rsp 83 | * PowerDesc Req 84 | * SimpleDesc Req and Rsp 85 | 86 | ### License 87 | 88 | Copyright 2014 Munisense BV 89 | 90 | Licensed under the Apache License, Version 2.0 (the "License"); 91 | you may not use this file except in compliance with the License. 92 | You may obtain a copy of the License at 93 | 94 | http://www.apache.org/licenses/LICENSE-2.0 95 | 96 | Unless required by applicable law or agreed to in writing, software 97 | distributed under the License is distributed on an "AS IS" BASIS, 98 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 99 | See the License for the specific language governing permissions and 100 | limitations under the License. 101 | 102 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 22 | 28 | 29 | 30 | 31 | 32 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 | 60 | 62 | 63 | 64 | 65 | 66 | 69 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "munisense/zigbee", 3 | "description": "Zigbee Frame Encoding/Decoding Library", 4 | "keywords": ["munisense", "zigbee","frame","encoding", "decoding","php"], 5 | "type": "library", 6 | "license": "Apache-2.0", 7 | "require": { 8 | "php": ">=5.4.0" 9 | }, 10 | "require-dev": { 11 | "phpunit/phpunit": "4.1.*" 12 | }, 13 | "autoload": { 14 | "psr-4": {"Munisense\\Zigbee\\": ["src/"]} 15 | }, 16 | "autoload-dev": { 17 | "psr-4": {"Munisense\\Zigbee\\": ["src/", "tests/"]} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | tests 6 | 7 | 8 | 9 | 10 | ignore 11 | 12 | 13 | 14 | 15 | src 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/AbstractFrame.php: -------------------------------------------------------------------------------- 1 | setFrame($frame); 18 | } 19 | 20 | public function displayFrame() 21 | { 22 | return Buffer::displayOctetString($this->getFrame()); 23 | } 24 | } -------------------------------------------------------------------------------- /src/Exception/ZigbeeException.php: -------------------------------------------------------------------------------- 1 | '\Munisense\Zigbee\ZCL\IAS_Zone\IAS_Zone', 21 | ); 22 | } -------------------------------------------------------------------------------- /src/ZCL/ClusterFactory.php: -------------------------------------------------------------------------------- 1 | setAttributeId($attribute_id); 16 | return $element; 17 | } 18 | 19 | public function setFrame($frame) 20 | { 21 | $this->setAttributeId(Buffer::unpackInt16u($frame)); 22 | } 23 | 24 | public function getFrame() 25 | { 26 | $frame = ""; 27 | 28 | Buffer::packInt16u($frame, $this->getAttributeId()); 29 | 30 | return $frame; 31 | } 32 | 33 | public function setAttributeId($attribute_id) 34 | { 35 | $attribute_id = intval($attribute_id); 36 | if($attribute_id < 0x00 || $attribute_id > 0xffff) 37 | throw new ZigbeeException("Invalid attribute id"); 38 | 39 | $this->attribute_id = $attribute_id; 40 | } 41 | 42 | public function getAttributeId() 43 | { 44 | return $this->attribute_id; 45 | } 46 | 47 | public function displayAttributeId() 48 | { 49 | return sprintf("0x%04x", $this->getAttributeId()); 50 | } 51 | 52 | public function __toString() 53 | { 54 | return "AttributeId: ".$this->displayAttributeId(); 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /src/ZCL/General/AttributeInformation.php: -------------------------------------------------------------------------------- 1 | setAttributeId($attribute_id); 17 | $element->setDatatypeId($datatype_id); 18 | return $element; 19 | } 20 | 21 | public function consumeFrame(&$frame) 22 | { 23 | $this->setAttributeId(Buffer::unpackInt16u($frame)); 24 | $this->setDatatypeId(Buffer::unpackInt8u($frame)); 25 | } 26 | 27 | public function setFrame($frame) 28 | { 29 | $this->consumeFrame($frame); 30 | } 31 | 32 | public function getFrame() 33 | { 34 | $frame = ""; 35 | 36 | Buffer::packInt16u($frame, $this->getAttributeId()); 37 | Buffer::packInt8u($frame, $this->getDatatypeId()); 38 | 39 | return $frame; 40 | } 41 | 42 | public function setAttributeId($attribute_id) 43 | { 44 | $attribute_id = intval($attribute_id); 45 | if($attribute_id < 0x00 || $attribute_id > 0xffff) 46 | throw new ZigbeeException("Invalid attribute id"); 47 | 48 | $this->attribute_id = $attribute_id; 49 | } 50 | 51 | public function getAttributeId() 52 | { 53 | return $this->attribute_id; 54 | } 55 | 56 | public function displayAttributeId() 57 | { 58 | return sprintf("0x%04x", $this->getAttributeId()); 59 | } 60 | 61 | public function setDatatypeId($datatype_id) 62 | { 63 | $datatype_id = intval($datatype_id); 64 | if($datatype_id < 0x00 || $datatype_id > 0xff) 65 | throw new ZigbeeException("Invalid datatype id"); 66 | 67 | $this->datatype_id = $datatype_id; 68 | } 69 | 70 | public function getDatatypeId() 71 | { 72 | return $this->datatype_id; 73 | } 74 | 75 | public function displayDatatypeId() 76 | { 77 | return sprintf("0x%02x", $this->getDatatypeId()); 78 | } 79 | 80 | public function __toString() 81 | { 82 | return "AttributeId: ".$this->displayAttributeId().", DatatypeId: ".$this->displayDatatypeId(); 83 | } 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/ZCL/General/AttributeRecord.php: -------------------------------------------------------------------------------- 1 | setDirection($direction); 20 | $element->setAttributeId($attribute_id); 21 | return $element; 22 | } 23 | 24 | public function consumeFrame(&$frame) 25 | { 26 | $this->setDirection(Buffer::unpackInt8u($frame)); 27 | $this->setAttributeId(Buffer::unpackInt16u($frame)); 28 | } 29 | 30 | public function setFrame($frame) 31 | { 32 | $this->consumeFrame($frame); 33 | } 34 | 35 | public function getFrame() 36 | { 37 | $frame = ""; 38 | 39 | Buffer::packInt8u($frame, $this->getDirection()); 40 | Buffer::packInt16u($frame, $this->getAttributeId()); 41 | 42 | return $frame; 43 | } 44 | 45 | public function setDirection($direction) 46 | { 47 | $direction = intval($direction); 48 | if($direction < 0x00 || $direction > 0x01) 49 | throw new ZigbeeException("Invalid direction"); 50 | 51 | $this->direction = $direction; 52 | } 53 | 54 | public function getDirection() 55 | { 56 | return $this->direction; 57 | } 58 | 59 | public function displayDirection() 60 | { 61 | return sprintf("0x%02x", $this->getDirection()); 62 | } 63 | 64 | /** 65 | * @param $attribute_id 66 | * @throws \Munisense\Zigbee\Exception\ZigbeeException 67 | */ 68 | public function setAttributeId($attribute_id) 69 | { 70 | $attribute_id = intval($attribute_id); 71 | if($attribute_id < 0x00 || $attribute_id > 0xffff) 72 | throw new ZigbeeException("Invalid attribute id"); 73 | 74 | $this->attribute_id = $attribute_id; 75 | } 76 | 77 | public function getAttributeId() 78 | { 79 | return $this->attribute_id; 80 | } 81 | 82 | public function displayAttributeId() 83 | { 84 | return sprintf("0x%04x", $this->getAttributeId()); 85 | } 86 | 87 | public function __toString() 88 | { 89 | return "Direction: ".$this->displayDirection().", AttributeId: ".$this->displayAttributeId(); 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /src/ZCL/General/AttributeReport.php: -------------------------------------------------------------------------------- 1 | setAttributeId(Buffer::unpackInt16u($frame)); 17 | $this->setDatatypeId(Buffer::unpackInt8u($frame)); 18 | $this->setValue(Buffer::unpackDatatype($frame, $this->getDatatypeId())); 19 | } 20 | 21 | public function setFrame($frame) 22 | { 23 | $this->consumeFrame($frame); 24 | } 25 | 26 | public function getFrame() 27 | { 28 | $frame = ""; 29 | 30 | Buffer::packInt16u($frame, $this->getAttributeId()); 31 | Buffer::packInt8u($frame, $this->getDatatypeId()); 32 | Buffer::packDatatype($frame, $this->getDatatypeId(), $this->getValue()); 33 | 34 | return $frame; 35 | } 36 | 37 | public function setAttributeId($attribute_id) 38 | { 39 | $attribute_id = intval($attribute_id); 40 | if($attribute_id < 0x00 || $attribute_id > 0xffff) 41 | throw new ZigbeeException("Invalid attribute id"); 42 | 43 | $this->attribute_id = $attribute_id; 44 | } 45 | 46 | public function getAttributeId() 47 | { 48 | return $this->attribute_id; 49 | } 50 | 51 | public function displayAttributeId() 52 | { 53 | return sprintf("0x%04x", $this->getAttributeId()); 54 | } 55 | 56 | public function setDatatypeId($datatype_id) 57 | { 58 | $datatype_id = intval($datatype_id); 59 | if($datatype_id < 0x00 || $datatype_id > 0xff) 60 | throw new ZigbeeException("Invalid datatype id"); 61 | 62 | $this->datatype_id = $datatype_id; 63 | } 64 | 65 | public function getDatatypeId() 66 | { 67 | return $this->datatype_id; 68 | } 69 | 70 | public function displayDatatypeId() 71 | { 72 | return sprintf("0x%02x", $this->getDatatypeId()); 73 | } 74 | 75 | public function setValue($value) 76 | { 77 | $this->value = $value; 78 | } 79 | 80 | public function getValue() 81 | { 82 | return $this->value; 83 | } 84 | 85 | public function displayValue() 86 | { 87 | return Buffer::displayDatatype($this->getDatatypeId(), $this->getValue()); 88 | } 89 | 90 | public function __toString() 91 | { 92 | return "AttributeId: ".$this->displayAttributeId().", DatatypeId: ".$this->displayDatatypeId().", Value: ".$this->displayValue(); 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /src/ZCL/General/AttributeReportingConfigurationStatusRecord.php: -------------------------------------------------------------------------------- 1 | setStatus(ZCLStatus::SUCCESS); 28 | 29 | $element->setParentFrame($parent); 30 | 31 | return $element; 32 | } 33 | 34 | /** 35 | * If there is an error code, we do not need the full AttributeReportingConfigurationRecord 36 | * 37 | * @param $status 38 | * @param $direction 39 | * @param $attribute_id 40 | * @return AttributeReportingConfigurationStatusRecord 41 | */ 42 | public static function constructWithError($status, $direction, $attribute_id) 43 | { 44 | $element = new self; 45 | $element->setStatus($status); 46 | $element->setDirection($direction); 47 | $element->setAttributeId($attribute_id); 48 | 49 | return $element; 50 | } 51 | 52 | protected function setParentFrame(AttributeReportingConfigurationRecord $parent) 53 | { 54 | $parent_frame = $parent->getFrame(); 55 | parent::consumeFrame($parent_frame); 56 | } 57 | 58 | /** 59 | * Helper method to map this object on a AttributeReportingConfigurationRecord. 60 | * 61 | * @return AttributeReportingConfigurationRecord 62 | * @throws ZigbeeException When status is not SUCCESS 63 | */ 64 | public function getAttributeReportingConfigurationRecord() 65 | { 66 | if($this->getStatus() == ZCLStatus::SUCCESS) 67 | return new AttributeReportingConfigurationRecord(parent::getFrame()); 68 | else 69 | throw new ZigbeeException("Can only fetch AttributeReportingConfigurationRecord when status is set to SUCCESS"); 70 | } 71 | 72 | public function consumeFrame(&$frame) 73 | { 74 | $this->setStatus(Buffer::unpackInt8u($frame)); 75 | parent::consumeFrame($frame); 76 | } 77 | 78 | public function getFrame() 79 | { 80 | $frame = ""; 81 | 82 | Buffer::packInt8u($frame, $this->getStatus()); 83 | 84 | if($this->getStatus() == ZCLStatus::SUCCESS) 85 | { 86 | $frame .= parent::getFrame(); 87 | } 88 | // If the status field is not set to SUCCESS, all fields except the direction and 89 | // attribute identifier fields shall be omitted. 90 | else 91 | { 92 | Buffer::packInt8u($frame, $this->getDirection()); 93 | Buffer::packInt16u($frame, $this->getAttributeId()); 94 | } 95 | 96 | return $frame; 97 | } 98 | 99 | /** 100 | * If the attribute is not implemented on the sender or receiver of the command, 101 | * whichever is relevant (depending on direction), this field shall be set to 102 | * UNSUPPORTED_ATTRIBUTE. If the attribute is supported, but is not capable of 103 | * being reported, this field shall be set to UNREPORTABLE_ATTRIBUTE. 104 | * Otherwise, this field shall be set to SUCCESS. 105 | * 106 | * @param int $status 107 | * @throws ZigbeeException 108 | */ 109 | public function setStatus($status) 110 | { 111 | $status = intval($status); 112 | if(!in_array($status, [ZCLStatus::UNSUPPORTED_ATTRIBUTE, ZCLStatus::UNREPORTABLE_ATTRIBUTE, ZCLStatus::SUCCESS])) 113 | throw new ZigbeeException("Invalid status"); 114 | 115 | $this->status = $status; 116 | } 117 | 118 | /** 119 | * @return int Status 120 | */ 121 | public function getStatus() 122 | { 123 | return $this->status; 124 | } 125 | 126 | public function displayStatus() 127 | { 128 | return ZCLStatus::displayStatus($this->getStatus()); 129 | } 130 | 131 | public function __toString() 132 | { 133 | return "Status: ".$this->displayStatus().", ".parent::__toString(); 134 | } 135 | } 136 | 137 | -------------------------------------------------------------------------------- /src/ZCL/General/AttributeStatusRecord.php: -------------------------------------------------------------------------------- 1 | setStatus($status); 22 | $element->setDirection($direction); 23 | $element->setAttributeId($attribute_id); 24 | return $element; 25 | } 26 | 27 | public function consumeFrame(&$frame) 28 | { 29 | $this->setStatus(Buffer::unpackInt8u($frame)); 30 | $this->setDirection(Buffer::unpackInt8u($frame)); 31 | $this->setAttributeId(Buffer::unpackInt16u($frame)); 32 | } 33 | 34 | public function setFrame($frame) 35 | { 36 | $this->consumeFrame($frame); 37 | } 38 | 39 | public function getFrame() 40 | { 41 | $frame = ""; 42 | 43 | Buffer::packInt8u($frame, $this->getStatus()); 44 | Buffer::packInt8u($frame, $this->getDirection()); 45 | Buffer::packInt16u($frame, $this->getAttributeId()); 46 | 47 | return $frame; 48 | } 49 | 50 | /** 51 | * @param int $status 52 | */ 53 | public function setStatus($status) 54 | { 55 | $this->status = $status; 56 | } 57 | 58 | /** 59 | * @return int 60 | */ 61 | public function getStatus() 62 | { 63 | return $this->status; 64 | } 65 | 66 | public function displayStatus() 67 | { 68 | return ZCLStatus::displayStatus($this->status); 69 | } 70 | 71 | public function setDirection($direction) 72 | { 73 | $direction = intval($direction); 74 | if($direction < 0x00 || $direction > 0x01) 75 | throw new ZigbeeException("Invalid direction"); 76 | 77 | $this->direction = $direction; 78 | } 79 | 80 | public function getDirection() 81 | { 82 | return $this->direction; 83 | } 84 | 85 | public function displayDirection() 86 | { 87 | return sprintf("0x%02x", $this->getDirection()); 88 | } 89 | 90 | public function setAttributeId($attribute_id) 91 | { 92 | $attribute_id = intval($attribute_id); 93 | if($attribute_id < 0x00 || $attribute_id > 0xffff) 94 | throw new ZigbeeException("Invalid attribute id"); 95 | 96 | $this->attribute_id = $attribute_id; 97 | } 98 | 99 | public function getAttributeId() 100 | { 101 | return $this->attribute_id; 102 | } 103 | 104 | public function displayAttributeId() 105 | { 106 | return sprintf("0x%04x", $this->getAttributeId()); 107 | } 108 | 109 | public function __toString() 110 | { 111 | return "Status: ".$this->displayStatus().", Direction: ".$this->displayDirection().", AttributeId: ".$this->displayAttributeId(); 112 | } 113 | } 114 | 115 | -------------------------------------------------------------------------------- /src/ZCL/General/ConfigureReportingCommand.php: -------------------------------------------------------------------------------- 1 | setAttributeReportingConfigurationRecords($attribute_reporting_configuration_records); 23 | return $frame; 24 | } 25 | 26 | public function setFrame($frame) 27 | { 28 | while(strlen($frame)) 29 | { 30 | $configure_reporting_element = new AttributeReportingConfigurationRecord(); 31 | $configure_reporting_element->consumeFrame($frame); 32 | $this->addAttributeReportingConfigurationRecord($configure_reporting_element); 33 | } 34 | } 35 | 36 | public function getFrame() 37 | { 38 | $frame = ""; 39 | 40 | foreach($this->attribute_reporting_configuration_records as $configure_reporting_element) 41 | $frame .= $configure_reporting_element->getFrame(); 42 | 43 | return $frame; 44 | } 45 | 46 | public function setAttributeReportingConfigurationRecords(array $configure_reporting_elements) 47 | { 48 | $this->attribute_reporting_configuration_records = []; 49 | foreach($configure_reporting_elements as $configure_reporting_element) 50 | $this->addAttributeReportingConfigurationRecord($configure_reporting_element); 51 | 52 | $this->attribute_reporting_configuration_records = $configure_reporting_elements; 53 | } 54 | 55 | public function getAttributeReportingConfigurationRecords() 56 | { 57 | return $this->attribute_reporting_configuration_records; 58 | } 59 | 60 | public function addAttributeReportingConfigurationRecord(AttributeReportingConfigurationRecord $configure_reporting_element) 61 | { 62 | $this->attribute_reporting_configuration_records[] = $configure_reporting_element; 63 | } 64 | 65 | public function __toString() 66 | { 67 | $x = 0; 68 | $count = count($this->getAttributeReportingConfigurationRecords()); 69 | $output = __CLASS__." (count: ".$count.", length: ".strlen($this->getFrame()).")".PHP_EOL; 70 | foreach($this->getAttributeReportingConfigurationRecords() as $configure_reporting_element) 71 | $output .= (++$x == $count ? "`" : "|" )."- ".$configure_reporting_element.PHP_EOL; 72 | 73 | return $output; 74 | } 75 | 76 | 77 | /** 78 | * Returns the Command ID of this frame 79 | * @return int 80 | */ 81 | public function getCommandId() 82 | { 83 | return GeneralCommand::CONFIGURE_REPORTING; 84 | } 85 | 86 | /** 87 | * Returns the Frame Type of this frame 88 | * @return int 89 | */ 90 | public function getFrameType() 91 | { 92 | return ZCLFrame::FRAME_TYPE_PROFILE_WIDE; 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /src/ZCL/General/ConfigureReportingResponseCommand.php: -------------------------------------------------------------------------------- 1 | setAttributeStatusRecords($attribute_status_records); 26 | return $frame; 27 | } 28 | 29 | public function isSuccess() 30 | { 31 | return count($this->attribute_status_records) == 0; 32 | } 33 | 34 | public function setFrame($frame) 35 | { 36 | /** 37 | * Note that attribute status records are not included for successfully configured 38 | * attributes, in order to save bandwidth. In the case of successful configuration of all 39 | * attributes, only a single attribute statusrecord shall be included in the command, 40 | * with the status field set to SUCCESS and the direction and attribute identifier 41 | * fields omitted 42 | */ 43 | if(strlen($frame) == 1) 44 | { 45 | $status = Buffer::unpackInt8u($frame); 46 | if($status != ZCLStatus::SUCCESS) 47 | throw new ZigbeeException("If a ".__CLASS__." only has one byte, it should be the SUCCESS status"); 48 | 49 | return; 50 | } 51 | else 52 | while(strlen($frame)) 53 | { 54 | $attribute_status_record = new AttributeStatusRecord(); 55 | $attribute_status_record->consumeFrame($frame); 56 | $this->addAttributeStatusRecord($attribute_status_record); 57 | } 58 | } 59 | 60 | public function getFrame() 61 | { 62 | $frame = ""; 63 | 64 | if(!empty($this->attribute_status_records)) 65 | { 66 | foreach($this->attribute_status_records as $attribute_status_record) 67 | $frame .= $attribute_status_record->getFrame(); 68 | } 69 | else 70 | Buffer::packInt8u($frame, ZCLStatus::SUCCESS); 71 | 72 | return $frame; 73 | } 74 | 75 | public function setAttributeStatusRecords(array $attribute_status_records) 76 | { 77 | foreach($attribute_status_records as $attribute_status_record) 78 | $this->addAttributeStatusRecord($attribute_status_record); 79 | } 80 | 81 | public function getAttributeStatusRecords() 82 | { 83 | return $this->attribute_status_records; 84 | } 85 | 86 | public function addAttributeStatusRecord(AttributeStatusRecord $attribute_status_records) 87 | { 88 | $this->attribute_status_records[] = $attribute_status_records; 89 | } 90 | 91 | public function __toString() 92 | { 93 | $x = 0; 94 | $count = count($this->getAttributeStatusRecords()); 95 | $output = __CLASS__." (count: ".$count.", length: ".strlen($this->getFrame()).")".PHP_EOL; 96 | foreach($this->getAttributeStatusRecords() as $attribute_status_record) 97 | $output .= (++$x == $count ? "`" : "|" )."- ".$attribute_status_record.PHP_EOL; 98 | 99 | return $output; 100 | } 101 | 102 | 103 | /** 104 | * Returns the Command ID of this frame 105 | * @return int 106 | */ 107 | public function getCommandId() 108 | { 109 | return GeneralCommand::CONFIGURE_REPORTING_RESPONSE; 110 | } 111 | 112 | /** 113 | * Returns the Frame Type of this frame 114 | * @return int 115 | */ 116 | public function getFrameType() 117 | { 118 | return ZCLFrame::FRAME_TYPE_PROFILE_WIDE; 119 | } 120 | } 121 | 122 | -------------------------------------------------------------------------------- /src/ZCL/General/DefaultResponseCommand.php: -------------------------------------------------------------------------------- 1 | command_identifier = $command_identifier; 20 | $frame->status_code = $status_code; 21 | return $frame; 22 | } 23 | 24 | public function setFrame($frame) 25 | { 26 | $this->setCommandIdentifier(Buffer::unpackInt8u($frame)); 27 | $this->setStatusCode(Buffer::unpackInt8u($frame)); 28 | } 29 | 30 | public function getFrame() 31 | { 32 | $frame = ""; 33 | 34 | Buffer::packInt8u($frame, $this->command_identifier); 35 | Buffer::packInt8u($frame, $this->status_code); 36 | 37 | return $frame; 38 | } 39 | 40 | /** 41 | * @param int $command_identifier 42 | */ 43 | public function setCommandIdentifier($command_identifier) 44 | { 45 | $this->command_identifier = $command_identifier; 46 | } 47 | 48 | /** 49 | * @return int 50 | */ 51 | public function getCommandIdentifier() 52 | { 53 | return $this->command_identifier; 54 | } 55 | 56 | public function displayCommandIdentifier() 57 | { 58 | return sprintf("0x%02x", $this->command_identifier); 59 | } 60 | 61 | /** 62 | * @param int $status_code 63 | */ 64 | public function setStatusCode($status_code) 65 | { 66 | $this->status_code = $status_code; 67 | } 68 | 69 | /** 70 | * @return int 71 | */ 72 | public function getStatusCode() 73 | { 74 | return $this->status_code; 75 | } 76 | 77 | public function displayStatusCode() 78 | { 79 | return ZCLStatus::displayStatus($this->status_code); 80 | } 81 | 82 | public function __toString() 83 | { 84 | return __CLASS__." (commandIdentifier: ".$this->displayCommandIdentifier().", status: ".$this->displayStatusCode().")".PHP_EOL; 85 | } 86 | 87 | 88 | /** 89 | * Returns the Command ID of this frame 90 | * @return int 91 | */ 92 | public function getCommandId() 93 | { 94 | return GeneralCommand::DEFAULT_RESPONSE; 95 | } 96 | 97 | /** 98 | * Returns the Frame Type of this frame 99 | * @return int 100 | */ 101 | public function getFrameType() 102 | { 103 | return ZCLFrame::FRAME_TYPE_PROFILE_WIDE; 104 | } 105 | } 106 | 107 | -------------------------------------------------------------------------------- /src/ZCL/General/DiscoverAttributesCommand.php: -------------------------------------------------------------------------------- 1 | setStartAttributeIdentifier($start_attribute_identifier); 25 | $frame->setMaximumAttributeIdentifiers($maximum_attribute_identifiers); 26 | return $frame; 27 | } 28 | 29 | function getFrame() 30 | { 31 | $frame = ""; 32 | 33 | Buffer::packInt16u($frame, $this->getStartAttributeIdentifier()); 34 | Buffer::packInt8u($frame, $this->getMaximumAttributeIdentifiers()); 35 | 36 | return $frame; 37 | } 38 | 39 | function setFrame($frame) 40 | { 41 | $this->setStartAttributeIdentifier(Buffer::unpackInt16u($frame)); 42 | $this->setMaximumAttributeIdentifiers(Buffer::unpackInt8u($frame)); 43 | } 44 | 45 | public function setStartAttributeIdentifier($start_attribute_identifier) 46 | { 47 | $this->start_attribute_identifier = $start_attribute_identifier; 48 | } 49 | 50 | public function setMaximumAttributeIdentifiers($maximum_attribute_identifiers) 51 | { 52 | $this->maximum_attribute_identifiers = $maximum_attribute_identifiers; 53 | } 54 | 55 | public function getMaximumAttributeIdentifiers() 56 | { 57 | return $this->maximum_attribute_identifiers; 58 | } 59 | 60 | public function getStartAttributeIdentifier() 61 | { 62 | return $this->start_attribute_identifier; 63 | } 64 | 65 | /** 66 | * Returns the Command ID of this frame 67 | * @return int 68 | */ 69 | public function getCommandId() 70 | { 71 | return GeneralCommand::DISCOVER_ATTRIBUTES; 72 | } 73 | 74 | /** 75 | * Returns the Frame Type of this frame 76 | * @return int 77 | */ 78 | public function getFrameType() 79 | { 80 | return ZCLFrame::FRAME_TYPE_PROFILE_WIDE; 81 | } 82 | } -------------------------------------------------------------------------------- /src/ZCL/General/DiscoverAttributesResponseCommand.php: -------------------------------------------------------------------------------- 1 | setDiscoveryComplete($discovery_complete); 32 | $frame->setAttributes($attributes); 33 | return $frame; 34 | } 35 | 36 | function getFrame() 37 | { 38 | $frame = ""; 39 | 40 | Buffer::packInt8u($frame, $this->getDiscoveryComplete() ? 1 : 0); 41 | 42 | foreach($this->attributes as $attribute) 43 | $frame .= $attribute->getFrame(); 44 | 45 | return $frame; 46 | } 47 | 48 | function setFrame($frame) 49 | { 50 | $this->setDiscoveryComplete(Buffer::unpackInt8u($frame) == 1); 51 | 52 | while(strlen($frame)) 53 | { 54 | $attribute_information = new AttributeInformation(); 55 | $attribute_information->consumeFrame($frame); 56 | $this->addAttributeInformation($attribute_information); 57 | } 58 | } 59 | 60 | /** 61 | * @param AttributeInformation[] $attributes 62 | */ 63 | public function setAttributes($attributes) 64 | { 65 | $this->attributes = []; 66 | foreach($attributes as $attribute_information) 67 | $this->addAttributeInformation($attribute_information); 68 | } 69 | 70 | public function addAttributeInformation(AttributeInformation $attribute_information) 71 | { 72 | $this->attributes[] = $attribute_information; 73 | } 74 | 75 | /** 76 | * @return AttributeInformation[] 77 | */ 78 | public function getAttributes() 79 | { 80 | return $this->attributes; 81 | } 82 | 83 | /** 84 | * @param boolean $discovery_complete 85 | */ 86 | public function setDiscoveryComplete($discovery_complete) 87 | { 88 | $this->discovery_complete = $discovery_complete; 89 | } 90 | 91 | /** 92 | * @return boolean 93 | */ 94 | public function getDiscoveryComplete() 95 | { 96 | return $this->discovery_complete; 97 | } 98 | 99 | /** 100 | * Returns the Command ID of this frame 101 | * @return int 102 | */ 103 | public function getCommandId() 104 | { 105 | return GeneralCommand::DISCOVER_ATTRIBUTES_RESPONSE; 106 | } 107 | 108 | /** 109 | * Returns the Frame Type of this frame 110 | * @return int 111 | */ 112 | public function getFrameType() 113 | { 114 | return ZCLFrame::FRAME_TYPE_PROFILE_WIDE; 115 | } 116 | } -------------------------------------------------------------------------------- /src/ZCL/General/GeneralCommand.php: -------------------------------------------------------------------------------- 1 | array("class" => "Munisense\\Zigbee\\ZCL\\General\\ReadAttributesCommand", "name" => "Read Attributes"), 27 | self::READ_ATTRIBUTES_RESPONSE => array("class" => "Munisense\\Zigbee\\ZCL\\General\\ReadAttributesResponseCommand", "name" => "Read Attributes Response"), 28 | self::WRITE_ATTRIBUTES => array("class" => "Munisense\\Zigbee\\ZCL\\General\\WriteAttributesCommand", "name" => "Write Attributes"), 29 | self::WRITE_ATTRIBUTES_UNDIVIDED => array("class" => "Munisense\\Zigbee\\ZCL\\General\\WriteAttributesCommand","name" => "Write Attributes Undivided"), 30 | self::WRITE_ATTRIBUTES_RESPONSE => array("class" => "Munisense\\Zigbee\\ZCL\\General\\WriteAttributesResponseCommand", "name" => "Write Attributes Response"), 31 | self::WRITE_ATTRIBUTES_NO_RESPONSE => array("class" => "Munisense\\Zigbee\\ZCL\\General\\WriteAttributesCommand","name" => "Write Attributes No Response"), 32 | self::CONFIGURE_REPORTING => array("class" => "Munisense\\Zigbee\\ZCL\\General\\ConfigureReportingCommand", "name" => "Configure Reporting"), 33 | self::CONFIGURE_REPORTING_RESPONSE => array("class" => "Munisense\\Zigbee\\ZCL\\General\\ConfigureReportingResponseCommand","name" => "Configure Reporting Response"), 34 | self::READ_REPORTING_CONFIGURATION => array("class" => "Munisense\\Zigbee\\ZCL\\General\\ReadReportingConfigurationCommand","name" => "Read Reporting Configuration"), 35 | self::READ_REPORTING_CONFIGURATION_RESPONSE => array("class" => "Munisense\\Zigbee\\ZCL\\General\\ReadReportingConfigurationResponseCommand", "name" => "Read Reporting Configuration Response"), 36 | self::REPORT_ATTRIBUTES => array("class" => "Munisense\\Zigbee\\ZCL\\General\\ReportAttributesCommand", "name" => "Report Attributes"), 37 | self::DEFAULT_RESPONSE => array("class" => "Munisense\\Zigbee\\ZCL\\General\\DefaultResponseCommand","name" => "Default Response"), 38 | self::DISCOVER_ATTRIBUTES => array("class" => "Munisense\\Zigbee\\ZCL\\General\\DiscoverAttributesCommand", "name" => "Discover Attributes"), 39 | self::DISCOVER_ATTRIBUTES_RESPONSE => array("class" => "Munisense\\Zigbee\\ZCL\\General\\DiscoverAttributesResponseCommand", "name" => "Discover Attributes Response"), 40 | self::READ_ATTRIBUTES_STRUCTURED => array("class" => "Munisense\\Zigbee\\ZCL\\General\\ReadAttributesStructuredCommand", "name" => "Read Attributes Structured"), 41 | self::WRITE_ATTRIBUTES_STRUCTURED => array("class" => "Munisense\\Zigbee\\ZCL\\General\\WriteAttributesCommand","name" => "Write Attributes Structured"), 42 | self::WRITE_ATTRIBUTES_STRUCTURED_RESPONSE => array("class" => "Munisense\\Zigbee\\ZCL\\General\\ZCLWriteAttributesStructuredResponseFrame", "name" => "Write Attributes Structured Response") 43 | ); 44 | 45 | public static function displayCommand($command_id) 46 | { 47 | if(isset(self::$command[$command_id])) 48 | return self::$command[$command_id]['name']; 49 | else 50 | return "Unknown (".sprintf("0x%02x", $command_id).")"; 51 | } 52 | } -------------------------------------------------------------------------------- /src/ZCL/General/ReadAttributesCommand.php: -------------------------------------------------------------------------------- 1 | attribute_identifiers = $elements; 21 | return $frame; 22 | } 23 | 24 | public function setFrame($frame) 25 | { 26 | while(strlen($frame)) 27 | { 28 | $attribute_identifier = new AttributeIdentifier(); 29 | $attribute_identifier->setAttributeId(Buffer::unpackInt16u($frame)); 30 | $this->attribute_identifiers[] = $attribute_identifier; 31 | } 32 | } 33 | 34 | public function getFrame() 35 | { 36 | $frame = ""; 37 | 38 | foreach($this->attribute_identifiers as $attribute_identifier) 39 | $frame .= $attribute_identifier->getFrame(); 40 | 41 | return $frame; 42 | } 43 | 44 | public function setAttributeIdentifiers(array $attribute_identifiers) 45 | { 46 | $this->attribute_identifiers = []; 47 | foreach($attribute_identifiers as $attribute_identifier) 48 | $this->addAttributeIdentifier($attribute_identifier); 49 | } 50 | 51 | public function getAttributeIdentifiers() 52 | { 53 | return $this->attribute_identifiers; 54 | } 55 | 56 | public function addAttributeIdentifier(AttributeIdentifier $attribute_identifier) 57 | { 58 | $this->attribute_identifiers[] = $attribute_identifier; 59 | } 60 | 61 | public function __toString() 62 | { 63 | $output = __CLASS__." (count: ".count($this->getAttributeIdentifiers()).", length: ".strlen($this->getFrame()).")".PHP_EOL; 64 | $read_attributes_elements = $this->getAttributeIdentifiers(); 65 | $read_attributes_elements_count = count($read_attributes_elements); 66 | foreach($read_attributes_elements as $key => $read_attributes_element) 67 | $output .= ($key + 1 == $read_attributes_elements_count ? "`" : "|")."- ".$read_attributes_element.PHP_EOL; 68 | 69 | return $output; 70 | } 71 | 72 | 73 | /** 74 | * Returns the Command ID of this frame 75 | * @return int 76 | */ 77 | public function getCommandId() 78 | { 79 | return GeneralCommand::READ_ATTRIBUTES; 80 | } 81 | 82 | /** 83 | * Returns the Frame Type of this frame 84 | * @return int 85 | */ 86 | public function getFrameType() 87 | { 88 | return ZCLFrame::FRAME_TYPE_PROFILE_WIDE; 89 | } 90 | } 91 | 92 | -------------------------------------------------------------------------------- /src/ZCL/General/ReadAttributesResponseCommand.php: -------------------------------------------------------------------------------- 1 | read_attributes_status_records = $elements; 20 | return $frame; 21 | } 22 | 23 | public function setFrame($frame) 24 | { 25 | while(strlen($frame)) 26 | { 27 | $status_record = new ReadAttributesStatusRecord(); 28 | $status_record->consumeFrame($frame); 29 | $this->addReadAttributesElement($status_record); 30 | } 31 | } 32 | 33 | public function getFrame() 34 | { 35 | $frame = ""; 36 | 37 | foreach($this->read_attributes_status_records as $read_attributes_element) 38 | $frame .= $read_attributes_element->getFrame(); 39 | 40 | return $frame; 41 | } 42 | 43 | 44 | public function setReadAttributesStatusRecords(array $read_attributes_status_records) 45 | { 46 | $this->read_attributes_status_records = []; 47 | foreach($read_attributes_status_records as $read_attributes_status_record) 48 | $this->addReadAttributesElement($read_attributes_status_record); 49 | } 50 | 51 | public function getReadAttributesStatusRecords() 52 | { 53 | return $this->read_attributes_status_records; 54 | } 55 | 56 | public function addReadAttributesElement(ReadAttributesStatusRecord $read_attributes_status_record) 57 | { 58 | $this->read_attributes_status_records[] = $read_attributes_status_record; 59 | } 60 | 61 | public function __toString() 62 | { 63 | $output = __CLASS__." (count: ".count($this->getReadAttributesStatusRecords()).", length: ".strlen($this->getFrame()).")".PHP_EOL; 64 | $read_attributes_elements = $this->getReadAttributesStatusRecords(); 65 | $read_attributes_elements_count = count($read_attributes_elements); 66 | foreach($read_attributes_elements as $key => $read_attributes_element) 67 | $output .= ($key + 1 == $read_attributes_elements_count ? "`" : "|")."- ".$read_attributes_element.PHP_EOL; 68 | 69 | return $output; 70 | } 71 | 72 | 73 | /** 74 | * Returns the Command ID of this frame 75 | * @return int 76 | */ 77 | public function getCommandId() 78 | { 79 | return GeneralCommand::READ_ATTRIBUTES_RESPONSE; 80 | } 81 | 82 | /** 83 | * Returns the Frame Type of this frame 84 | * @return int 85 | */ 86 | public function getFrameType() 87 | { 88 | return ZCLFrame::FRAME_TYPE_PROFILE_WIDE; 89 | } 90 | } 91 | 92 | -------------------------------------------------------------------------------- /src/ZCL/General/ReadAttributesStatusRecord.php: -------------------------------------------------------------------------------- 1 | setAttributeId($attribute_id); 21 | $record->setStatus(ZCLStatus::SUCCESS); 22 | $record->setDatatypeId($datatype_id); 23 | $record->setValue($value); 24 | return $record; 25 | } 26 | 27 | public static function constructFailure($attribute_id, $status) 28 | { 29 | $record = new self; 30 | $record->setAttributeId($attribute_id); 31 | $record->setStatus($status); 32 | return $record; 33 | } 34 | 35 | public function consumeFrame(&$frame) 36 | { 37 | $this->setAttributeId(Buffer::unpackInt16u($frame)); 38 | $this->setStatus(Buffer::unpackInt8u($frame)); 39 | 40 | if($this->getStatus() == ZCLStatus::SUCCESS) 41 | { 42 | $this->setDatatypeId(Buffer::unpackInt8u($frame)); 43 | $this->setValue(Buffer::unpackDatatype($frame, $this->getDatatypeId())); 44 | } 45 | } 46 | 47 | public function setFrame($frame) 48 | { 49 | $this->consumeFrame($frame); 50 | 51 | if(strlen($frame) > 0) 52 | throw new ZigbeeException("Still data left in frame buffer"); 53 | } 54 | 55 | public function getFrame() 56 | { 57 | $frame = ""; 58 | 59 | Buffer::packInt16u($frame, $this->getAttributeId()); 60 | Buffer::packInt8u($frame, $this->getStatus()); 61 | 62 | if($this->getStatus() == ZCLStatus::SUCCESS) 63 | { 64 | Buffer::packInt8u($frame, $this->getDatatypeId()); 65 | Buffer::packDatatype($frame, $this->getDatatypeId(), $this->getValue()); 66 | } 67 | 68 | return $frame; 69 | } 70 | 71 | public function setAttributeId($attribute_id) 72 | { 73 | $attribute_id = intval($attribute_id); 74 | if($attribute_id < 0x0000 || $attribute_id > 0xffff) 75 | throw new ZigbeeException("Invalid attribute id"); 76 | 77 | $this->attribute_id = $attribute_id; 78 | } 79 | 80 | public function getAttributeId() 81 | { 82 | return $this->attribute_id; 83 | } 84 | 85 | public function displayAttributeId() 86 | { 87 | return sprintf("0x%04x", $this->getAttributeId()); 88 | } 89 | 90 | /** 91 | * @param int $status 92 | * @throws ZigbeeException 93 | */ 94 | public function setStatus($status) 95 | { 96 | $status = intval($status); 97 | if($status < 0x00 || $status > 0xff) 98 | throw new ZigbeeException("Invalid status"); 99 | 100 | $this->status = $status; 101 | } 102 | 103 | /** 104 | * @return mixed 105 | */ 106 | public function getStatus() 107 | { 108 | return $this->status; 109 | } 110 | 111 | public function displayStatus() 112 | { 113 | return ZCLStatus::displayStatus($this->getStatus()); 114 | } 115 | 116 | public function setDatatypeId($datatype_id) 117 | { 118 | $datatype_id = intval($datatype_id); 119 | if($datatype_id < 0x00 || $datatype_id > 0xff) 120 | throw new ZigbeeException("Invalid datatype id"); 121 | 122 | $this->datatype_id = $datatype_id; 123 | } 124 | 125 | public function getDatatypeId() 126 | { 127 | return $this->datatype_id; 128 | } 129 | 130 | public function displayDatatypeId() 131 | { 132 | return sprintf("0x%02x", $this->getDatatypeId()); 133 | } 134 | 135 | public function setValue($value) 136 | { 137 | $this->value = $value; 138 | } 139 | 140 | public function getValue() 141 | { 142 | return $this->value; 143 | } 144 | 145 | public function displayValue() 146 | { 147 | return Buffer::displayDatatype($this->getDatatypeId(), $this->getValue()); 148 | } 149 | 150 | public function __toString() 151 | { 152 | return "AttributeId: ".$this->displayAttributeId().", Status: ".$this->displayStatus().($this->getStatus() == ZCLStatus::SUCCESS ? ", DatatypeId: ".$this->displayDatatypeId().", Value: ".$this->displayValue() : ""); 153 | } 154 | } 155 | 156 | -------------------------------------------------------------------------------- /src/ZCL/General/ReadAttributesStructuredCommand.php: -------------------------------------------------------------------------------- 1 | addAttributeRecord($element); 33 | 34 | return $frame; 35 | } 36 | 37 | public function setFrame($frame) 38 | { 39 | while(strlen($frame)) 40 | { 41 | $attribute_record = new AttributeRecord(); 42 | $attribute_record->consumeFrame($frame); 43 | $this->attribute_records[] = $attribute_record; 44 | } 45 | } 46 | 47 | public function getFrame() 48 | { 49 | $frame = ""; 50 | 51 | foreach($this->attribute_records as $attribute_record) 52 | $frame .= $attribute_record->getFrame(); 53 | 54 | return $frame; 55 | } 56 | 57 | /** 58 | * @param AttributeRecord[] $attribute_records 59 | */ 60 | public function setAttributeRecords(array $attribute_records) 61 | { 62 | $this->attribute_records = []; 63 | foreach($attribute_records as $attribute_record) 64 | $this->addAttributeRecord($attribute_record); 65 | } 66 | 67 | /** 68 | * @return AttributeRecord[] 69 | */ 70 | public function getAttributeRecords() 71 | { 72 | return $this->attribute_records; 73 | } 74 | 75 | /** 76 | * @param AttributeRecord $attribute_record 77 | */ 78 | public function addAttributeRecord(AttributeRecord $attribute_record) 79 | { 80 | $this->attribute_records[] = $attribute_record; 81 | } 82 | 83 | public function __toString() 84 | { 85 | $output = __CLASS__." (count: ".count($this->getAttributeRecords()).", length: ".strlen($this->getFrame()).")".PHP_EOL; 86 | $attribute_records = $this->getAttributeRecords(); 87 | $attribute_records_count = count($attribute_records); 88 | foreach($attribute_records as $key => $attribute_record) 89 | $output .= ($key + 1 == $attribute_records_count ? "`" : "|")."- ".$attribute_record.PHP_EOL; 90 | 91 | return $output; 92 | } 93 | 94 | 95 | /** 96 | * Returns the Command ID of this frame 97 | * @return int 98 | */ 99 | public function getCommandId() 100 | { 101 | return GeneralCommand::READ_REPORTING_CONFIGURATION; 102 | } 103 | 104 | /** 105 | * Returns the Frame Type of this frame 106 | * @return int 107 | */ 108 | public function getFrameType() 109 | { 110 | return ZCLFrame::FRAME_TYPE_PROFILE_WIDE; 111 | } 112 | } 113 | 114 | -------------------------------------------------------------------------------- /src/ZCL/General/ReadReportingConfigurationResponseCommand.php: -------------------------------------------------------------------------------- 1 | addAttributeReportingConfigurationStatusRecord($element); 35 | 36 | return $frame; 37 | } 38 | 39 | public function setFrame($frame) 40 | { 41 | while(strlen($frame)) 42 | { 43 | $attribute_record = new AttributeReportingConfigurationStatusRecord(); 44 | $attribute_record->consumeFrame($frame); 45 | $this->addAttributeReportingConfigurationStatusRecord($attribute_record); 46 | } 47 | } 48 | 49 | public function getFrame() 50 | { 51 | $frame = ""; 52 | 53 | foreach($this->attribute_reporting_configuration_status_records as $attribute_record) 54 | $frame .= $attribute_record->getFrame(); 55 | 56 | return $frame; 57 | } 58 | 59 | public function setAttributeReportingConfigurationStatusRecords(array $attribute_records) 60 | { 61 | $this->attribute_reporting_configuration_status_records = []; 62 | foreach($attribute_records as $attribute_record) 63 | $this->addAttributeReportingConfigurationStatusRecord($attribute_record); 64 | } 65 | 66 | public function getAttributeReportingConfigurationStatusRecords() 67 | { 68 | return $this->attribute_reporting_configuration_status_records; 69 | } 70 | 71 | public function addAttributeReportingConfigurationStatusRecord(AttributeReportingConfigurationStatusRecord $attribute_record) 72 | { 73 | $this->attribute_reporting_configuration_status_records[] = $attribute_record; 74 | } 75 | 76 | public function __toString() 77 | { 78 | $output = __CLASS__." (count: ".count($this->getAttributeReportingConfigurationStatusRecords()).", length: ".strlen($this->getFrame()).")".PHP_EOL; 79 | $attribute_records = $this->getAttributeReportingConfigurationStatusRecords(); 80 | $attribute_records_count = count($attribute_records); 81 | foreach($attribute_records as $key => $attribute_record) 82 | $output .= ($key + 1 == $attribute_records_count ? "`" : "|")."- ".$attribute_record.PHP_EOL; 83 | 84 | return $output; 85 | } 86 | 87 | 88 | /** 89 | * Returns the Command ID of this frame 90 | * @return int 91 | */ 92 | public function getCommandId() 93 | { 94 | return GeneralCommand::READ_REPORTING_CONFIGURATION_RESPONSE; 95 | } 96 | 97 | /** 98 | * Returns the Frame Type of this frame 99 | * @return int 100 | */ 101 | public function getFrameType() 102 | { 103 | return ZCLFrame::FRAME_TYPE_PROFILE_WIDE; 104 | } 105 | } 106 | 107 | -------------------------------------------------------------------------------- /src/ZCL/General/ReportAttributesCommand.php: -------------------------------------------------------------------------------- 1 | consumeFrame($frame); 30 | $this->addAttributeReport($attribute_report); 31 | } 32 | } 33 | 34 | public function getFrame() 35 | { 36 | $frame = ""; 37 | 38 | foreach($this->attribute_reports as $report_attributes_element) 39 | $frame .= $report_attributes_element->getFrame(); 40 | 41 | return $frame; 42 | } 43 | 44 | public function setAttributeReports(array $attribute_reports) 45 | { 46 | $this->attribute_reports = []; 47 | foreach($attribute_reports as $attribute_report) 48 | $this->addAttributeReport($attribute_report); 49 | } 50 | 51 | public function getAttributeReports() 52 | { 53 | return $this->attribute_reports; 54 | } 55 | 56 | public function addAttributeReport(AttributeReport $attribute_report) 57 | { 58 | $this->attribute_reports[] = $attribute_report; 59 | } 60 | 61 | public function __toString() 62 | { 63 | $output = __CLASS__." (count: ".count($this->getAttributeReports()).", length: ".strlen($this->getFrame()).")".PHP_EOL; 64 | foreach($this->getAttributeReports() as $attribute_report) 65 | $output .= "|- ".$attribute_report.PHP_EOL; 66 | 67 | return $output; 68 | } 69 | 70 | 71 | /** 72 | * Returns the Command ID of this frame 73 | * @return int 74 | */ 75 | public function getCommandId() 76 | { 77 | return GeneralCommand::REPORT_ATTRIBUTES; 78 | } 79 | 80 | /** 81 | * Returns the Frame Type of this frame 82 | * @return int 83 | */ 84 | public function getFrameType() 85 | { 86 | return ZCLFrame::FRAME_TYPE_PROFILE_WIDE; 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /src/ZCL/General/WriteAttributeRecord.php: -------------------------------------------------------------------------------- 1 | setAttributeId($attribute_id); 18 | $element->setDatatypeId($datatype_id); 19 | $element->setValue($value); 20 | return $element; 21 | } 22 | 23 | public function consumeFrame(&$frame) 24 | { 25 | $this->setAttributeId(Buffer::unpackInt16u($frame)); 26 | $this->setDatatypeId(Buffer::unpackInt8u($frame)); 27 | $this->setValue(Buffer::unpackDatatype($frame, $this->getDatatypeId())); 28 | } 29 | 30 | public function setFrame($frame) 31 | { 32 | $this->consumeFrame($frame); 33 | 34 | if(strlen($frame) > 0) 35 | throw new ZigbeeException("Still data left in frame buffer"); 36 | } 37 | 38 | public function getFrame() 39 | { 40 | $frame = ""; 41 | 42 | Buffer::packInt16u($frame, $this->getAttributeId()); 43 | Buffer::packInt8u($frame, $this->getDatatypeId()); 44 | Buffer::packDatatype($frame, $this->getDatatypeId(), $this->getValue()); 45 | 46 | return $frame; 47 | } 48 | 49 | public function setAttributeId($attribute_id) 50 | { 51 | $attribute_id = intval($attribute_id); 52 | if($attribute_id < 0x0000 || $attribute_id > 0xffff) 53 | throw new ZigbeeException("Invalid attribute id"); 54 | 55 | $this->attribute_id = $attribute_id; 56 | } 57 | 58 | public function getAttributeId() 59 | { 60 | return $this->attribute_id; 61 | } 62 | 63 | public function displayAttributeId() 64 | { 65 | return sprintf("0x%04x", $this->getAttributeId()); 66 | } 67 | 68 | public function setDatatypeId($datatype_id) 69 | { 70 | $datatype_id = intval($datatype_id); 71 | if($datatype_id < 0x00 || $datatype_id > 0xff) 72 | throw new ZigbeeException("Invalid datatype id"); 73 | 74 | $this->datatype_id = $datatype_id; 75 | } 76 | 77 | public function getDatatypeId() 78 | { 79 | return $this->datatype_id; 80 | } 81 | 82 | public function displayDatatypeId() 83 | { 84 | return sprintf("0x%02x", $this->getDatatypeId()); 85 | } 86 | 87 | public function setValue($value) 88 | { 89 | $this->value = $value; 90 | } 91 | 92 | public function getValue() 93 | { 94 | return $this->value; 95 | } 96 | 97 | public function displayValue() 98 | { 99 | return Buffer::displayDatatype($this->getDatatypeId(), $this->getValue()); 100 | } 101 | 102 | public function __toString() 103 | { 104 | return "AttributeId: ".$this->displayAttributeId().", DatatypeId: ".$this->displayDatatypeId().", Value: ".$this->displayValue(); 105 | } 106 | } 107 | 108 | -------------------------------------------------------------------------------- /src/ZCL/General/WriteAttributeStatusRecord.php: -------------------------------------------------------------------------------- 1 | setStatus($status); 18 | $element->setAttributeId($attribute_id); 19 | return $element; 20 | } 21 | 22 | public function consumeFrame(&$frame) 23 | { 24 | $this->setStatus(Buffer::unpackInt8u($frame)); 25 | $this->setAttributeId(Buffer::unpackInt16u($frame)); 26 | } 27 | 28 | public function setFrame($frame) 29 | { 30 | $this->consumeFrame($frame); 31 | 32 | if(strlen($frame) > 0) 33 | throw new ZigbeeException("Still data left in frame buffer"); 34 | } 35 | 36 | public function getFrame() 37 | { 38 | $frame = ""; 39 | 40 | Buffer::packInt8u($frame, $this->getStatus()); 41 | Buffer::packInt16u($frame, $this->getAttributeId()); 42 | 43 | return $frame; 44 | } 45 | 46 | public function setAttributeId($attribute_id) 47 | { 48 | $attribute_id = intval($attribute_id); 49 | if($attribute_id < 0x0000 || $attribute_id > 0xffff) 50 | throw new ZigbeeException("Invalid attribute id"); 51 | 52 | $this->attribute_id = $attribute_id; 53 | } 54 | 55 | public function getAttributeId() 56 | { 57 | return $this->attribute_id; 58 | } 59 | 60 | public function displayAttributeId() 61 | { 62 | return sprintf("0x%04x", $this->getAttributeId()); 63 | } 64 | 65 | /** 66 | * @param int $status 67 | * @throws ZigbeeException 68 | */ 69 | public function setStatus($status) 70 | { 71 | $status = intval($status); 72 | if($status < 0x00 || $status > 0xff) 73 | throw new ZigbeeException("Invalid status"); 74 | 75 | $this->status = $status; 76 | } 77 | 78 | /** 79 | * @return mixed 80 | */ 81 | public function getStatus() 82 | { 83 | return $this->status; 84 | } 85 | 86 | public function displayStatus() 87 | { 88 | return ZCLStatus::displayStatus($this->getStatus()); 89 | } 90 | 91 | public function __toString() 92 | { 93 | return "AttributeId: ".$this->displayAttributeId().", Status: ".$this->displayStatus(); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/ZCL/General/WriteAttributesCommand.php: -------------------------------------------------------------------------------- 1 | setWriteAttributeRecords($write_attribute_records); 23 | return $frame; 24 | } 25 | 26 | public function setFrame($frame) 27 | { 28 | while(strlen($frame)) 29 | { 30 | $write_attribute_record = new WriteAttributeRecord(); 31 | $write_attribute_record->consumeFrame($frame); 32 | $this->addWriteAttributeRecord($write_attribute_record); 33 | } 34 | } 35 | 36 | public function getFrame() 37 | { 38 | $frame = ""; 39 | 40 | foreach($this->write_attribute_records as $write_attribute_record) 41 | $frame .= $write_attribute_record->getFrame(); 42 | 43 | return $frame; 44 | } 45 | 46 | public function setWriteAttributeRecords(array $write_attribute_records) 47 | { 48 | $this->write_attribute_records = []; 49 | foreach($write_attribute_records as $write_attribute_record) 50 | $this->addWriteAttributeRecord($write_attribute_record); 51 | } 52 | 53 | public function getWriteAttributeRecords() 54 | { 55 | return $this->write_attribute_records; 56 | } 57 | 58 | public function addWriteAttributeRecord(WriteAttributeRecord $write_attribute_record) 59 | { 60 | $this->write_attribute_records[] = $write_attribute_record; 61 | } 62 | 63 | public function __toString() 64 | { 65 | $output = __CLASS__." (count: ".count($this->getWriteAttributeRecords()).", length: ".strlen($this->getFrame()).")".PHP_EOL; 66 | $write_attribute_records = $this->getWriteAttributeRecords(); 67 | $write_attributes_elements_count = count($write_attribute_records); 68 | foreach($write_attribute_records as $key => $write_attribute_record) 69 | $output .= ($key + 1 == $write_attributes_elements_count ? "`" : "|")."- ".$write_attribute_record.PHP_EOL; 70 | 71 | return $output; 72 | } 73 | 74 | 75 | /** 76 | * Returns the Command ID of this frame 77 | * @return int 78 | */ 79 | public function getCommandId() 80 | { 81 | return GeneralCommand::WRITE_ATTRIBUTES; 82 | } 83 | 84 | /** 85 | * Returns the Frame Type of this frame 86 | * @return int 87 | */ 88 | public function getFrameType() 89 | { 90 | return ZCLFrame::FRAME_TYPE_PROFILE_WIDE; 91 | } 92 | } 93 | 94 | -------------------------------------------------------------------------------- /src/ZCL/General/WriteAttributesResponseCommand.php: -------------------------------------------------------------------------------- 1 | setWriteAttributeStatusRecords($write_attribute_status_records); 28 | return $frame; 29 | } 30 | 31 | public function isSuccess() 32 | { 33 | return count($this->write_attribute_status_records) == 0; 34 | } 35 | 36 | public function setFrame($frame) 37 | { 38 | /** 39 | * If there are no write attribute status records in the constructed command, indicating that all attributes were 40 | * written successfully, a single write attribute status record shall be included in the 41 | * command, with the status field set to SUCCESS and the attribute identifier field 42 | * omitted. 43 | */ 44 | if(strlen($frame) == 1) 45 | { 46 | $status = Buffer::unpackInt8u($frame); 47 | if($status != ZCLStatus::SUCCESS) 48 | throw new ZigbeeException("If a ".__CLASS__." only has one byte, it should be the SUCCESS status"); 49 | 50 | return; 51 | } 52 | else 53 | while(strlen($frame)) 54 | { 55 | $write_attribute_status_record = new WriteAttributeStatusRecord(); 56 | $write_attribute_status_record->consumeFrame($frame); 57 | $this->write_attribute_status_records[] = $write_attribute_status_record; 58 | } 59 | } 60 | 61 | public function getFrame() 62 | { 63 | $frame = ""; 64 | 65 | // If there are no records, just send a single SUCCESS 66 | if(empty($this->write_attribute_status_records)) 67 | Buffer::packInt8u($frame, ZCLStatus::SUCCESS); 68 | else 69 | // Loop over the different records 70 | foreach($this->write_attribute_status_records as $write_attribute_status_record) 71 | $frame .= $write_attribute_status_record->getFrame(); 72 | 73 | return $frame; 74 | } 75 | 76 | public function setWriteAttributeStatusRecords(array $write_attribute_status_records) 77 | { 78 | $this->write_attribute_status_records = []; 79 | foreach($write_attribute_status_records as $write_attribute_status_record) 80 | $this->addWriteAttributeStatusRecord($write_attribute_status_record); 81 | } 82 | 83 | public function getWriteAttributeStatusRecords() 84 | { 85 | return $this->write_attribute_status_records; 86 | } 87 | 88 | public function addWriteAttributeStatusRecord(WriteAttributeStatusRecord $write_attribute_status_record) 89 | { 90 | if($write_attribute_status_record->getStatus() == ZCLStatus::SUCCESS) 91 | throw new ZigbeeException("Attributes with status SUCCESS should be omitted"); 92 | 93 | $this->write_attribute_status_records[] = $write_attribute_status_record; 94 | } 95 | 96 | public function __toString() 97 | { 98 | $output = __CLASS__." (count: ".count($this->getWriteAttributeStatusRecords()).", length: ".strlen($this->getFrame()).")".PHP_EOL; 99 | $write_attribute_status_records = $this->getWriteAttributeStatusRecords(); 100 | $write_attribute_status_records_count = count($write_attribute_status_records); 101 | foreach($write_attribute_status_records as $key => $write_attribute_status_record) 102 | $output .= ($key + 1 == $write_attribute_status_records_count ? "`" : "|")."- ".$write_attribute_status_record.PHP_EOL; 103 | 104 | return $output; 105 | } 106 | 107 | 108 | /** 109 | * Returns the Command ID of this frame 110 | * @return int 111 | */ 112 | public function getCommandId() 113 | { 114 | return GeneralCommand::WRITE_ATTRIBUTES_RESPONSE; 115 | } 116 | 117 | /** 118 | * Returns the Frame Type of this frame 119 | * @return int 120 | */ 121 | public function getFrameType() 122 | { 123 | return ZCLFrame::FRAME_TYPE_PROFILE_WIDE; 124 | } 125 | } 126 | 127 | -------------------------------------------------------------------------------- /src/ZCL/General/WriteAttributesStructuredCommand.php: -------------------------------------------------------------------------------- 1 | ["name" => "ZoneState", "description" => "", "datatype_id" => 0x30], 19 | self::ZONE_TYPE_ATTRIBUTE => ["name" => "ZoneType", "description" => "", "datatype_id" => 0x31], 20 | self::ZONE_STATUS_ATTRIBUTE => ["name" => "ZoneStatus", "description" => "", "datatype_id" => 0x19], 21 | self::IAS_CIE_ADDRESS_ATTRIBUTE => ["name" => "IasCieAddress", "description" => "", "datatype_id" => 0xf0], 22 | ]; 23 | 24 | const ZONE_STATUS_CHANGE_NOTIFICATION_COMMAND = ZoneStatusChangeNotificationCommand::COMMAND_ID; 25 | 26 | protected static $command = array( 27 | ZoneStatusChangeNotificationCommand::COMMAND_ID => 'Munisense\Zigbee\ZCL\IAS_Zone\ZoneStatusChangeNotificationCommand', 28 | ); 29 | } -------------------------------------------------------------------------------- /src/ZCL/IAS_Zone/ZoneStatusChangeNotificationCommand.php: -------------------------------------------------------------------------------- 1 | setZoneStatus($zone_status); 34 | $frame->setExtendedStatus($extended_status); 35 | return $frame; 36 | } 37 | 38 | /** 39 | * @param int $extended_status 40 | */ 41 | public function setExtendedStatus($extended_status) 42 | { 43 | $this->extended_status = $extended_status; 44 | } 45 | 46 | /** 47 | * @return int 48 | */ 49 | public function getExtendedStatus() 50 | { 51 | return $this->extended_status; 52 | } 53 | 54 | /** 55 | * @param \Munisense\Zigbee\ZCL\IAS_Zone\ZoneStatus $zone_status 56 | */ 57 | public function setZoneStatus($zone_status) 58 | { 59 | $this->zone_status = $zone_status; 60 | } 61 | 62 | /** 63 | * @return \Munisense\Zigbee\ZCL\IAS_Zone\ZoneStatus 64 | */ 65 | public function getZoneStatus() 66 | { 67 | return $this->zone_status; 68 | } 69 | 70 | /** 71 | * Returns the frame as a sequence of bytes. 72 | * 73 | * @return string $frame 74 | */ 75 | function getFrame() 76 | { 77 | $frame = ""; 78 | Buffer::packInt16u($frame, $this->getZoneStatus()->getValue()); 79 | Buffer::packInt8u($frame, $this->getExtendedStatus()); 80 | return $frame; 81 | } 82 | 83 | /** 84 | * @param string $frame 85 | */ 86 | function setFrame($frame) 87 | { 88 | $zone_status = new ZoneStatus(); 89 | $zone_status->setValue(Buffer::unpackInt16u($frame)); 90 | $this->setZoneStatus($zone_status); 91 | $this->setExtendedStatus(Buffer::unpackInt8u($frame)); 92 | } 93 | 94 | public function getCommandId() 95 | { 96 | return self::COMMAND_ID; 97 | } 98 | 99 | public function getFrameType() 100 | { 101 | return ZCLFrame::FRAME_TYPE_CLUSTER_SPECIFIC; 102 | } 103 | } -------------------------------------------------------------------------------- /src/ZCL/IZCLCommandFrame.php: -------------------------------------------------------------------------------- 1 | "SUCCESS", 29 | self::FAILURE => "FAILURE", 30 | self::MALFORMED_COMMAND => "MALFORMED_COMMAND", 31 | self::UNSUP_CLUSTER_COMMAND => "UNSUP_CLUSTER_COMMAND", 32 | self::UNSUP_GENERAL_COMMAND => "UNSUP_GENERAL_COMMAND", 33 | self::UNSUP_MANUF_CLUSTER_COMMAND => "UNSUP_MANUF_CLUSTER_COMMAND", 34 | self::UNSUP_MANUF_GENERAL_COMMAND => "UNSUP_MANUF_GENERAL_COMMAND", 35 | self::INVALID_FIELD => "INVALID_FIELD", 36 | self::UNSUPPORTED_ATTRIBUTE => "UNSUPPORTED_ATTRIBUTE", 37 | self::INVALID_VALUE => "INVALID_VALUE", 38 | self::READ_ONLY => "READ_ONLY", 39 | self::INSUFFICIENT_SPACE => "INSUFFICIENT_SPACE", 40 | self::DUPLICATE_EXIST => "DUPLICATE_EXIST", 41 | self::NOT_FOUND => "NOT_FOUND", 42 | self::UNREPORTABLE_ATTRIBUTE => "UNREPORTABLE_ATTRIBUTE", 43 | self::INVALID_DATA_TYPE => "INVALID_DATA_TYPE", 44 | self::HARDWARE_FAILURE => "HARDWARE_FAILURE", 45 | self::SOFTWARE_FAILURE => "SOFTWARE_FAILURE", 46 | self::CALIBRATION_ERROR => "CALIBRATION_ERROR", 47 | ); 48 | 49 | public static function displayStatus($status_id) 50 | { 51 | if(isset(self::$status[$status_id])) 52 | return self::$status[$status_id]; 53 | else 54 | return "Unknown (".sprintf("0x%02x", $status_id).")"; 55 | } 56 | } -------------------------------------------------------------------------------- /src/ZDP/Discovery/AbstractNWKAddrOfInterestReqCommand.php: -------------------------------------------------------------------------------- 1 | setNwkAddressOfInterest(Buffer::unpackInt16u($frame)); 23 | } 24 | 25 | public function getFrame() 26 | { 27 | $frame = ""; 28 | Buffer::packInt16u($frame, $this->getNwkAddressOfInterest()); 29 | return $frame; 30 | } 31 | 32 | public function setNwkAddressOfInterest($nwk_address) 33 | { 34 | if($nwk_address >= 0x0000 && $nwk_address <= 0xffff) 35 | $this->nwk_address_of_interest = $nwk_address; 36 | else 37 | throw new ZigbeeException("Nwk Address not in range 0x0000 - 0xffff: ".sprintf("0x%04x", $nwk_address)); 38 | } 39 | 40 | public function getNwkAddressOfInterest() 41 | { 42 | return $this->nwk_address_of_interest; 43 | } 44 | 45 | public function displayNwkAddressOfInterest() 46 | { 47 | return sprintf("0x%04x", $this->getNwkAddressOfInterest()); 48 | } 49 | 50 | public function __toString() 51 | { 52 | $output = __CLASS__." (length: ".strlen($this->getFrame()).")".PHP_EOL; 53 | $output .= "|- NwkAddr : ".$this->displayNwkAddressOfInterest().PHP_EOL; 54 | 55 | return $output; 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/ZDP/Discovery/ActiveEPReqCommand.php: -------------------------------------------------------------------------------- 1 | setNwkAddressOfInterest($nwk_address_of_interest); 20 | return $frame; 21 | } 22 | 23 | /** 24 | * Returns the Cluster ID of this frame 25 | * @return int 26 | */ 27 | public function getClusterId() 28 | { 29 | return Command::COMMAND_ACTIVE_EP_REQ; 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/ZDP/Discovery/ExtendedSimpleDescReqCommand.php: -------------------------------------------------------------------------------- 1 | setNwkAddressOfInterest($nwk_addr_of_interest); 25 | $frame->setEndpoint($endpoint); 26 | $frame->setStartIndex($start_index); 27 | return $frame; 28 | } 29 | 30 | public function setFrame($frame) 31 | { 32 | $this->setNwkAddressOfInterest(Buffer::unpackInt16u($frame)); 33 | $this->setEndpoint(Buffer::unpackInt8u($frame)); 34 | $this->setStartIndex(Buffer::unpackInt8u($frame)); 35 | } 36 | 37 | public function getFrame() 38 | { 39 | $frame = parent::getFrame(); 40 | Buffer::packInt8u($frame, $this->getStartIndex()); 41 | return $frame; 42 | } 43 | 44 | public function __toString() 45 | { 46 | $output = __CLASS__." (length: ".strlen($this->getFrame()).")".PHP_EOL; 47 | $output .= "|- NwkAddr : ".$this->displayNwkAddressOfInterest().PHP_EOL; 48 | $output .= "|- Endpoint : ".$this->displayEndpoint().PHP_EOL; 49 | $output .= "`- Start Index : ".$this->displayStartIndex().PHP_EOL; 50 | 51 | return $output; 52 | } 53 | 54 | public function setStartIndex($start_index) 55 | { 56 | $start_index = intval($start_index); 57 | if($start_index < 0x00 || $start_index > 0xff) 58 | throw new ZigbeeException("Invalid start index"); 59 | 60 | $this->start_index = $start_index; 61 | } 62 | 63 | public function getStartIndex() 64 | { 65 | return $this->start_index; 66 | } 67 | 68 | public function displayStartIndex() 69 | { 70 | return sprintf("0x%02x", $this->getStartIndex()); 71 | } 72 | 73 | /** 74 | * Returns the Cluster ID of this frame 75 | * @return int 76 | */ 77 | public function getClusterId() 78 | { 79 | return Command::COMMAND_EXTENDED_SIMPLE_DESC_REQ; 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /src/ZDP/Discovery/IEEEAddrReqCommand.php: -------------------------------------------------------------------------------- 1 | setRequestType(self::REQUEST_TYPE_SINGLE); 33 | $frame->setNwkAddress($nwk_address); 34 | $frame->setStartIndex(0x00); 35 | return $frame; 36 | } 37 | 38 | public static function constructExtended($nwk_address, $start_index = 0x00) 39 | { 40 | $frame = new self; 41 | $frame->setRequestType(self::REQUEST_TYPE_EXTENDED); 42 | $frame->setNwkAddress($nwk_address); 43 | $frame->setStartIndex($start_index); 44 | return $frame; 45 | } 46 | 47 | public function setFrame($frame) 48 | { 49 | $this->setNwkAddress(Buffer::unpackInt16u($frame)); 50 | $this->setRequestType(Buffer::unpackInt8u($frame)); 51 | $this->setStartIndex(Buffer::unpackInt8u($frame)); 52 | } 53 | 54 | public function getFrame() 55 | { 56 | $frame = ""; 57 | 58 | Buffer::packInt16u($frame, $this->getNwkAddress()); 59 | Buffer::packInt8u($frame, $this->getRequestType()); 60 | Buffer::packInt8u($frame, $this->getStartIndex()); 61 | 62 | return $frame; 63 | } 64 | 65 | public function setNwkAddress($nwk_address) 66 | { 67 | if($nwk_address >= 0x0000 && $nwk_address <= 0xffff) 68 | $this->nwk_address = $nwk_address; 69 | else 70 | throw new ZigbeeException("Invalid nwk address"); 71 | } 72 | 73 | public function getNwkAddress() 74 | { 75 | return $this->nwk_address; 76 | } 77 | 78 | public function displayNwkAddress() 79 | { 80 | return sprintf("0x%04x", $this->getNwkAddress()); 81 | } 82 | 83 | public function setRequestType($request_type) 84 | { 85 | if(!in_array($request_type, array(self::REQUEST_TYPE_SINGLE, self::REQUEST_TYPE_EXTENDED))) 86 | throw new ZigbeeException("Invalid request type"); 87 | 88 | $this->request_type = $request_type; 89 | } 90 | 91 | public function getRequestType() 92 | { 93 | return $this->request_type; 94 | } 95 | 96 | public function displayRequestType() 97 | { 98 | $request_type = $this->getRequestType(); 99 | switch($request_type) 100 | { 101 | case self::REQUEST_TYPE_SINGLE: $output = "Single Device Response"; break; 102 | case self::REQUEST_TYPE_EXTENDED: $output = "Extended Response"; break; 103 | default: $output = "unknown"; break; 104 | } 105 | 106 | return sprintf("%s (0x%02x)", $output, $request_type); 107 | } 108 | 109 | public function setStartIndex($start_index) 110 | { 111 | $start_index = intval($start_index); 112 | if($start_index < 0x00 || $start_index > 0xff) 113 | throw new ZigbeeException("Invalid start index"); 114 | 115 | $this->start_index = $start_index; 116 | } 117 | 118 | public function getStartIndex() 119 | { 120 | return $this->start_index; 121 | } 122 | 123 | public function displayStartIndex() 124 | { 125 | return sprintf("0x%02x", $this->getStartIndex()); 126 | } 127 | 128 | public function __toString() 129 | { 130 | $output = __CLASS__." (length: ".strlen($this->getFrame()).")".PHP_EOL; 131 | $output .= "|- NwkAddr : ".$this->displayNwkAddress().PHP_EOL; 132 | $output .= "|- RequestType : ".$this->displayRequestType().PHP_EOL; 133 | $output .= "`- StartIndex : ".$this->displayStartIndex().PHP_EOL; 134 | 135 | return $output; 136 | } 137 | 138 | /** 139 | * Returns the Cluster ID of this frame 140 | * @return int 141 | */ 142 | public function getClusterId() 143 | { 144 | return Command::COMMAND_IEEE_ADDR_REQ; 145 | } 146 | } 147 | 148 | -------------------------------------------------------------------------------- /src/ZDP/Discovery/IEEEAddrRspCommand.php: -------------------------------------------------------------------------------- 1 | setNwkAddressOfInterest($nwk_address_of_interest); 20 | return $frame; 21 | } 22 | 23 | /** 24 | * Returns the Cluster ID of this frame 25 | * @return int 26 | */ 27 | public function getClusterId() 28 | { 29 | return Command::COMMAND_NODE_DESC_REQ; 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/ZDP/Discovery/NwkAddrRspCommand.php: -------------------------------------------------------------------------------- 1 | setNwkAddressOfInterest($nwk_address_of_interest); 20 | return $frame; 21 | } 22 | 23 | /** 24 | * Returns the Cluster ID of this frame 25 | * @return int 26 | */ 27 | public function getClusterId() 28 | { 29 | return Command::COMMAND_POWER_DESC_REQ; 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/ZDP/Discovery/SimpleDescReqCommand.php: -------------------------------------------------------------------------------- 1 | setNwkAddressOfInterest($nwk_addr_of_interest); 24 | $frame->setEndpoint($endpoint); 25 | return $frame; 26 | } 27 | 28 | public function setFrame($frame) 29 | { 30 | $this->setNwkAddressOfInterest(Buffer::unpackInt16u($frame)); 31 | $this->setEndpoint(Buffer::unpackInt8u($frame)); 32 | } 33 | 34 | public function getFrame() 35 | { 36 | $frame = parent::getFrame(); 37 | Buffer::packInt8u($frame, $this->getEndpoint()); 38 | return $frame; 39 | } 40 | 41 | public function __toString() 42 | { 43 | $output = __CLASS__." (length: ".strlen($this->getFrame()).")".PHP_EOL; 44 | $output .= "|- NwkAddr : ".$this->displayNwkAddressOfInterest().PHP_EOL; 45 | $output .= "`- Endpoint : ".$this->displayEndpoint().PHP_EOL; 46 | 47 | return $output; 48 | } 49 | 50 | /** 51 | * @return int 52 | */ 53 | public function getEndpoint() 54 | { 55 | return $this->endpoint; 56 | } 57 | 58 | /** 59 | * @param int $endpoint 60 | * @throws \Munisense\Zigbee\Exception\ZigbeeException 61 | */ 62 | public function setEndpoint($endpoint) 63 | { 64 | if($endpoint >= 1 && $endpoint <= 240) 65 | $this->endpoint = $endpoint; 66 | else 67 | throw new ZigbeeException("Endpoint must be between 1 and 240"); 68 | } 69 | 70 | public function displayEndpoint() 71 | { 72 | return sprintf("0x%02x", $this->getEndpoint()); 73 | } 74 | 75 | /** 76 | * Returns the Cluster ID of this frame 77 | * @return int 78 | */ 79 | public function getClusterId() 80 | { 81 | return Command::COMMAND_SIMPLE_DESC_REQ; 82 | } 83 | } 84 | 85 | -------------------------------------------------------------------------------- /src/ZDP/Discovery/UserDescConfCommand.php: -------------------------------------------------------------------------------- 1 | setStatus($status); 30 | $frame->setNwkAddrOfInterest($nwk_addr_of_interest); 31 | return $frame; 32 | } 33 | 34 | public function setFrame($frame) 35 | { 36 | $this->setStatus(Buffer::unpackInt8u($frame)); 37 | $this->setNwkAddrOfInterest(Buffer::unpackInt16u($frame)); 38 | } 39 | 40 | public function getFrame() 41 | { 42 | $frame = ""; 43 | 44 | Buffer::packInt8u($frame, $this->getStatus()); 45 | Buffer::packInt16u($frame, $this->getNwkAddrOfInterest()); 46 | 47 | return $frame; 48 | } 49 | 50 | /** 51 | * @return int 52 | */ 53 | public function getStatus() 54 | { 55 | return $this->status; 56 | } 57 | 58 | /** 59 | * @param $status 60 | * @throws \Munisense\Zigbee\Exception\ZigbeeException 61 | */ 62 | public function setStatus($status) 63 | { 64 | if(in_array($status, self::$allowed_statusses)) 65 | $this->status = $status; 66 | else 67 | throw new ZigbeeException("Invalid status supplied"); 68 | } 69 | 70 | public function displayStatus() 71 | { 72 | return Status::displayStatus($this->getStatus()); 73 | } 74 | 75 | /** 76 | * @return array 77 | */ 78 | public static function getAllowedStatusses() 79 | { 80 | return self::$allowed_statusses; 81 | } 82 | 83 | /** 84 | * @param array $allowed_statusses 85 | */ 86 | public static function setAllowedStatusses($allowed_statusses) 87 | { 88 | self::$allowed_statusses = $allowed_statusses; 89 | } 90 | 91 | /** 92 | * @return int 93 | */ 94 | public function getNwkAddrOfInterest() 95 | { 96 | return $this->nwk_addr_of_interest; 97 | } 98 | 99 | /** 100 | * @param $nwk_address 101 | * @throws \Munisense\Zigbee\Exception\ZigbeeException 102 | */ 103 | public function setNwkAddrOfInterest($nwk_address) 104 | { 105 | if($nwk_address >= 0x0000 && $nwk_address <= 0xffff) 106 | $this->nwk_addr_of_interest = $nwk_address; 107 | else 108 | throw new ZigbeeException("Invalid nwk address"); 109 | } 110 | 111 | public function displayNwkAddrOfInterest() 112 | { 113 | return Buffer::displayInt16u($this->getNwkAddrOfInterest()); 114 | } 115 | 116 | public function __toString() 117 | { 118 | $output = __CLASS__." (length: ".strlen($this->getFrame()).")".PHP_EOL; 119 | $output .= "|- Status : ".$this->displayStatus().PHP_EOL; 120 | $output .= "|- NwkAddr : ".$this->displayNwkAddrOfInterest().PHP_EOL; 121 | 122 | return $output; 123 | } 124 | 125 | /** 126 | * Returns the Cluster ID of this frame 127 | * 128 | * @return int 129 | */ 130 | public function getClusterId() 131 | { 132 | return Command::COMMAND_USER_DESC_CONF; 133 | } 134 | } 135 | 136 | -------------------------------------------------------------------------------- /src/ZDP/Discovery/UserDescReqCommand.php: -------------------------------------------------------------------------------- 1 | setNwkAddressOfInterest($nwk_address_of_interest); 20 | return $frame; 21 | } 22 | 23 | /** 24 | * Returns the Cluster ID of this frame 25 | * @return int 26 | */ 27 | public function getClusterId() 28 | { 29 | return Command::COMMAND_USER_DESC_REQ; 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/ZDP/Discovery/UserDescSetCommand.php: -------------------------------------------------------------------------------- 1 | setNwkAddrOfInterest($nwk_addr_of_interest); 31 | $frame->setUserDescriptor($user_descriptor); 32 | return $frame; 33 | } 34 | 35 | public function setFrame($frame) 36 | { 37 | $this->setNwkAddrOfInterest(Buffer::unpackInt16u($frame)); 38 | 39 | // User Descriptor Length, unused, but may not remain in buffer 40 | Buffer::unpackInt8u($frame); 41 | $this->setUserDescriptor(new UserDescriptor($frame)); 42 | } 43 | 44 | public function getFrame() 45 | { 46 | $frame = ""; 47 | 48 | Buffer::packInt16u($frame, $this->getNwkAddrOfInterest()); 49 | 50 | $user_descr_frame = $this->getUserDescriptor()->getFrame(); 51 | Buffer::packInt8u($frame, strlen($user_descr_frame)); 52 | $frame .= $user_descr_frame; 53 | 54 | return $frame; 55 | } 56 | 57 | /** 58 | * @return int 59 | */ 60 | public function getNwkAddrOfInterest() 61 | { 62 | return $this->nwk_addr_of_interest; 63 | } 64 | 65 | /** 66 | * @param $nwk_address 67 | * @throws \Munisense\Zigbee\Exception\ZigbeeException 68 | */ 69 | public function setNwkAddrOfInterest($nwk_address) 70 | { 71 | if($nwk_address >= 0x0000 && $nwk_address <= 0xffff) 72 | $this->nwk_addr_of_interest = $nwk_address; 73 | else 74 | throw new ZigbeeException("Invalid nwk address"); 75 | } 76 | 77 | public function displayNwkAddrOfInterest() 78 | { 79 | return Buffer::displayInt16u($this->getNwkAddrOfInterest()); 80 | } 81 | 82 | /** 83 | * @return UserDescriptor 84 | */ 85 | public function getUserDescriptor() 86 | { 87 | return $this->user_descriptor; 88 | } 89 | 90 | /** 91 | * @param UserDescriptor $user_descriptor 92 | */ 93 | public function setUserDescriptor($user_descriptor) 94 | { 95 | $this->user_descriptor = $user_descriptor; 96 | } 97 | 98 | public function __toString() 99 | { 100 | $output = __CLASS__." (length: ".strlen($this->getFrame()).")".PHP_EOL; 101 | $output .= "|- NwkAddr : ".$this->displayNwkAddrOfInterest().PHP_EOL; 102 | $output .= preg_replace("/^ /", "`- ", preg_replace("/^/m", " ", $this->getUserDescriptor())); 103 | 104 | return $output; 105 | } 106 | 107 | /** 108 | * Returns the Cluster ID of this frame 109 | * 110 | * @return int 111 | */ 112 | public function getClusterId() 113 | { 114 | return Command::COMMAND_USER_DESC_SET; 115 | } 116 | } 117 | 118 | -------------------------------------------------------------------------------- /src/ZDP/Discovery/UserDescriptor.php: -------------------------------------------------------------------------------- 1 | setUserDescription($user_description); 25 | return $frame; 26 | } 27 | 28 | /** 29 | * Returns the frame as a sequence of bytes. 30 | * 31 | * @return string $frame 32 | */ 33 | function getFrame() 34 | { 35 | $frame = ""; 36 | 37 | // Note: 2.3.2.7 Suggests 16 bytes always, but the length field of the UserDescRsp command would then not be needed? 38 | $user_description = $this->getUserDescription(); 39 | for($x = 0; $x < strlen($user_description); $x++) 40 | if(isset($user_description[$x])) 41 | Buffer::packInt8u($frame, ord($user_description[$x])); 42 | 43 | return $frame; 44 | } 45 | 46 | /** 47 | * @param string $frame 48 | */ 49 | function setFrame($frame) 50 | { 51 | $this->setUserDescription(substr($frame, 0, 16)); 52 | } 53 | 54 | /** 55 | * @param string $user_description Description of maximum 16 bytes long 56 | * @throws ZigbeeException When the input is too long 57 | */ 58 | public function setUserDescription($user_description) 59 | { 60 | if(strlen($user_description) <= 16) 61 | $this->user_description = $user_description; 62 | else 63 | throw new ZigbeeException("User Description may not be longer than 16 bytes: " .strlen($user_description)); 64 | } 65 | 66 | /** 67 | * @return string 68 | */ 69 | public function getUserDescription() 70 | { 71 | return $this->user_description; 72 | } 73 | 74 | /** 75 | * @return string 76 | */ 77 | public function displayUserDescription() 78 | { 79 | return $this->user_description; 80 | } 81 | public function __toString() 82 | { 83 | $output = __CLASS__." (length: ".strlen($this->getFrame()).")".PHP_EOL; 84 | $output .= " `- Description: ".$this->displayUserDescription(); 85 | return $output; 86 | } 87 | } -------------------------------------------------------------------------------- /src/ZDP/IZDPCommandFrame.php: -------------------------------------------------------------------------------- 1 | setStartIndex($start_index); 23 | return $frame; 24 | } 25 | 26 | public function setFrame($frame) 27 | { 28 | $this->setStartIndex(Buffer::unpackInt8u($frame)); 29 | } 30 | 31 | public function getFrame() 32 | { 33 | $frame = ""; 34 | Buffer::packInt8u($frame, $this->getStartIndex()); 35 | return $frame; 36 | } 37 | 38 | public function setStartIndex($start_index) 39 | { 40 | $start_index = intval($start_index); 41 | if($start_index < 0x00 || $start_index > 0xff) 42 | throw new ZigbeeException("Invalid start index"); 43 | 44 | $this->start_index = $start_index; 45 | } 46 | 47 | public function getStartIndex() 48 | { 49 | return $this->start_index; 50 | } 51 | 52 | public function displayStartIndex() 53 | { 54 | return sprintf("0x%02x", $this->getStartIndex()); 55 | } 56 | 57 | public function __toString() 58 | { 59 | $output = __CLASS__." (length: ".strlen($this->getFrame()).")".PHP_EOL; 60 | $output .= "`- StartIndex : ".$this->displayStartIndex().PHP_EOL; 61 | return $output; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/ZDP/Network/MgmtBindReqCommand.php: -------------------------------------------------------------------------------- 1 | "SUCCESS", 24 | self::INV_REQUESTTYPE => "INV_REQUESTTYPE", 25 | self::DEVICE_NOT_FOUND => "DEVICE_NOT_FOUND", 26 | self::INVALID_EP => "INVALID_EP", 27 | self::NOT_ACTIVE => "NOT_ACTIVE", 28 | self::NOT_SUPPORTED => "NOT_SUPPORTED", 29 | self::TIMEOUT => "TIMEOUT", 30 | self::NO_MATCH => "NO_MATCH", 31 | self::NO_ENTRY => "UNSUPPORTED_ATTRIBUTE", 32 | self::NO_DESCRIPTOR => "NO_DESCRIPTOR", 33 | self::INSUFFICIENT_SPACE => "INSUFFICIENT_SPACE", 34 | self::NOT_PERMITTED => "NOT_PERMITTED", 35 | self::TABLE_FULL => "TABLE_FULL", 36 | self::NOT_AUTHORIZED => "NOT_AUTHORIZED" 37 | ); 38 | 39 | public static function displayStatus($status_id) 40 | { 41 | if(isset(self::$status[$status_id])) 42 | return self::$status[$status_id]; 43 | else 44 | return "Unknown (".sprintf("0x%02x", $status_id).")"; 45 | } 46 | } -------------------------------------------------------------------------------- /src/ZDP/ZDPFrame.php: -------------------------------------------------------------------------------- 1 | setPayloadObject($payload); 19 | $frame->setTransactionId($transaction_id); 20 | return $frame; 21 | } 22 | 23 | public function __construct($frame = null, $command_id = 0xffff) 24 | { 25 | $this->setCommandId($command_id); 26 | 27 | if($frame !== null) 28 | $this->setFrame($frame); 29 | } 30 | 31 | public function setFrame($frame) 32 | { 33 | $this->setTransactionId(Buffer::unpackInt8u($frame)); 34 | $this->setPayload($frame); 35 | } 36 | 37 | public function getFrame() 38 | { 39 | $frame = ""; 40 | 41 | Buffer::packInt8u($frame, $this->getTransactionId()); 42 | $frame .= $this->getPayload(); 43 | 44 | return $frame; 45 | } 46 | 47 | public function displayFrame() 48 | { 49 | return Buffer::displayOctetString($this->getFrame()); 50 | } 51 | 52 | public function setTransactionId($transaction_id) 53 | { 54 | $transaction_id = intval($transaction_id); 55 | if($transaction_id < 0x00 || $transaction_id > 0xff) 56 | throw new ZigbeeException("Invalid transaction id: ".$transaction_id); 57 | 58 | $this->transaction_id = $transaction_id; 59 | } 60 | 61 | public function getTransactionId() 62 | { 63 | return $this->transaction_id; 64 | } 65 | 66 | public function displayTransactionId() 67 | { 68 | return sprintf("0x%02x", $this->getTransactionId()); 69 | } 70 | 71 | public function setCommandId($command_id) 72 | { 73 | $command_id = intval($command_id); 74 | if($command_id < 0x0000 || $command_id > 0xffff) 75 | throw new ZigbeeException("Invalid command id"); 76 | 77 | $this->command_id = $command_id; 78 | } 79 | 80 | public function getCommandId() 81 | { 82 | return $this->command_id; 83 | } 84 | 85 | public function displayCommandId() 86 | { 87 | return Command::displayCommand($this->getCommandId()); 88 | } 89 | 90 | public function setPayload($payload) 91 | { 92 | $this->payload = $payload; 93 | } 94 | 95 | public function getPayload() 96 | { 97 | return $this->payload; 98 | } 99 | 100 | public function setPayloadObject(IZDPCommandFrame $object) 101 | { 102 | $this->setCommandId($object->getClusterId()); 103 | $this->setPayload($object->getFrame()); 104 | return; 105 | } 106 | 107 | public function getPayloadObject() 108 | { 109 | $class = $this->findClassOfPayload(); 110 | return new $class($this->getPayload()); 111 | } 112 | 113 | public static function findClassByCluster($cluster_id) 114 | { 115 | if(isset(Command::$command[$cluster_id])) 116 | return Command::$command[$cluster_id]['class']; 117 | 118 | throw new ZigbeeException("Payload class not found"); 119 | } 120 | 121 | protected function findClassOfPayload() 122 | { 123 | return self::findClassByCluster($this->getCommandId()); 124 | } 125 | 126 | public function displayPayload() 127 | { 128 | return Buffer::displayOctetString($this->getPayload()); 129 | } 130 | 131 | public function __toString() 132 | { 133 | $output = __CLASS__." (length: ".strlen($this->getFrame()).", command: ".$this->displayCommandId().")".PHP_EOL; 134 | $output .= "|- TransactionId : ".$this->displayTransactionId().PHP_EOL; 135 | $output .= "|- Payload (length: ".strlen($this->getPayload()).")".PHP_EOL; 136 | 137 | try 138 | { 139 | $output .= preg_replace("/^ /", "`- ", preg_replace("/^/m", " ", $this->getPayloadObject())); 140 | } 141 | catch(\Exception $e) 142 | { 143 | $output .= "`-> ".$this->displayPayload().PHP_EOL; 144 | } 145 | 146 | return $output; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /tests/APS/APSFrameTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00", $frame->displayFrame()); 17 | } 18 | 19 | public function testZCLInclusion() 20 | { 21 | $zcl_frame = ZCLFrame::construct(ReadAttributesCommand::construct([])); 22 | 23 | $aps_frame = new APSFrame(); 24 | $aps_frame->setPayloadObject($zcl_frame); 25 | 26 | // The APS payload should be the same as the frame 27 | $this->assertEquals($zcl_frame->getFrame(), $aps_frame->getPayload()); 28 | $this->assertEquals(APSFrame::FRAME_TYPE_DATA, $aps_frame->getFrameType()); 29 | } 30 | 31 | public function testSetters() 32 | { 33 | $frame = new APSFrame(); 34 | $frame->setDestinationEndpoint(0x0a); 35 | $frame->setClusterId(0x0001); 36 | $frame->setProfileId(0xf123); 37 | $frame->setSourceEndpoint(0x0b); 38 | $frame->setApsCounter(0xfe); 39 | $this->assertEquals("0x00 0x0a 0x01 0x00 0x23 0xf1 0x0b 0xfe", $frame->displayFrame()); 40 | } 41 | 42 | /** 43 | * 2.2.5.1.2 This field shall be included in the frame only if the 44 | * delivery mode sub-field of the frame control field is set to 0b00 (normal unicast 45 | * delivery), 0b01 (indirect delivery where the indirect address mode sub-field of the 46 | * frame control field is also set to 0), or 0b10 (broadcast delivery). 47 | */ 48 | public function testDestinationEndpoint() 49 | { 50 | $frame = new APSFrame(); 51 | $frame->setDestinationEndpoint(0x0a); 52 | $frame->setGroupAddress(0xf00d); 53 | 54 | // Unicast, broadcast and indirect have the destination endpoint but not the group_id 55 | $frame->setDeliveryMode(APSFrame::DELIVERY_MODE_UNICAST); 56 | $this->assertEquals("0x00 0x0a 0x00 0x00 0x00 0x00 0x00 0x00", $frame->displayFrame()); 57 | $frame->setDeliveryMode(APSFrame::DELIVERY_MODE_BROADCAST); 58 | $this->assertEquals("0x08 0x0a 0x00 0x00 0x00 0x00 0x00 0x00", $frame->displayFrame()); 59 | $frame->setDeliveryMode(APSFrame::DELIVERY_MODE_INDIRECT); 60 | $this->assertEquals("0x04 0x0a 0x00 0x00 0x00 0x00 0x00 0x00", $frame->displayFrame()); 61 | } 62 | 63 | public function testGroupId() 64 | { 65 | $frame = new APSFrame(); 66 | $frame->setDestinationEndpoint(0x0a); 67 | $frame->setGroupAddress(0xf00d); 68 | 69 | // Group ID should be included, but not the destination 70 | $frame->setDeliveryMode(APSFrame::DELIVERY_MODE_GROUP_ADDRESS); 71 | $this->assertEquals("0x0c 0x0d 0xf0 0x00 0x00 0x00 0x00 0x00 0x00", $frame->displayFrame()); 72 | } 73 | 74 | public function testReverse() 75 | { 76 | $input = chr(0x00) . chr(0x0a) . chr(0x01) . chr(0x00) . chr(0x23) . chr(0xf1) . chr(0x0b) . chr(0xfe); 77 | $frame = new APSFrame($input); 78 | $this->assertEquals($input, $frame->getFrame()); 79 | } 80 | } -------------------------------------------------------------------------------- /tests/ZCL/ClusterFactoryTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf("Munisense\\Zigbee\\ZCL\\IAS_Zone\\IAS_Zone", ClusterFactory::getClusterClassInstance(IAS_Zone::CLUSTER_ID)); 11 | } 12 | 13 | /** 14 | * @throws \Munisense\Zigbee\Exception\ZigbeeException 15 | * @expectedException \Munisense\Zigbee\Exception\ZigbeeException 16 | */ 17 | public function testgetClusterClassInstance__Invalid() 18 | { 19 | ClusterFactory::getClusterClassInstance(0xffff); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/ZCL/General/AttributeInformationTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(0x0001, $element->getAttributeId()); 11 | $this->assertEquals(0x20, $element->getDatatypeId()); 12 | } 13 | 14 | public function testToString() 15 | { 16 | $this->assertEquals("AttributeId: 0x0001, DatatypeId: 0x20",AttributeInformation::construct(0x0001, 0x20)->__toString()); 17 | } 18 | } -------------------------------------------------------------------------------- /tests/ZCL/General/AttributeRecordTest.php: -------------------------------------------------------------------------------- 1 | frame = chr(AttributeRecord::DIRECTION_SERVER_TO_CLIENT) . chr(0x20) . chr(0x00); 14 | } 15 | 16 | public function testConstructor() 17 | { 18 | $elem = new AttributeRecord($this->frame); 19 | $this->assertEquals(AttributeRecord::DIRECTION_SERVER_TO_CLIENT, $elem->getDirection()); 20 | $this->assertEquals(self::ATTRIBUTE_ID, $elem->getAttributeId()); 21 | } 22 | 23 | public function testConstruct() 24 | { 25 | $elem = AttributeRecord::construct(AttributeRecord::DIRECTION_SERVER_TO_CLIENT, self::ATTRIBUTE_ID); 26 | $this->assertEquals(AttributeRecord::DIRECTION_SERVER_TO_CLIENT, $elem->getDirection()); 27 | $this->assertEquals(self::ATTRIBUTE_ID, $elem->getAttributeId()); 28 | } 29 | 30 | public function testDisplay() 31 | { 32 | $elem = new AttributeRecord($this->frame); 33 | $this->assertEquals("0x00", $elem->displayDirection()); 34 | $this->assertEquals("0x0020", $elem->displayAttributeId()); 35 | $this->assertEquals("Direction: 0x00, AttributeId: 0x0020", $elem->__toString()); 36 | $this->assertEquals("0x00 0x20 0x00", $elem->displayFrame()); 37 | } 38 | 39 | public function testReverse() 40 | { 41 | $elem = AttributeRecord::construct(AttributeRecord::DIRECTION_SERVER_TO_CLIENT, self::ATTRIBUTE_ID); 42 | $old_frame = $elem->getFrame(); 43 | $new_elem = new AttributeRecord($old_frame); 44 | $this->assertEquals($old_frame, $new_elem->getFrame()); 45 | } 46 | } -------------------------------------------------------------------------------- /tests/ZCL/General/AttributeReportingConfigurationRecordTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x01 0x34 0x12 0x3c 0x00", $record->displayFrame()); 14 | } 15 | 16 | public function testConstructReported() 17 | { 18 | $record = AttributeReportingConfigurationRecord::constructReported( 19 | 0x1234, 0x23, 60, 10, 5 20 | ); 21 | $this->assertEquals("0x00 0x34 0x12 0x23 0x3c 0x00 0x0a 0x00 0x05 0x00 0x00 0x00", $record->displayFrame()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/ZCL/General/AttributeReportingConfigurationStatusRecordTest.php: -------------------------------------------------------------------------------- 1 | setStatus($allowed_status); 26 | $this->assertEquals($allowed_status, $record->getStatus()); 27 | } 28 | 29 | foreach($disallowed_statusses as $disallowed_status) 30 | { 31 | try 32 | { 33 | $record->setStatus($disallowed_status); 34 | $this->fail("setStatus should not accept status " . ZCLStatus::displayStatus($disallowed_status)); 35 | } 36 | catch(ZigbeeException $e) {} 37 | } 38 | } 39 | 40 | /** 41 | * If the status field is not set to SUCCESS, all fields except the direction and 42 | * attribute identifier fields shall be omitted. 43 | */ 44 | public function testErrorFrame() 45 | { 46 | $record = new AttributeReportingConfigurationStatusRecord(); 47 | $record->setStatus(ZCLStatus::UNSUPPORTED_ATTRIBUTE); 48 | $record->setAttributeId(0x1234); 49 | $record->setDatatypeId(0x23); 50 | 51 | $this->assertEquals("0x86 0x00 0x34 0x12", $record->displayFrame()); 52 | } 53 | 54 | public function testConstructWithError() 55 | { 56 | $record = AttributeReportingConfigurationStatusRecord::constructWithError( 57 | ZCLStatus::UNSUPPORTED_ATTRIBUTE, 58 | AttributeReportingConfigurationStatusRecord::DIRECTION_SERVER_TO_CLIENT, 59 | 0x0023 60 | ); 61 | 62 | $this->assertEquals("0x86 0x00 0x23 0x00", $record->displayFrame()); 63 | } 64 | 65 | public function testConstructorSuccess() 66 | { 67 | $record = AttributeReportingConfigurationStatusRecord::constructSuccess( 68 | AttributeReportingConfigurationRecord::constructReceived(0x1234, 60) 69 | ); 70 | 71 | $this->assertEquals("0x00 0x01 0x34 0x12 0x3c 0x00", $record->displayFrame()); 72 | } 73 | 74 | public function testGetAttributeReportingConfigurationRecord() 75 | { 76 | // Test with a Received Object 77 | $parent = AttributeReportingConfigurationRecord::constructReceived(0x1234, 60); 78 | $record = AttributeReportingConfigurationStatusRecord::constructSuccess($parent); 79 | $config_record = $record->getAttributeReportingConfigurationRecord(); 80 | $this->assertInstanceOf("Munisense\\Zigbee\\ZCL\\General\\AttributeReportingConfigurationRecord", $config_record); 81 | $this->assertEquals($parent->displayFrame(), $config_record->displayFrame()); 82 | 83 | // Test with a Reported Object 84 | $parent = AttributeReportingConfigurationRecord::constructReported(0x1234, 60, 400, 200, 12); 85 | $record = AttributeReportingConfigurationStatusRecord::constructSuccess($parent); 86 | $config_record = $record->getAttributeReportingConfigurationRecord(); 87 | $this->assertInstanceOf("Munisense\\Zigbee\\ZCL\\General\\AttributeReportingConfigurationRecord", $config_record); 88 | $this->assertEquals($parent->displayFrame(), $config_record->displayFrame()); 89 | } 90 | 91 | /** 92 | * @expectedException \Munisense\Zigbee\Exception\ZigbeeException 93 | */ 94 | public function testGetAttributeReportingConfigurationRecord_Failure() 95 | { 96 | $record = AttributeReportingConfigurationStatusRecord::constructWithError(ZCLStatus::UNREPORTABLE_ATTRIBUTE, AttributeRecord::DIRECTION_SERVER_TO_CLIENT, 0x0012); 97 | 98 | // Should throw an exception 99 | $record->getAttributeReportingConfigurationRecord(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /tests/ZCL/General/ConfigureReportingCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('0x01 0x34 0x12 0x3c 0x00 0x00 0x67 0x45 0x23 0x3c 0x00 0x0a 0x00 0x0c 0x00 0x00 0x00', $zcl->displayFrame()); 15 | } 16 | 17 | public function testReverse() 18 | { 19 | $old_zcl = ConfigureReportingCommand::construct([ 20 | AttributeReportingConfigurationRecord::constructReceived(0x1234, 60), 21 | AttributeReportingConfigurationRecord::constructReported(0x4567, 0x23, 60, 10, 12) 22 | ]); 23 | 24 | $old_zcl_frame = $old_zcl->getFrame(); 25 | 26 | $new = new ConfigureReportingCommand($old_zcl_frame); 27 | $this->assertEquals($old_zcl_frame, $new->getFrame()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/ZCL/General/ConfigureReportingResponseCommandTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($frame->isSuccess()); 16 | $this->assertEquals("0x00", $frame->displayFrame()); 17 | } 18 | 19 | public function testStaticConstruct() 20 | { 21 | $zcl = ConfigureReportingResponseCommand::construct([ 22 | AttributeStatusRecord::construct(ZCLStatus::UNREPORTABLE_ATTRIBUTE, AttributeReportingConfigurationStatusRecord::DIRECTION_SERVER_TO_CLIENT , 0x1234), 23 | AttributeStatusRecord::construct(ZCLStatus::CALIBRATION_ERROR, AttributeReportingConfigurationStatusRecord::DIRECTION_SERVER_TO_CLIENT , 0x4567) 24 | ]); 25 | 26 | $this->assertEquals('0x8c 0x00 0x34 0x12 0xc2 0x00 0x67 0x45', $zcl->displayFrame()); 27 | } 28 | 29 | public function testReverse() 30 | { 31 | $old_zcl = ConfigureReportingResponseCommand::construct([ 32 | AttributeStatusRecord::construct(ZCLStatus::UNREPORTABLE_ATTRIBUTE, AttributeReportingConfigurationStatusRecord::DIRECTION_SERVER_TO_CLIENT , 0x1234), 33 | AttributeStatusRecord::construct(ZCLStatus::CALIBRATION_ERROR, AttributeReportingConfigurationStatusRecord::DIRECTION_SERVER_TO_CLIENT , 0x4567) 34 | ]); 35 | 36 | $old_zcl_frame = $old_zcl->getFrame(); 37 | 38 | $new = new ConfigureReportingResponseCommand($old_zcl_frame); 39 | $this->assertEquals($old_zcl_frame, $new->getFrame()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/ZCL/General/DiscoverAttributesCommandTest.php: -------------------------------------------------------------------------------- 1 | frame = DiscoverAttributesCommand::construct(self::START_ATTRIBUTE_IDENTIFIER, self::MAXIMUM_ATTRIBUTE_IDENTIFIERS); 20 | } 21 | 22 | public function testStaticConstruct() 23 | { 24 | $this->assertEquals('0x00 0x00 0x20', $this->frame->displayFrame()); 25 | } 26 | 27 | public function testZCLInclusion() 28 | { 29 | $zcl = new ZCLFrame(); 30 | 31 | try 32 | { 33 | $zcl->setPayloadObject($this->frame); 34 | } 35 | catch(\Exception $e) 36 | { 37 | $this->fail("Could not include DiscoverAttributesCommand in a ZCLFrame: ".$e->getMessage()); 38 | } 39 | } 40 | 41 | public function testReverse() 42 | { 43 | $old_zcl_frame = $this->frame->getFrame(); 44 | $new = new DiscoverAttributesCommand($old_zcl_frame); 45 | $this->assertEquals($old_zcl_frame, $new->getFrame()); 46 | } 47 | } -------------------------------------------------------------------------------- /tests/ZCL/General/DiscoverAttributesResponseCommandTest.php: -------------------------------------------------------------------------------- 1 | zcl_str = chr(0x01).chr(0x02).chr(0x01).chr(0x21).chr(0x08).chr(0x04).chr(0x22); 20 | $this->zcl_attributes_element_0 = AttributeInformation::construct(0x0102, 0x21); 21 | $this->zcl_attributes_element_1 = AttributeInformation::construct(0x0408, 0x22); 22 | $this->zcl_frame = DiscoverAttributesResponseCommand::construct(true, [ 23 | $this->zcl_attributes_element_0, $this->zcl_attributes_element_1 24 | ]); 25 | } 26 | 27 | public function testDisplayFrame() 28 | { 29 | $this->assertEquals('0x01 0x02 0x01 0x21 0x08 0x04 0x22', $this->zcl_frame->displayFrame()); 30 | } 31 | 32 | public function testReverse() 33 | { 34 | $old_zcl_frame = $this->zcl_frame->getFrame(); 35 | $new = new ZCLFrame($old_zcl_frame); 36 | $this->assertEquals($old_zcl_frame, $new->getFrame()); 37 | } 38 | 39 | public function testSetFrame() 40 | { 41 | $frame = new DiscoverAttributesResponseCommand($this->zcl_str); 42 | 43 | $records = $frame->getAttributes(); 44 | $this->assertEquals(2, count($records)); 45 | 46 | $this->assertEquals($this->zcl_attributes_element_0, $records[0]); 47 | $this->assertEquals($this->zcl_attributes_element_1, $records[1]); 48 | } 49 | } -------------------------------------------------------------------------------- /tests/ZCL/General/GeneralCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("Report Attributes", GeneralCommand::displayCommand(0x0a)); 11 | $this->assertEquals("Unknown (0xff)", GeneralCommand::displayCommand(0xFF)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/ZCL/General/ReadAttributesCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('0x02 0x00 0x09 0x08', $zcl->displayFrame()); 15 | } 16 | 17 | public function testReverse() 18 | { 19 | $old_zcl = ReadAttributesCommand::construct([ 20 | AttributeIdentifier::construct(0x02), 21 | AttributeIdentifier::construct(0x0809) 22 | ]); 23 | 24 | $old_zcl_frame = $old_zcl->getFrame(); 25 | 26 | $new = new ReadAttributesCommand($old_zcl_frame); 27 | 28 | $this->assertEquals($old_zcl_frame, $new->getFrame()); 29 | } 30 | } -------------------------------------------------------------------------------- /tests/ZCL/General/ReadAttributesResponseCommandTest.php: -------------------------------------------------------------------------------- 1 | zcl_str = chr(0x02).chr(0x01).chr(0xc0).chr(0x08).chr(0x04).chr(0x00).chr(0x22).chr(0x28).chr(0x23).chr(0x00); 22 | $this->zcl_read_attribute_status_record_0 = ReadAttributesStatusRecord::constructFailure(0x0102, ZCLStatus::HARDWARE_FAILURE); 23 | $this->zcl_read_attribute_status_record_1 = ReadAttributesStatusRecord::constructSuccess(0x0408, 0x22, 9000); 24 | $this->zcl_frame = ReadAttributesResponseCommand::construct([ 25 | $this->zcl_read_attribute_status_record_0, $this->zcl_read_attribute_status_record_1 26 | ]); 27 | } 28 | 29 | public function testDisplayFrame() 30 | { 31 | $this->assertEquals('0x02 0x01 0xc0 0x08 0x04 0x00 0x22 0x28 0x23 0x00', $this->zcl_frame->displayFrame()); 32 | } 33 | 34 | public function testReverse() 35 | { 36 | $old_zcl_frame = $this->zcl_frame->getFrame(); 37 | $new = new ZCLFrame($old_zcl_frame); 38 | $this->assertEquals($old_zcl_frame, $new->getFrame()); 39 | } 40 | 41 | public function testSetFrame() 42 | { 43 | $frame = new ReadAttributesResponseCommand($this->zcl_str); 44 | 45 | $records = $frame->getReadAttributesStatusRecords(); 46 | $this->assertEquals(2, count($records)); 47 | 48 | $this->assertEquals($this->zcl_read_attribute_status_record_0, $records[0]); 49 | $this->assertEquals($this->zcl_read_attribute_status_record_1, $records[1]); 50 | } 51 | } -------------------------------------------------------------------------------- /tests/ZCL/General/ReadReportingConfigurationCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('0x01 0x02 0x01 0x00 0x04 0x03', $zcl->displayFrame()); 15 | } 16 | 17 | public function testReverse() 18 | { 19 | $old_zcl = ReadReportingConfigurationCommand::construct([ 20 | AttributeRecord::construct(AttributeRecord::DIRECTION_CLIENT_TO_SERVER, 0x0102), 21 | AttributeRecord::construct(AttributeRecord::DIRECTION_SERVER_TO_CLIENT, 0x0304) 22 | ]); 23 | 24 | $old_zcl_frame = $old_zcl->getFrame(); 25 | 26 | $new = new ReadReportingConfigurationCommand($old_zcl_frame); 27 | 28 | $this->assertEquals($old_zcl_frame, $new->getFrame()); 29 | } 30 | } -------------------------------------------------------------------------------- /tests/ZCL/General/WriteAttributesCommandTest.php: -------------------------------------------------------------------------------- 1 | zcl_str = chr(0x02).chr(0x01).chr(0x21).chr(0x37).chr(0x00).chr(0x08).chr(0x04).chr(0x22).chr(0x28).chr(0x23).chr(0x00); 20 | $this->write_attribute_record_0 = WriteAttributeRecord::construct(0x0102, 0x21, 55); 21 | $this->write_attribute_record_1 = WriteAttributeRecord::construct(0x0408, 0x22, 9000); 22 | $this->zcl_frame = WriteAttributesCommand::construct([ 23 | $this->write_attribute_record_0, $this->write_attribute_record_1 24 | ]); 25 | } 26 | 27 | public function testDisplayFrame() 28 | { 29 | $this->assertEquals('0x02 0x01 0x21 0x37 0x00 0x08 0x04 0x22 0x28 0x23 0x00', $this->zcl_frame->displayFrame()); 30 | } 31 | 32 | public function testReverse() 33 | { 34 | $old_zcl_frame = $this->zcl_frame->getFrame(); 35 | $new = new ZCLFrame($old_zcl_frame); 36 | $this->assertEquals($old_zcl_frame, $new->getFrame()); 37 | } 38 | 39 | public function testSetFrame() 40 | { 41 | $frame = new WriteAttributesCommand($this->zcl_str); 42 | 43 | $records = $frame->getWriteAttributeRecords(); 44 | $this->assertEquals(2, count($records)); 45 | 46 | $this->assertEquals($this->write_attribute_record_0, $records[0]); 47 | $this->assertEquals($this->write_attribute_record_1, $records[1]); 48 | } 49 | } -------------------------------------------------------------------------------- /tests/ZCL/General/WriteAttributesResponseCommandTest.php: -------------------------------------------------------------------------------- 1 | zcl_str = chr(0xc2).chr(0x21).chr(0x00).chr(0xc0).chr(0x22).chr(0x00); 22 | $this->zcl_write_attribute_status_record_0 = WriteAttributeStatusRecord::construct(ZCLStatus::CALIBRATION_ERROR, 0x21); 23 | $this->zcl_write_attribute_status_record_1 = WriteAttributeStatusRecord::construct(ZCLStatus::HARDWARE_FAILURE, 0x22); 24 | $this->zcl_frame = WriteAttributesResponseCommand::construct([ 25 | $this->zcl_write_attribute_status_record_0, $this->zcl_write_attribute_status_record_1 26 | ]); 27 | } 28 | 29 | public function testDisplayFrame() 30 | { 31 | $this->assertEquals('0xc2 0x21 0x00 0xc0 0x22 0x00', $this->zcl_frame->displayFrame()); 32 | } 33 | 34 | public function testReverse() 35 | { 36 | $old_zcl_frame = $this->zcl_frame->getFrame(); 37 | $new = new ZCLFrame($old_zcl_frame); 38 | $this->assertEquals($old_zcl_frame, $new->getFrame()); 39 | } 40 | 41 | public function testAllSuccess() 42 | { 43 | Buffer::packInt8u($payload, ZCLStatus::SUCCESS); 44 | $frame = new WriteAttributesResponseCommand($payload); 45 | $this->assertTrue($frame->isSuccess()); 46 | $this->assertEquals("0x00", $frame->displayFrame()); 47 | } 48 | 49 | public function testSetFrame() 50 | { 51 | $frame = new WriteAttributesResponseCommand($this->zcl_str); 52 | 53 | $records = $frame->getWriteAttributeStatusRecords(); 54 | $this->assertEquals(2, count($records)); 55 | 56 | $this->assertEquals($this->zcl_write_attribute_status_record_0, $records[0]); 57 | $this->assertEquals($this->zcl_write_attribute_status_record_1, $records[1]); 58 | } 59 | } -------------------------------------------------------------------------------- /tests/ZCL/IAS_Zone/ZoneStatusChangeNotificationCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(0x5A, $command->getZoneStatus()->getValue()); 15 | } 16 | 17 | public function testStaticConstruct() 18 | { 19 | $command = ZoneStatusChangeNotificationCommand::construct( 20 | new ZoneStatus(0x5A), 0x00 21 | ); 22 | 23 | $this->assertEquals(0x5A, $command->getZoneStatus()->getValue()); 24 | } 25 | 26 | public function testFitInZCLFrame() 27 | { 28 | $bytes = chr(0x5A).chr(0x00).chr(0x00); 29 | 30 | $command = new ZoneStatusChangeNotificationCommand($bytes); 31 | 32 | $zcl_frame = new ZCLFrame(); 33 | $zcl_frame->setPayloadObject($command); 34 | 35 | /** 36 | * @var $output ZoneStatusChangeNotificationCommand 37 | */ 38 | $output = $zcl_frame->getPayloadObject(Cluster::IAS_ZONE); 39 | $this->assertInstanceOf("Munisense\\Zigbee\\ZCL\\IAS_Zone\\ZoneStatusChangeNotificationCommand", $output); 40 | $this->assertEquals($bytes, $output->getFrame()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/ZCL/IAS_Zone/ZoneStatusTest.php: -------------------------------------------------------------------------------- 1 | setValue(0xff); 12 | 13 | $this->assertEquals(ZoneStatus::ALARM_1_OPENED_OR_ALARMED, $status->getAlarm1()); 14 | $this->assertEquals(ZoneStatus::ALARM_2_OPENED_OR_ALARMED, $status->getAlarm2()); 15 | $this->assertEquals(ZoneStatus::TAMPER_TAMPERED, $status->getTamper()); 16 | $this->assertEquals(ZoneStatus::BATTERY_LOW_BATTERY, $status->getBattery()); 17 | $this->assertEquals(ZoneStatus::SUPERVISION_REPORTS_ON, $status->getSupervisionReports()); 18 | $this->assertEquals(ZoneStatus::RESTORE_REPORTS_ON, $status->getRestoreReports()); 19 | $this->assertEquals(ZoneStatus::TROUBLE_FAILURE, $status->getTrouble()); 20 | $this->assertEquals(ZoneStatus::AC_MAINS_FAULT, $status->getACMains()); 21 | 22 | $status->setValue(0x00); 23 | 24 | $this->assertEquals(ZoneStatus::ALARM_1_CLOSED_OR_NOT_ALARMED, $status->getAlarm1()); 25 | $this->assertEquals(ZoneStatus::ALARM_2_CLOSED_OR_NOT_ALARMED, $status->getAlarm2()); 26 | $this->assertEquals(ZoneStatus::TAMPER_NOT_TAMPERED, $status->getTamper()); 27 | $this->assertEquals(ZoneStatus::BATTERY_OK, $status->getBattery()); 28 | $this->assertEquals(ZoneStatus::SUPERVISION_REPORTS_DOES_NOT_REPORT, $status->getSupervisionReports()); 29 | $this->assertEquals(ZoneStatus::RESTORE_REPORTS_DOES_NOT_REPORT_RESTORE, $status->getRestoreReports()); 30 | $this->assertEquals(ZoneStatus::TROUBLE_OK, $status->getTrouble()); 31 | $this->assertEquals(ZoneStatus::AC_MAINS_OK, $status->getACMains()); 32 | } 33 | 34 | public function testStaticConstruct() 35 | { 36 | $status = ZoneStatus::construct( 37 | ZoneStatus::ALARM_1_OPENED_OR_ALARMED, 38 | ZoneStatus::ALARM_2_OPENED_OR_ALARMED, 39 | ZoneStatus::TAMPER_TAMPERED, 40 | ZoneStatus::BATTERY_LOW_BATTERY, 41 | ZoneStatus::SUPERVISION_REPORTS_ON, 42 | ZoneStatus::RESTORE_REPORTS_ON, 43 | ZoneStatus::TROUBLE_FAILURE, 44 | ZoneStatus::AC_MAINS_FAULT 45 | ); 46 | 47 | $this->assertEquals(0xff, $status->getValue()); 48 | } 49 | 50 | public function testSetters() 51 | { 52 | $status = new ZoneStatus(); 53 | $this->assertEquals(0x00, $status->getValue()); 54 | 55 | // First start setting them all 56 | $status->setAlarm1(ZoneStatus::ALARM_1_OPENED_OR_ALARMED); 57 | $this->assertEquals(0x01, $status->getValue()); 58 | 59 | $status->setAlarm2(ZoneStatus::ALARM_2_OPENED_OR_ALARMED); 60 | $this->assertEquals(0x03, $status->getValue()); 61 | 62 | $status->setTamper(ZoneStatus::TAMPER_TAMPERED); 63 | $this->assertEquals(0x07, $status->getValue()); 64 | 65 | $status->setBattery(ZoneStatus::BATTERY_LOW_BATTERY); 66 | $this->assertEquals(0x0F, $status->getValue()); 67 | 68 | $status->setSupervisionReports(ZoneStatus::SUPERVISION_REPORTS_ON); 69 | $this->assertEquals(0x1F, $status->getValue()); 70 | 71 | $status->setRestoreReports(ZoneStatus::RESTORE_REPORTS_ON); 72 | $this->assertEquals(0x3F, $status->getValue()); 73 | 74 | $status->setTrouble(ZoneStatus::TROUBLE_FAILURE); 75 | $this->assertEquals(0x7F, $status->getValue()); 76 | 77 | $status->setACMains(ZoneStatus::AC_MAINS_FAULT); 78 | $this->assertEquals(0xFF, $status->getValue()); 79 | 80 | // Now unset them all 81 | $status->setAlarm1(ZoneStatus::ALARM_1_CLOSED_OR_NOT_ALARMED); 82 | $this->assertEquals(0xFE, $status->getValue()); 83 | 84 | $status->setAlarm2(ZoneStatus::ALARM_2_CLOSED_OR_NOT_ALARMED); 85 | $this->assertEquals(0xFC, $status->getValue()); 86 | 87 | $status->setTamper(ZoneStatus::TAMPER_NOT_TAMPERED); 88 | $this->assertEquals(0xF8, $status->getValue()); 89 | 90 | $status->setBattery(ZoneStatus::BATTERY_OK); 91 | $this->assertEquals(0xF0, $status->getValue()); 92 | 93 | $status->setSupervisionReports(ZoneStatus::SUPERVISION_REPORTS_DOES_NOT_REPORT); 94 | $this->assertEquals(0xE0, $status->getValue()); 95 | 96 | $status->setRestoreReports(ZoneStatus::RESTORE_REPORTS_DOES_NOT_REPORT_RESTORE); 97 | $this->assertEquals(0xC0, $status->getValue()); 98 | 99 | $status->setTrouble(ZoneStatus::TROUBLE_OK); 100 | $this->assertEquals(0x80, $status->getValue()); 101 | 102 | $status->setACMains(ZoneStatus::AC_MAINS_OK); 103 | $this->assertEquals(0x00, $status->getValue()); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /tests/ZCL/ZCLFrameTest.php: -------------------------------------------------------------------------------- 1 | setTransactionId(0x0001); 15 | 16 | $read_attributes_elem = new AttributeIdentifier(); 17 | $read_attributes_elem->setAttributeId(0x02); 18 | 19 | $read_attributes = new ReadAttributesCommand(); 20 | $read_attributes->addAttributeIdentifier($read_attributes_elem); 21 | 22 | $zcl->setPayloadObject($read_attributes); 23 | 24 | $this->assertEquals('0x00 0x01 0x00 0x02 0x00', $zcl->displayFrame()); 25 | } 26 | 27 | public function testReadAttributeStaticConstruct() 28 | { 29 | $zcl = ZCLFrame::construct( 30 | ReadAttributesCommand::construct([ 31 | AttributeIdentifier::construct(0x02) 32 | ]), 33 | 0x4E47, 34 | ZCLFrame::DIRECTION_SERVER_TO_CLIENT, 35 | ZCLFrame::DEFAULT_RESPONSE_ENABLED, 36 | 0x0001 37 | ); 38 | 39 | $this->assertEquals('0x04 0x47 0x4e 0x01 0x00 0x02 0x00', $zcl->displayFrame()); 40 | } 41 | 42 | public function testUpdateFrameType() 43 | { 44 | $zcl = ZCLFrame::construct(); 45 | $zcl->setCommandId(GeneralCommand::CONFIGURE_REPORTING); 46 | $zcl->setFrameType(ZCLFrame::FRAME_TYPE_CLUSTER_SPECIFIC); 47 | 48 | // Set payload changes the FrameType 49 | $zcl->setPayloadObject(ReadAttributesCommand::construct([])); 50 | 51 | $this->assertEquals(ZCLFrame::FRAME_TYPE_PROFILE_WIDE, $zcl->getFrameType()); 52 | $this->assertEquals(GeneralCommand::READ_ATTRIBUTES, $zcl->getCommandId()); 53 | } 54 | 55 | public function testReverse() 56 | { 57 | $old_zcl = ZCLFrame::construct( 58 | ReadAttributesCommand::construct([ 59 | AttributeIdentifier::construct(0x02) 60 | ]), 61 | 0x4E47, 62 | ZCLFrame::DIRECTION_SERVER_TO_CLIENT, 63 | ZCLFrame::DEFAULT_RESPONSE_ENABLED, 64 | 0x0001 65 | ); 66 | 67 | $old_zcl_frame = $old_zcl->getFrame(); 68 | 69 | $new = new ZCLFrame($old_zcl_frame); 70 | 71 | $this->assertEquals($old_zcl_frame, $new->getFrame()); 72 | } 73 | } -------------------------------------------------------------------------------- /tests/ZCL/ZCLStatusTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("UNSUPPORTED_ATTRIBUTE", ZCLStatus::displayStatus(0x86)); 10 | $this->assertEquals("Unknown (0xff)", ZCLStatus::displayStatus(0xFF)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/ActiveEPRspCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x81 0x12 0xab 0x00", $frame->displayFrame()); 18 | } 19 | 20 | public function testStaticConstructSuccess() 21 | { 22 | $frame = ActiveEPRspCommand::constructSuccess(0xab12, [0x00, 0x0a]); 23 | $this->assertEquals("0x00 0x12 0xab 0x02 0x00 0x0a", $frame->displayFrame()); 24 | } 25 | 26 | /** 27 | * @expectedException \Munisense\Zigbee\Exception\ZigbeeException 28 | */ 29 | public function testInvalidEP() 30 | { 31 | $frame = new ActiveEPRspCommand(); 32 | $frame->setActiveEpList([0xff+1]); 33 | } 34 | 35 | public function testInclusionByConstructor() 36 | { 37 | $base_frame = ActiveEPRspCommand::constructSuccess(0xab12, [0x00, 0x0a]); 38 | $transaction_id = chr(0x12); 39 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 40 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\ActiveEPRspCommand", $parent->getPayloadObject()); 41 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 42 | } 43 | 44 | public function testInclusionByStaticConstructor() 45 | { 46 | $base_frame = ActiveEPRspCommand::constructSuccess(0xab12, [0x00, 0x0a]); 47 | $transaction_id = 20; 48 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 49 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\ActiveEPRspCommand", $parent->getPayloadObject()); 50 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/ExtendedSimpleDescReqCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x34 0x12 0xab 0x0a", $frame->displayFrame()); 17 | } 18 | 19 | public function testConstructor() 20 | { 21 | $frame = new ExtendedSimpleDescReqCommand(chr(0x12).chr(0x34).chr(0xab).chr(0x0a)); 22 | $this->assertEquals("0x12 0x34 0xab 0x0a", $frame->displayFrame()); 23 | } 24 | 25 | public function testInclusionByConstructor() 26 | { 27 | $base_frame = ExtendedSimpleDescReqCommand::constructExtended(0x77ae, 0xab, 0x0a); 28 | $transaction_id = chr(0x12); 29 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 30 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\ExtendedSimpleDescReqCommand", $parent->getPayloadObject()); 31 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 32 | } 33 | 34 | public function testInclusionByStaticConstructor() 35 | { 36 | $base_frame = ExtendedSimpleDescReqCommand::constructExtended(0x77ae, 0xab, 0x0a); 37 | $transaction_id = 20; 38 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 39 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\ExtendedSimpleDescReqCommand", $parent->getPayloadObject()); 40 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/ExtendedSimpleDescRspCommandTest.php: -------------------------------------------------------------------------------- 1 | setStatus(Status::DEVICE_NOT_FOUND); 14 | $this->assertEquals(Status::DEVICE_NOT_FOUND, $frame->getStatus()); 15 | } 16 | 17 | /** 18 | * @throws \Munisense\Zigbee\Exception\ZigbeeException 19 | * @expectedException \Munisense\Zigbee\Exception\ZigbeeException 20 | */ 21 | public function testSetStatus_InvalidInput() 22 | { 23 | $frame = new ExtendedSimpleDescRspCommand(); 24 | $frame->setStatus(Status::NO_ENTRY); 25 | } 26 | 27 | public function testConstructFailure() 28 | { 29 | $frame = ExtendedSimpleDescRspCommand::constructFailure(Status::DEVICE_NOT_FOUND, 0x77ae, 0x0a, 0x12, 0xab, 0xef); 30 | $this->assertEquals("0x81 0xae 0x77 0x0a 0x12 0xab 0xef", $frame->displayFrame()); 31 | } 32 | 33 | public function testConstructSuccess() 34 | { 35 | $frame = ExtendedSimpleDescRspCommand::constructSuccess(0x77ae, 0x0a, 0x12, 0xab, 0xef, [0x1234, 0xabcd]); 36 | $base_str = "0x00 0xae 0x77 0x0a 0x12 0xab 0xef"; 37 | $this->assertEquals($base_str." 0x34 0x12 0xcd 0xab", $frame->displayFrame()); 38 | } 39 | 40 | public function testSetFrameFailure() 41 | { 42 | $base_frame = ExtendedSimpleDescRspCommand::constructFailure(Status::DEVICE_NOT_FOUND, 0x77ae, 0x0a, 0x12, 0xab, 0xef); 43 | $frame = new ExtendedSimpleDescRspCommand($base_frame->getFrame()); 44 | $this->assertEquals($base_frame->displayFrame(), $frame->displayFrame()); 45 | } 46 | 47 | public function testSetFrameSuccess() 48 | { 49 | $base_frame = ExtendedSimpleDescRspCommand::constructSuccess(0x77ae, 0x0a, 0x12, 0xab, 0xef, [0x1234, 0xabcd]); 50 | $frame = new ExtendedSimpleDescRspCommand($base_frame->getFrame()); 51 | $this->assertEquals($base_frame->displayFrame(), $frame->displayFrame()); 52 | } 53 | 54 | /** 55 | * @expectedException \Munisense\Zigbee\Exception\ZigbeeException 56 | */ 57 | public function testAddInvalidCluster() 58 | { 59 | $frame = new ExtendedSimpleDescRspCommand(); 60 | $frame->setAppClusterList([0xff00, 0xffff+1]); 61 | } 62 | 63 | public function testInclusionByConstructor() 64 | { 65 | $base_frame = ExtendedSimpleDescRspCommand::constructSuccess(0x77ae, 0x0a, 0x12, 0xab, 0xef, [0x1234, 0xabcd]); 66 | $transaction_id = chr(0x12); 67 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 68 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\ExtendedSimpleDescRspCommand", $parent->getPayloadObject()); 69 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 70 | } 71 | 72 | public function testInclusionByStaticConstructor() 73 | { 74 | $base_frame = ExtendedSimpleDescRspCommand::constructSuccess(0x77ae, 0x0a, 0x12, 0xab, 0xef, [0x1234, 0xabcd]); 75 | $transaction_id = 20; 76 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 77 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\ExtendedSimpleDescRspCommand", $parent->getPayloadObject()); 78 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/IEEEAddrReqCommandTest.php: -------------------------------------------------------------------------------- 1 | setNwkAddress(0xffffff); 17 | } 18 | 19 | public function testGetFrameSimple() 20 | { 21 | $frame = IEEEAddrReqCommand::constructSingle(0x1234); 22 | $this->assertEquals("0x34 0x12 0x00 0x00", $frame->displayFrame()); 23 | } 24 | 25 | public function testGetFrameExtended() 26 | { 27 | $frame = IEEEAddrReqCommand::constructExtended(0x1234, 0x01); 28 | $this->assertEquals("0x34 0x12 0x01 0x01", $frame->displayFrame()); 29 | } 30 | 31 | public function testSetFrameSimple() 32 | { 33 | $base_frame = IEEEAddrReqCommand::constructSingle(0x1234); 34 | $frame = new IEEEAddrReqCommand($base_frame->getFrame()); 35 | $this->assertEquals($base_frame->displayFrame(), $frame->displayFrame()); 36 | } 37 | 38 | public function testSetFrameExtended() 39 | { 40 | $base_frame = IEEEAddrReqCommand::constructExtended(0x1234, 0x01); 41 | $frame = new IEEEAddrReqCommand($base_frame->getFrame()); 42 | $this->assertEquals($base_frame->displayFrame(), $frame->displayFrame()); 43 | } 44 | 45 | public function testInclusionByConstructor() 46 | { 47 | $base_frame = IEEEAddrReqCommand::constructExtended(0x1234, 0x01); 48 | $transaction_id = chr(0x12); 49 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 50 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\IEEEAddrReqCommand", $parent->getPayloadObject()); 51 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 52 | } 53 | 54 | public function testInclusionByStaticConstructor() 55 | { 56 | $base_frame = IEEEAddrReqCommand::constructExtended(0x1234, 0x01); 57 | $transaction_id = 20; 58 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 59 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\IEEEAddrReqCommand", $parent->getPayloadObject()); 60 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/IEEEAddrRspCommandTest.php: -------------------------------------------------------------------------------- 1 | getFrame(), $base_frame->getClusterId()); 21 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\IEEEAddrRspCommand", $parent->getPayloadObject()); 22 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 23 | } 24 | 25 | public function testInclusionByStaticConstructor() 26 | { 27 | $base_frame = IEEEAddrRspCommand::constructExtended(Status::SUCCESS, 123456, 0x77ae, 0x01, [0x1234, 0xabcd]); 28 | $transaction_id = 20; 29 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 30 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\IEEEAddrRspCommand", $parent->getPayloadObject()); 31 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/NodeDescReqCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x34 0x12", $frame->displayFrame()); 17 | } 18 | 19 | public function testConstructor() 20 | { 21 | $frame = new NodeDescReqCommand(chr(0x12).chr(0x34)); 22 | $this->assertEquals("0x12 0x34", $frame->displayFrame()); 23 | } 24 | 25 | public function testInclusionByConstructor() 26 | { 27 | $base_frame = NodeDescReqCommand::construct(0x77ae); 28 | $transaction_id = chr(0x12); 29 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 30 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\NodeDescReqCommand", $parent->getPayloadObject()); 31 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 32 | } 33 | 34 | public function testInclusionByStaticConstructor() 35 | { 36 | $base_frame = NodeDescReqCommand::construct(0x77ae); 37 | $transaction_id = 20; 38 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 39 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\NodeDescReqCommand", $parent->getPayloadObject()); 40 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/NodeDescRspCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x81 0x12 0xab 0x00", $frame->displayFrame()); 15 | } 16 | 17 | public function testStaticConstructSuccess() 18 | { 19 | $node_descriptor = new NodeDescriptor(); 20 | $frame = NodeDescRspCommand::constructSuccess(0xab12, $node_descriptor); 21 | $node_descriptor_frame_length = sprintf("0x%02x", strlen($node_descriptor->getFrame())); 22 | $this->assertEquals(trim("0x00 0x12 0xab ".$node_descriptor_frame_length." ".$node_descriptor->displayFrame()), $frame->displayFrame()); 23 | } 24 | 25 | public function testInclusionByConstructor() 26 | { 27 | $base_frame = NodeDescRspCommand::constructFailure(Status::DEVICE_NOT_FOUND, 0xab12); 28 | $transaction_id = chr(0x12); 29 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 30 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\NodeDescRspCommand", $parent->getPayloadObject()); 31 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 32 | } 33 | 34 | public function testInclusionByStaticConstructor() 35 | { 36 | $base_frame = NodeDescRspCommand::constructFailure(Status::DEVICE_NOT_FOUND, 0xab12); 37 | $transaction_id = 20; 38 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 39 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\NodeDescRspCommand", $parent->getPayloadObject()); 40 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/NodeDescriptorTest.php: -------------------------------------------------------------------------------- 1 | getFrame(); 15 | $new_descriptor = new NodeDescriptor($frame); 16 | 17 | $this->assertEquals($node_descriptor->getFrame(), $new_descriptor->getFrame()); 18 | } 19 | 20 | /** 21 | * @expectedException \Munisense\Zigbee\Exception\ZigbeeException 22 | */ 23 | public function testSetMaximumOutgoingTransferSize__Invalid() 24 | { 25 | $node_descriptor = new NodeDescriptor(); 26 | $node_descriptor->setMaximumOutgoingTransferSize(0x7fff + 1); 27 | } 28 | 29 | public function testSetMaximumOutgoingTransferSize() 30 | { 31 | $valid_elems = [0, 0xff, 0x7fff]; 32 | $node_descriptor = new NodeDescriptor(); 33 | 34 | foreach($valid_elems as $elem) 35 | $node_descriptor->setMaximumOutgoingTransferSize($elem); 36 | } 37 | 38 | /** 39 | * @expectedException \Munisense\Zigbee\Exception\ZigbeeException 40 | */ 41 | public function testSetMaximumIncomingTransferSize__Invalid() 42 | { 43 | $node_descriptor = new NodeDescriptor(); 44 | $node_descriptor->setMaximumIncomingTransferSize(0x7fff + 1); 45 | } 46 | 47 | public function testSetMaximumIncomingTransferSize() 48 | { 49 | $valid_elems = [0, 0xff, 0x7fff]; 50 | $node_descriptor = new NodeDescriptor(); 51 | 52 | foreach($valid_elems as $elem) 53 | $node_descriptor->setMaximumIncomingTransferSize($elem); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/NodePowerDescriptorTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x52 0x44", $power_desc->displayFrame()); 13 | } 14 | 15 | public function testReverse() 16 | { 17 | $power_desc = NodePowerDescriptor::construct(NodePowerDescriptor::MODE_RECEIVER_STIMULATED, NodePowerDescriptor::SOURCE_DISPOSABLE_BATTERY ^ NodePowerDescriptor::SOURCE_CONSTANT_MAINS_POWER, 18 | NodePowerDescriptor::SOURCE_DISPOSABLE_BATTERY, NodePowerDescriptor::LEVEL_33PERC 19 | ); 20 | 21 | $frame = $power_desc->getFrame(); 22 | $new_descriptor = new NodePowerDescriptor($frame); 23 | 24 | $this->assertEquals($power_desc->getFrame(), $new_descriptor->getFrame()); 25 | } 26 | 27 | public function testDisplayPowerSource() 28 | { 29 | $power_desc = new NodePowerDescriptor(); 30 | $this->assertEquals("RECHARGEABLE_BATTERY", $power_desc->displayPowerSource(NodePowerDescriptor::SOURCE_RECHARGEABLE_BATTERY)); 31 | $this->assertEquals("RECHARGEABLE_BATTERY, CONSTANT_MAINS_POWER", $power_desc->displayPowerSource(NodePowerDescriptor::SOURCE_CONSTANT_MAINS_POWER ^ NodePowerDescriptor::SOURCE_RECHARGEABLE_BATTERY)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/NwkAddrReqCommandTest.php: -------------------------------------------------------------------------------- 1 | setIeeeAddress(0xffffffffffffffffff); 17 | } 18 | 19 | public function testGetFrameSimple() 20 | { 21 | $frame = NwkAddrReqCommand::constructSingle(0xff); 22 | $this->assertEquals("0xff 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00", $frame->displayFrame()); 23 | } 24 | 25 | public function testGetFrameExtended() 26 | { 27 | $frame = NwkAddrReqCommand::constructExtended(0xff, 0x01); 28 | $this->assertEquals("0xff 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x01", $frame->displayFrame()); 29 | } 30 | 31 | public function testSetFrameSimple() 32 | { 33 | $base_frame = NwkAddrReqCommand::constructSingle(0xff); 34 | $frame = new NwkAddrReqCommand($base_frame->getFrame()); 35 | $this->assertEquals($base_frame->displayFrame(), $frame->displayFrame()); 36 | } 37 | 38 | public function testSetFrameExtended() 39 | { 40 | $base_frame = NwkAddrReqCommand::constructExtended(0xff, 0x01); 41 | $frame = new NwkAddrReqCommand($base_frame->getFrame()); 42 | $this->assertEquals($base_frame->displayFrame(), $frame->displayFrame()); 43 | } 44 | 45 | public function testInclusionByConstructor() 46 | { 47 | $base_frame = NwkAddrReqCommand::constructExtended(0xff, 0x01); 48 | $transaction_id = chr(0x12); 49 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 50 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\NwkAddrReqCommand", $parent->getPayloadObject()); 51 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 52 | } 53 | 54 | public function testInclusionByStaticConstructor() 55 | { 56 | $base_frame = NwkAddrReqCommand::constructExtended(0xff, 0x01); 57 | $transaction_id = 20; 58 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 59 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\NwkAddrReqCommand", $parent->getPayloadObject()); 60 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/NwkAddrRspCommandTest.php: -------------------------------------------------------------------------------- 1 | setStatus(Status::DEVICE_NOT_FOUND); 14 | $this->assertEquals(Status::DEVICE_NOT_FOUND, $frame->getStatus()); 15 | } 16 | 17 | /** 18 | * @throws \Munisense\Zigbee\Exception\ZigbeeException 19 | * @expectedException \Munisense\Zigbee\Exception\ZigbeeException 20 | */ 21 | public function testSetStatus_InvalidInput() 22 | { 23 | $frame = new NwkAddrRspCommand(); 24 | $frame->setStatus(Status::NO_ENTRY); 25 | } 26 | 27 | /** 28 | * If the RequestType in the request is Extended Response and there are no associated devices on the 29 | * Remote Device, this field shall be set to 0. 30 | * 31 | * If an error occurs or the RequestType in the request is for a Single 32 | * Device Response, this field shall not be included in the frame. 33 | */ 34 | public function testGetFrameEmptyList() 35 | { 36 | $frame = NwkAddrRspCommand::constructSingle(Status::SUCCESS, 123456, 0x77ae); 37 | $base_str = "0x00 0x40 0xe2 0x01 0x00 0x00 0x00 0x00 0x00 0xae 0x77"; 38 | $this->assertEquals($base_str, $frame->displayFrame()); 39 | 40 | // Num associated devices as 0x00 and omit the rest 41 | $frame = NwkAddrRspCommand::constructExtended(Status::SUCCESS, 123456, 0x77ae, 0x01, []); 42 | $this->assertEquals($base_str." 0x00", $frame->displayFrame()); 43 | } 44 | 45 | public function testGetFrameExtended() 46 | { 47 | $frame = NwkAddrRspCommand::constructExtended(Status::SUCCESS, 123456, 0x77ae, 0x01, [0x1234, 0xabcd]); 48 | $base_str = "0x00 0x40 0xe2 0x01 0x00 0x00 0x00 0x00 0x00 0xae 0x77"; 49 | $this->assertEquals($base_str." 0x02 0x01 0x34 0x12 0xcd 0xab", $frame->displayFrame()); 50 | } 51 | 52 | public function testSetFrameSimple() 53 | { 54 | $base_frame = NwkAddrRspCommand::constructSingle(Status::SUCCESS, 123456, 0x77ae); 55 | $frame = new NwkAddrRspCommand($base_frame->getFrame()); 56 | $this->assertEquals($base_frame->displayFrame(), $frame->displayFrame()); 57 | } 58 | 59 | public function testSetFrameExtended() 60 | { 61 | $base_frame = NwkAddrRspCommand::constructExtended(Status::SUCCESS, 123456, 0x77ae, 0x01, [0x1234, 0xabcd]); 62 | $frame = new NwkAddrRspCommand($base_frame->getFrame()); 63 | $this->assertEquals($base_frame->displayFrame(), $frame->displayFrame()); 64 | } 65 | 66 | /** 67 | * @expectedException \Munisense\Zigbee\Exception\ZigbeeException 68 | */ 69 | public function testAddInvalidAssociatedDevice() 70 | { 71 | $frame = new NwkAddrRspCommand(); 72 | $frame->setAssociatedDeviceList([0xff00, 0xffff+1]); 73 | } 74 | 75 | public function testInclusionByConstructor() 76 | { 77 | $base_frame = NwkAddrRspCommand::constructExtended(Status::SUCCESS, 123456, 0x77ae, 0x01, [0x1234, 0xabcd]); 78 | $transaction_id = chr(0x12); 79 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 80 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\NwkAddrRspCommand", $parent->getPayloadObject()); 81 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 82 | } 83 | 84 | public function testInclusionByStaticConstructor() 85 | { 86 | $base_frame = NwkAddrRspCommand::constructExtended(Status::SUCCESS, 123456, 0x77ae, 0x01, [0x1234, 0xabcd]); 87 | $transaction_id = 20; 88 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 89 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\NwkAddrRspCommand", $parent->getPayloadObject()); 90 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/PowerDescRspCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x81 0x12 0xab", $frame->displayFrame()); 18 | } 19 | 20 | public function testStaticConstructSuccess() 21 | { 22 | $power_descriptor = new NodePowerDescriptor(); 23 | $frame = PowerDescRspCommand::constructSuccess(0xab12, $power_descriptor); 24 | $this->assertEquals(trim("0x00 0x12 0xab ".$power_descriptor->displayFrame()), $frame->displayFrame()); 25 | } 26 | 27 | public function testInclusionByConstructor() 28 | { 29 | $base_frame = PowerDescRspCommand::constructFailure(Status::DEVICE_NOT_FOUND, 0xab12); 30 | $transaction_id = chr(0x12); 31 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 32 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\PowerDescRspCommand", $parent->getPayloadObject()); 33 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 34 | } 35 | 36 | public function testInclusionByStaticConstructor() 37 | { 38 | $base_frame = PowerDescRspCommand::constructFailure(Status::DEVICE_NOT_FOUND, 0xab12); 39 | $transaction_id = 20; 40 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 41 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\PowerDescRspCommand", $parent->getPayloadObject()); 42 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/SimpleDescReqCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x34 0x12 0xab", $frame->displayFrame()); 17 | } 18 | 19 | public function testConstructor() 20 | { 21 | $frame = new SimpleDescReqCommand(chr(0x12).chr(0x34).chr(0xab)); 22 | $this->assertEquals("0x12 0x34 0xab", $frame->displayFrame()); 23 | } 24 | 25 | public function testInclusionByConstructor() 26 | { 27 | $base_frame = SimpleDescReqCommand::construct(0x77ae, 0xab); 28 | $transaction_id = chr(0x12); 29 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 30 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\SimpleDescReqCommand", $parent->getPayloadObject()); 31 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 32 | } 33 | 34 | public function testInclusionByStaticConstructor() 35 | { 36 | $base_frame = SimpleDescReqCommand::construct(0x77ae, 0xab); 37 | $transaction_id = 20; 38 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 39 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\SimpleDescReqCommand", $parent->getPayloadObject()); 40 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/SimpleDescRspCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x81 0x12 0xab 0x00", $frame->displayFrame()); 18 | } 19 | 20 | public function testStaticConstructSuccess() 21 | { 22 | $frame = SimpleDescRspCommand::constructSuccess(0xab12, SimpleDescriptor::construct(0x0a, 0x1234, 0xabcd, 8)); 23 | $this->assertEquals("0x00 0x12 0xab 0x08 0x0a 0x34 0x12 0xcd 0xab 0x08 0x00 0x00", $frame->displayFrame()); 24 | } 25 | 26 | public function testReverse() 27 | { 28 | $simple_desc = SimpleDescRspCommand::constructSuccess(0xab12, SimpleDescriptor::construct(0x0a, 0x1234, 0xabcd, 8)); 29 | $frame = $simple_desc->getFrame(); 30 | $new_descriptor = new SimpleDescRspCommand($frame); 31 | $this->assertEquals($simple_desc->displayFrame(), $new_descriptor->displayFrame()); 32 | } 33 | 34 | public function testInclusionByConstructor() 35 | { 36 | $base_frame = SimpleDescRspCommand::constructFailure(Status::DEVICE_NOT_FOUND, 0xab12); 37 | $transaction_id = chr(0x12); 38 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 39 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\SimpleDescRspCommand", $parent->getPayloadObject()); 40 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 41 | } 42 | 43 | public function testInclusionByStaticConstructor() 44 | { 45 | $base_frame = SimpleDescRspCommand::constructFailure(Status::DEVICE_NOT_FOUND, 0xab12); 46 | $transaction_id = 20; 47 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 48 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\SimpleDescRspCommand", $parent->getPayloadObject()); 49 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/SimpleDescriptorTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x0a 0x34 0x12 0xcd 0xab 0x0a 0x01 0x57 0x13 0x02 0x11 0x00 0x22 0x00", $simple_desc->displayFrame()); 13 | } 14 | 15 | public function testSetFrame() 16 | { 17 | $base_frame = SimpleDescriptor::construct(0x0a, 0x1234, 0xabcd, 0b00001010, [0x1357], [0x0011,0x0022]); 18 | $frame = new SimpleDescriptor($base_frame->getFrame()); 19 | $this->assertEquals($base_frame->displayFrame(), $frame->displayFrame()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/UserDescConfCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x81 0x12 0xab", $frame->displayFrame()); 18 | } 19 | 20 | public function testReverse() 21 | { 22 | $user_desc = UserDescConfCommand::construct(Status::SUCCESS, 0xab12); 23 | $frame = $user_desc->getFrame(); 24 | $new_descriptor = new UserDescConfCommand($frame); 25 | $this->assertEquals($user_desc->displayFrame(), $new_descriptor->displayFrame()); 26 | } 27 | 28 | public function testInclusionByConstructor() 29 | { 30 | $base_frame = UserDescConfCommand::construct(Status::SUCCESS, 0xab12); 31 | $transaction_id = chr(0x12); 32 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 33 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\UserDescConfCommand", $parent->getPayloadObject()); 34 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 35 | } 36 | 37 | public function testInclusionByStaticConstructor() 38 | { 39 | $base_frame = UserDescConfCommand::construct(Status::SUCCESS, 0xab12); 40 | $transaction_id = 20; 41 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 42 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\UserDescConfCommand", $parent->getPayloadObject()); 43 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/UserDescRspCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x81 0x12 0xab 0x00", $frame->displayFrame()); 18 | } 19 | 20 | public function testStaticConstructSuccess() 21 | { 22 | $frame = UserDescRspCommand::constructSuccess(0xab12, UserDescriptor::construct("test")); 23 | $this->assertEquals("0x00 0x12 0xab 0x04 0x74 0x65 0x73 0x74", $frame->displayFrame()); 24 | } 25 | 26 | public function testReverse() 27 | { 28 | $user_desc = UserDescRspCommand::constructSuccess(0xab12, UserDescriptor::construct("hello")); 29 | $frame = $user_desc->getFrame(); 30 | $new_descriptor = new UserDescRspCommand($frame); 31 | $this->assertEquals($user_desc->displayFrame(), $new_descriptor->displayFrame()); 32 | } 33 | 34 | public function testInclusionByConstructor() 35 | { 36 | $base_frame = UserDescRspCommand::constructFailure(Status::DEVICE_NOT_FOUND, 0xab12); 37 | $transaction_id = chr(0x12); 38 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 39 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\UserDescRspCommand", $parent->getPayloadObject()); 40 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 41 | } 42 | 43 | public function testInclusionByStaticConstructor() 44 | { 45 | $base_frame = UserDescRspCommand::constructFailure(Status::DEVICE_NOT_FOUND, 0xab12); 46 | $transaction_id = 20; 47 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 48 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\UserDescRspCommand", $parent->getPayloadObject()); 49 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/ZDP/Discovery/UserDescSetCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x12 0xab 0x04 0x74 0x65 0x73 0x74", $frame->displayFrame()); 17 | } 18 | 19 | public function testReverse() 20 | { 21 | $user_desc = UserDescSetCommand::construct(0xab12, UserDescriptor::construct("hello")); 22 | $frame = $user_desc->getFrame(); 23 | $new_descriptor = new UserDescSetCommand($frame); 24 | $this->assertEquals($user_desc->displayFrame(), $new_descriptor->displayFrame()); 25 | } 26 | 27 | public function testInclusionByConstructor() 28 | { 29 | $base_frame = UserDescSetCommand::construct(0xab12, UserDescriptor::construct("hello")); 30 | $transaction_id = chr(0x12); 31 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 32 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\UserDescSetCommand", $parent->getPayloadObject()); 33 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 34 | } 35 | 36 | public function testInclusionByStaticConstructor() 37 | { 38 | $base_frame = UserDescSetCommand::construct(0xab12, UserDescriptor::construct("hello")); 39 | $transaction_id = 20; 40 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 41 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\UserDescSetCommand", $parent->getPayloadObject()); 42 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 43 | } 44 | } -------------------------------------------------------------------------------- /tests/ZDP/Discovery/UserDescriptorTest.php: -------------------------------------------------------------------------------- 1 | getFrame(); 11 | 12 | $new_user_desc = new UserDescriptor($frame); 13 | $this->assertEquals($user_desc->displayFrame(), $new_user_desc->displayFrame()); 14 | } 15 | 16 | /** 17 | * @expectedException \Munisense\Zigbee\Exception\ZigbeeException 18 | */ 19 | public function testLengthException() 20 | { 21 | UserDescriptor::construct("this is a test with a way too long name so it will throw an error"); 22 | } 23 | 24 | public function testFrameLength() 25 | { 26 | $str = "short"; 27 | $user_desc = UserDescriptor::construct($str); 28 | $this->assertEquals(strlen($str), strlen($user_desc->getFrame())); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/ZDP/Network/MgmtBindReqCommandTest.php: -------------------------------------------------------------------------------- 1 | getFrame(), $base_frame->getClusterId()); 18 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Network\\MgmtBindReqCommand", $parent->getPayloadObject()); 19 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 20 | } 21 | 22 | public function testInclusionByStaticConstructor() 23 | { 24 | $base_frame = MgmtBindReqCommand::construct(0xa1); 25 | $transaction_id = 20; 26 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 27 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Network\\MgmtBindReqCommand", $parent->getPayloadObject()); 28 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/ZDP/Network/MgmtCacheReqCommandTest.php: -------------------------------------------------------------------------------- 1 | getFrame(), $base_frame->getClusterId()); 18 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Network\\MgmtCacheReqCommand", $parent->getPayloadObject()); 19 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 20 | } 21 | 22 | public function testInclusionByStaticConstructor() 23 | { 24 | $base_frame = MgmtCacheReqCommand::construct(0xa1); 25 | $transaction_id = 20; 26 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 27 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Network\\MgmtCacheReqCommand", $parent->getPayloadObject()); 28 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/ZDP/Network/MgmtLqiReqCommandTest.php: -------------------------------------------------------------------------------- 1 | getFrame(), $base_frame->getClusterId()); 18 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Network\\MgmtLqiReqCommand", $parent->getPayloadObject()); 19 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 20 | } 21 | 22 | public function testInclusionByStaticConstructor() 23 | { 24 | $base_frame = MgmtLqiReqCommand::construct(0xa1); 25 | $transaction_id = 20; 26 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 27 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Network\\MgmtLqiReqCommand", $parent->getPayloadObject()); 28 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/ZDP/Network/MgmtLqiRspCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x00 0x0a 0x12 0x02 ".$neighbor_descriptor_1->displayFrame()." ".$neighbor_descriptor_2->displayFrame(), $frame->displayFrame()); 31 | } 32 | 33 | public function testConstructFailure() 34 | { 35 | $frame = MgmtLqiRspCommand::constructFailure(Status::NO_DESCRIPTOR); 36 | $this->assertEquals("0x89", $frame->displayFrame()); 37 | } 38 | 39 | 40 | public function testInclusionByConstructor() 41 | { 42 | $base_frame = MgmtLqiRspCommand::constructSuccess(80, 10, [ 43 | NeighborDescriptor::construct( 44 | "3781220488658316", "3781220489559882", Status::SUCCESS, NeighborDescriptor::ZIGBEE_END_DEVICE, NeighborDescriptor::RECEIVER_ON_WHEN_IDLE, 45 | NeighborDescriptor::RELATION_NEIGHBOR_IS_SIBLING, NeighborDescriptor::NEIGHBOR_ACCEPTS_JOIN_REQUESTS_UNKNOWN, 0x0f, 0xf0 46 | ), 47 | NeighborDescriptor::construct( 48 | "1231534523", "131412415445", Status::SUCCESS, NeighborDescriptor::ZIGBEE_COORDINATOR, NeighborDescriptor::RECEIVER_OFF_WHEN_IDLE, 49 | NeighborDescriptor::RELATION_NEIGHBOR_IS_CHILD, NeighborDescriptor::NEIGHBOR_IS_ACCEPTING_JOIN_REQUESTS, 0x1f, 0xf2 50 | ) 51 | ]); 52 | 53 | $transaction_id = chr(0x12); 54 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 55 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Network\\MgmtLqiRspCommand", $parent->getPayloadObject()); 56 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 57 | } 58 | 59 | public function testInclusionByStaticConstructor() 60 | { 61 | $base_frame = MgmtLqiRspCommand::constructSuccess(80, 10, [ 62 | NeighborDescriptor::construct( 63 | "3781220488658316", "3781220489559882", Status::SUCCESS, NeighborDescriptor::ZIGBEE_END_DEVICE, NeighborDescriptor::RECEIVER_ON_WHEN_IDLE, 64 | NeighborDescriptor::RELATION_NEIGHBOR_IS_SIBLING, NeighborDescriptor::NEIGHBOR_ACCEPTS_JOIN_REQUESTS_UNKNOWN, 0x0f, 0xf0 65 | ), 66 | NeighborDescriptor::construct( 67 | "1231534523", "131412415445", Status::SUCCESS, NeighborDescriptor::ZIGBEE_COORDINATOR, NeighborDescriptor::RECEIVER_OFF_WHEN_IDLE, 68 | NeighborDescriptor::RELATION_NEIGHBOR_IS_CHILD, NeighborDescriptor::NEIGHBOR_IS_ACCEPTING_JOIN_REQUESTS, 0x1f, 0xf2 69 | ) 70 | ]); 71 | 72 | $transaction_id = 20; 73 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 74 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Network\\MgmtLqiRspCommand", $parent->getPayloadObject()); 75 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/ZDP/Network/MgmtRtgReqCommandTest.php: -------------------------------------------------------------------------------- 1 | getFrame(), $base_frame->getClusterId()); 18 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Network\\MgmtRtgReqCommand", $parent->getPayloadObject()); 19 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 20 | } 21 | 22 | public function testInclusionByStaticConstructor() 23 | { 24 | $base_frame = MgmtRtgReqCommand::construct(0xa1); 25 | $transaction_id = 20; 26 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 27 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Network\\MgmtRtgReqCommand", $parent->getPayloadObject()); 28 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/ZDP/Network/MgmtRtgRspCommandTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x00 0x0a 0x12 0x02 ".$routing_descriptor_1->displayFrame()." ".$routing_descriptor_2->displayFrame(), $frame->displayFrame()); 25 | } 26 | 27 | public function testConstructFailure() 28 | { 29 | $frame = MgmtRtgRspCommand::constructFailure(Status::NO_DESCRIPTOR); 30 | $this->assertEquals("0x89", $frame->displayFrame()); 31 | } 32 | 33 | 34 | public function testInclusionByConstructor() 35 | { 36 | $base_frame = MgmtRtgRspCommand::constructSuccess(80, 10, [ 37 | RoutingDescriptor::construct(0x1234, RoutingDescriptor::VALIDATION_UNDERWAY, 1, 0, 1, 0xabcd), 38 | RoutingDescriptor::construct(0x2347, RoutingDescriptor::ACTIVE, 1, 1, 0, 0xabcd) 39 | ]); 40 | 41 | $transaction_id = chr(0x12); 42 | $parent = new ZDPFrame($transaction_id .$base_frame->getFrame(), $base_frame->getClusterId()); 43 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Network\\MgmtRtgRspCommand", $parent->getPayloadObject()); 44 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 45 | } 46 | 47 | public function testInclusionByStaticConstructor() 48 | { 49 | $base_frame = MgmtRtgRspCommand::constructSuccess(80, 10, [ 50 | RoutingDescriptor::construct(0x1234, RoutingDescriptor::VALIDATION_UNDERWAY, 1, 0, 1, 0xabcd), 51 | RoutingDescriptor::construct(0x2347, RoutingDescriptor::ACTIVE, 1, 1, 0, 0xabcd) 52 | ]); 53 | 54 | $transaction_id = 20; 55 | $parent = ZDPFrame::construct($base_frame, $transaction_id); 56 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Network\\MgmtRtgRspCommand", $parent->getPayloadObject()); 57 | $this->assertEquals($base_frame->displayFrame(), $parent->displayPayload()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/ZDP/Network/NeighborDescriptorTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x8c 0x3d 0x0b 0x00 0x00 0x6f 0x0d 0x00 0x4a 0xff 0x18 0x00 0x00 0x6f 0x0d 0x00 0x0a 0x00 0x46 0x02 0x0f 0xf0", $neighbor_descriptor->displayFrame()); 15 | } 16 | 17 | public function testReverse() 18 | { 19 | $neighbor_descriptor = NeighborDescriptor::construct( 20 | "3781220488658316", "3781220489559882", 0x0a, NeighborDescriptor::ZIGBEE_END_DEVICE, NeighborDescriptor::RECEIVER_ON_WHEN_IDLE, 21 | NeighborDescriptor::RELATION_NEIGHBOR_IS_SIBLING, NeighborDescriptor::NEIGHBOR_ACCEPTS_JOIN_REQUESTS_UNKNOWN, 0x0f, 0xf0 22 | ); 23 | 24 | $frame = $neighbor_descriptor->getFrame(); 25 | $new_descriptor = new NeighborDescriptor($frame); 26 | 27 | $this->assertEquals($neighbor_descriptor->displayFrame(), $new_descriptor->displayFrame()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/ZDP/Network/RoutingDescriptorTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x34 0x12 0x2c 0xcd 0xab", $routing_descriptor->displayFrame()); 11 | } 12 | 13 | public function testReverse() 14 | { 15 | $routing_descriptor = RoutingDescriptor::construct(0x1234, RoutingDescriptor::DISCOVERY_FAILED, 0, 1, 0, 0xabcd); 16 | $frame = $routing_descriptor->getFrame(); 17 | $new_descriptor = new RoutingDescriptor($frame); 18 | 19 | $this->assertEquals($routing_descriptor->displayFrame(), $new_descriptor->displayFrame()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/ZDP/ZDPFrameTest.php: -------------------------------------------------------------------------------- 1 | assertEquals("0x00", $frame->displayFrame()); 17 | } 18 | 19 | public function testFindClassByCluster() 20 | { 21 | $this->assertEquals("Munisense\\Zigbee\\ZDP\\Discovery\\IEEEAddrRspCommand", ZDPFrame::findClassByCluster(0x8001)); 22 | } 23 | 24 | public function testCommandInclusion() 25 | { 26 | $command = NwkAddrReqCommand::constructSingle(0xbeef); 27 | $frame = ZDPFrame::construct($command, 0x12); 28 | 29 | $this->assertEquals($command->getClusterId(), $frame->getCommandId()); 30 | $this->assertEquals("0x12 0xef 0xbe 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00", $frame->displayFrame()); 31 | } 32 | 33 | public function testGetPayloadObject() 34 | { 35 | $command = NwkAddrReqCommand::constructSingle(0xbeef); 36 | $frame = ZDPFrame::construct($command, 0x12); 37 | $this->assertInstanceOf("Munisense\\Zigbee\\ZDP\\Discovery\\NwkAddrReqCommand", $frame->getPayloadObject()); 38 | } 39 | } --------------------------------------------------------------------------------