Completed
Push — master ( eb7347...5263c9 )
by Chris
02:58 queued 12s
created

MessageEncoder::encodeStateLightPower()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace DaveRandom\LibLifxLan\Encoding;
4
5
use DaveRandom\LibLifxLan\DataTypes as DeviceDataTypes;
6
use DaveRandom\LibLifxLan\DataTypes\Light as LightDataTypes;
7
use DaveRandom\LibLifxLan\Messages\Device\Commands as DeviceCommands;
8
use DaveRandom\LibLifxLan\Messages\Device\Requests as DeviceRequests;
9
use DaveRandom\LibLifxLan\Messages\Device\Responses as DeviceResponses;
10
use DaveRandom\LibLifxLan\Messages\Light\Commands as LightCommands;
11
use DaveRandom\LibLifxLan\Messages\Light\Responses as LightResponses;
12
use DaveRandom\LibLifxLan\Messages\Message;
13
use DaveRandom\LibLifxLan\Messages\UnknownMessage;
14
use const DaveRandom\LibLifxLan\FLOAT32_CODE;
15
use function DaveRandom\LibLifxLan\datetimeinterface_to_nanotime;
16
use function DaveRandom\LibLifxLan\int16_to_uint16;
17
18
final class MessageEncoder
19
{
20
    /**
21
     * @uses encodeUnknownMessage
22
     * @uses encodeEchoRequest
23
     * @uses encodeEchoResponse
24
     * @uses encodeSetGroup
25
     * @uses encodeStateGroup
26
     * @uses encodeStateHostFirmware
27
     * @uses encodeStateHostInfo
28
     * @uses encodeStateInfo
29
     * @uses encodeSetLabel
30
     * @uses encodeStateLabel
31
     * @uses encodeSetLocation
32
     * @uses encodeStateLocation
33
     * @uses encodeSetDevicePower
34
     * @uses encodeStateDevicePower
35
     * @uses encodeStateService
36
     * @uses encodeStateVersion
37
     * @uses encodeStateWifiFirmware
38
     * @uses encodeStateWifiInfo
39
     * @uses encodeSetColor
40
     * @uses encodeSetWaveform
41
     * @uses encodeSetWaveformOptional
42
     * @uses encodeState
43
     * @uses encodeSetInfrared
44
     * @uses encodeStateInfrared
45
     * @uses encodeSetLightPower
46
     * @uses encodeStateLightPower
47
     */
48
    private const ENCODING_ROUTINES = [
49
        UnknownMessage::class => 'UnknownMessage',
50
51
        // Device command messages
52
        DeviceCommands\SetGroup::class => 'SetGroup',
53
        DeviceCommands\SetLabel::class => 'SetLabel',
54
        DeviceCommands\SetLocation::class => 'SetLocation',
55
        DeviceCommands\SetPower::class => 'SetDevicePower',
56
57
        // Device request messages
58
        DeviceRequests\EchoRequest::class => 'EchoRequest',
59
60
        // Device response messages
61
        DeviceResponses\EchoResponse::class => 'EchoResponse',
62
        DeviceResponses\StateGroup::class => 'StateGroup',
63
        DeviceResponses\StateHostFirmware::class => 'StateHostFirmware',
64
        DeviceResponses\StateHostInfo::class => 'StateHostInfo',
65
        DeviceResponses\StateInfo::class => 'StateInfo',
66
        DeviceResponses\StateLabel::class => 'StateLabel',
67
        DeviceResponses\StateLocation::class => 'StateLocation',
68
        DeviceResponses\StatePower::class => 'StateDevicePower',
69
        DeviceResponses\StateService::class => 'StateService',
70
        DeviceResponses\StateVersion::class => 'StateVersion',
71
        DeviceResponses\StateWifiFirmware::class => 'StateWifiFirmware',
72
        DeviceResponses\StateWifiInfo::class => 'StateWifiInfo',
73
74
        // Light command messages
75
        LightCommands\SetColor::class => 'SetColor',
76
        LightCommands\SetInfrared::class => 'SetInfrared',
77
        LightCommands\SetPower::class => 'SetLightPower',
78
        LightCommands\SetWaveform::class => 'SetWaveform',
79
        LightCommands\SetWaveformOptional::class => 'SetWaveformOptional',
80
81
        // Light response messages
82
        LightResponses\State::class => 'State',
83
        LightResponses\StateInfrared::class => 'StateInfrared',
84
        LightResponses\StatePower::class => 'StateLightPower',
85
    ];
86
87 5
    private function encodeHsbkColor(LightDataTypes\HsbkColor $color): string
88
    {
89 5
        return \pack('v4', $color->getHue(), $color->getSaturation(), $color->getBrightness(), $color->getTemperature());
90
    }
91
92 2
    private function encodeLocation(DeviceDataTypes\Location $location): string
93
    {
94 2
        return \pack(
95 2
            'a16a32P',
96 2
            $location->getGuid()->getBytes(),
97 2
            $location->getLabel()->getValue(),
98 2
            datetimeinterface_to_nanotime($location->getUpdatedAt())
99
        );
100
    }
101
102 2
    private function encodeGroup(DeviceDataTypes\Group $group): string
103
    {
104 2
        return \pack(
105 2
            'a16a32P',
106 2
            $group->getGuid()->getBytes(),
107 2
            $group->getLabel()->getValue(),
108 2
            datetimeinterface_to_nanotime($group->getUpdatedAt())
109
        );
110
    }
111
112 2
    private function encodeFirmware(DeviceDataTypes\Firmware $firmware)
113
    {
114 2
        return \pack(
115 2
            'PPV',
116 2
            datetimeinterface_to_nanotime($firmware->getBuild()),
117 2
            0, // reserved
118 2
            $firmware->getVersion()
119
        );
120
    }
121
122 2
    private function encodeNetworkInfo(DeviceDataTypes\NetworkInfo $info): string
123
    {
124 2
        return \pack(
125 2
            FLOAT32_CODE . 'VVv',
126 2
            $info->getSignal(),
127 2
            $info->getTx(),
128 2
            $info->getRx(),
129 2
            0 // reserved
130
        );
131
    }
132
133
    private function encodeUnknownMessage(UnknownMessage $message): string
134
    {
135
        return $message->getData();
136
    }
137
138 1
    private function encodeStateVersion(DeviceResponses\StateVersion $message): string
139
    {
140 1
        $version = $message->getVersion();
141
142 1
        return \pack('VVV', $version->getVendor(), $version->getProduct(), $version->getVersion());
143
    }
144
145 1
    private function encodeStateService(DeviceResponses\StateService $message): string
146
    {
147 1
        $service = $message->getService();
148
149 1
        return \pack('CV', $service->getTypeId(), $service->getPort());
150
    }
151
152 1
    private function encodeStateInfo(DeviceResponses\StateInfo $message): string
153
    {
154 1
        $info = $message->getInfo();
155
156 1
        return \pack('PPP', datetimeinterface_to_nanotime($info->getTime()), $info->getUptime(), $info->getDowntime());
157
    }
158
159 1
    private function encodeStateHostFirmware(DeviceResponses\StateHostFirmware $message): string
160
    {
161 1
        return $this->encodeFirmware($message->getHostFirmware());
162
    }
163
164 1
    private function encodeStateHostInfo(DeviceResponses\StateHostInfo $message): string
165
    {
166 1
        return $this->encodeNetworkInfo($message->getHostInfo());
167
    }
168
169 1
    private function encodeStateWifiFirmware(DeviceResponses\StateWifiFirmware $message): string
170
    {
171 1
        return $this->encodeFirmware($message->getWifiFirmware());
172
    }
173
174 1
    private function encodeStateWifiInfo(DeviceResponses\StateWifiInfo $message): string
175
    {
176 1
        return $this->encodeNetworkInfo($message->getWifiInfo());
177
    }
178
179 1
    private function encodeSetGroup(DeviceCommands\SetGroup $message): string
180
    {
181 1
        return $this->encodeGroup($message->getGroup());
182
    }
183
184 1
    private function encodeStateGroup(DeviceResponses\StateGroup $message): string
185
    {
186 1
        return $this->encodeGroup($message->getGroup());
187
    }
188
189 1
    private function encodeSetLabel(DeviceCommands\SetLabel $message): string
190
    {
191 1
        return \pack('a32', $message->getLabel()->getValue());
192
    }
193
194 1
    private function encodeStateLabel(DeviceResponses\StateLabel $message): string
195
    {
196 1
        return \pack('a32', $message->getLabel()->getValue());
197
    }
198
199 1
    private function encodeSetLocation(DeviceCommands\SetLocation $message): string
200
    {
201 1
        return $this->encodeLocation($message->getLocation());
202
    }
203
204 1
    private function encodeStateLocation(DeviceResponses\StateLocation $message): string
205
    {
206 1
        return $this->encodeLocation($message->getLocation());
207
    }
208
209 1
    private function encodeSetDevicePower(DeviceCommands\SetPower $message): string
210
    {
211 1
        return \pack('v', $message->getLevel());
212
    }
213
214 1
    private function encodeStateDevicePower(DeviceResponses\StatePower $message): string
215
    {
216 1
        return \pack('v', $message->getLevel());
217
    }
218
219 1
    private function encodeEchoRequest(DeviceRequests\EchoRequest $message): string
220
    {
221 1
        return $message->getPayload();
222
    }
223
224 1
    private function encodeEchoResponse(DeviceResponses\EchoResponse $message): string
225
    {
226 1
        return $message->getPayload();
227
    }
228
229 2
    private function encodeSetColor(LightCommands\SetColor $message): string
230
    {
231 2
        $transition = $message->getColorTransition();
232
233 2
        return "\x00" . $this->encodeHsbkColor($transition->getColor()) . \pack('V', $transition->getDuration());
234
    }
235
236 1
    private function encodeSetInfrared(LightCommands\SetInfrared $message): string
237
    {
238 1
        return \pack('v', $message->getBrightness());
239
    }
240
241 1
    private function encodeStateInfrared(LightResponses\StateInfrared $message): string
242
    {
243 1
        return \pack('v', $message->getBrightness());
244
    }
245
246 1
    private function encodeSetLightPower(LightCommands\SetPower $message): string
247
    {
248 1
        $transition = $message->getPowerTransition();
249
250 1
        return \pack('vV', $transition->getLevel(), $transition->getDuration());
251
    }
252
253 1
    private function encodeStateLightPower(LightResponses\StatePower $message): string
254
    {
255 1
        return \pack('v', $message->getLevel());
256
    }
257
258 1
    private function encodeState(LightResponses\State $message): string
259
    {
260 1
        $state = $message->getState();
261
262 1
        return $this->encodeHsbkColor($state->getColor()) . \pack(
263 1
            'v2a32P',
264 1
            0, // reserved
265 1
            $state->getPower(),
266 1
            $state->getLabel()->getValue(),
267 1
            0  // reserved
268
        );
269
    }
270
271 1
    private function encodeSetWaveform(LightCommands\SetWaveform $message): string
272
    {
273 1
        $effect = $message->getEffect();
274 1
        $skew = int16_to_uint16($effect->getSkewRatio());
275
276 1
        return "\x00" . \chr((int)$effect->isTransient())
277 1
            . $this->encodeHsbkColor($effect->getColor())
278 1
            . \pack('V' . FLOAT32_CODE . 'vC', $effect->getPeriod(), $effect->getCycles(), $skew, $effect->getWaveform())
279
        ;
280
    }
281
282 1
    private function encodeSetWaveformOptional(LightCommands\SetWaveformOptional $message): string
283
    {
284 1
        $effect = $message->getEffect();
285 1
        $skew = int16_to_uint16($effect->getSkewRatio());
286
287 1
        $options = $effect->getOptions();
288 1
        $optionData = \pack(
289 1
            'C4',
290 1
            (int)(bool)($options & LightDataTypes\Effect::SET_HUE),
291 1
            (int)(bool)($options & LightDataTypes\Effect::SET_SATURATION),
292 1
            (int)(bool)($options & LightDataTypes\Effect::SET_BRIGHTNESS),
293 1
            (int)(bool)($options & LightDataTypes\Effect::SET_TEMPERATURE)
294
        );
295
296 1
        return "\x00" . \chr((int)$effect->isTransient())
297 1
            . $this->encodeHsbkColor($effect->getColor())
298 1
            . \pack('V' . FLOAT32_CODE . 'vC', $effect->getPeriod(), $effect->getCycles(), $skew, $effect->getWaveform())
299 1
            . $optionData
300
        ;
301
    }
302
303 41
    public function encodeMessage(Message $message): string
304
    {
305 41
        return \array_key_exists($class = \get_class($message), self::ENCODING_ROUTINES)
306 26
            ? $this->{'encode' . self::ENCODING_ROUTINES[$class]}($message)
307 41
            : '';
308
    }
309
}
310