Python LimitlessLED via RF

Check-in [9ade53d067]
Login
Overview
Comment:Updated with some corrections
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 9ade53d067f1db41d12a62eab4312c2195f6db42d0e9cd98d7189cef887603aa
User & Date: rkeene on 2020-04-29 22:51:27
Other Links: manifest | tags
Context
2020-04-29
23:31
Corrected color temperature inversion and max brightness bug check-in: 1e1bbc1d62 user: rkeene tags: trunk
22:51
Updated with some corrections check-in: 9ade53d067 user: rkeene tags: trunk
13:52
limitlessled_rf v0.4 Added a few methods to query check-in: 18297c8278 user: rkeene tags: 0.4, trunk
Changes

Modified limitlessled_rf/__init__.py from [eb7f037ffb] to [114a008632].

1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
19
20











-
-
+
+







#! /usr/bin/env python3

import random
import time

class Remote:
	_remote_type_alias_map = {
		'fut089': 'rgb+cct'
	}
	_remote_type_parameters_map = {
		'rgbw': {
			'retries':  3,
			'delay':    0.005,
			'retries':  10,
			'delay':    0.001,
			'channels': [9, 40, 71],
			'syncword': [0x258B, 0x147A],
			'features': [
				'can_set_brightness',
				'has_brightness',
				'has_white',
				'has_color'
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56







-
+







				'zone_night:2': 0x16,
				'zone_night:3': 0x18,
				'zone_night:4': 0x1A,
				'speed_up':   0x0B,
				'speed_down': 0x0C,
				'change_color_mode': 0x0D,
				'zone_set_brightness': 0x0E,
				'set_color':  0x0F
				'zone_set_color':  0x0F
			}
		},
		'cct': {
			'retries':  10,
			'delay':    0.5,
			'channels': [4, 39, 74],
			'syncword': [0x55AA, 0x050A],
250
251
252
253
254
255
256






257
258
259
260
261
262
263
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269







+
+
+
+
+
+







				'zone': zone
			})
		return True

	def _compute_button_message_rgbw(self, button_info):
		remote_id = button_info['remote_id']
		message_id = button_info['message_id']

		# Allow setting color for all zones
		if button_info['button'] == 'set_color':
			button_info['button'] = 'zone_set_color'
			if 'zone' in button_info:
				del button_info['zone']

		# Allow setting brightness for all zones
		if button_info['button'] == 'set_brightness':
			button_info['button'] = 'zone_set_brightness'
			if 'zone' in button_info:
				del button_info['zone']

286
287
288
289
290
291
292
293
294


295

296
297





298
299
300
301
302
303
304
292
293
294
295
296
297
298


299
300
301
302


303
304
305
306
307
308
309
310
311
312
313
314







-
-
+
+

+
-
-
+
+
+
+
+







			elif brightness > 25:
				brightness = 25

			brightness = 31 - ((brightness + 15) % 32)

			brightness = brightness << 3

			if 'zone' in button_info:
				brightness = brightness | button_info['zone']
		elif button_info['button'] == 'zone_set_color':
			color = button_info['color']

		# The zone number is also encoded into the brightness byte
		elif button_info['button'] == 'set_color':
			color = button_info['color']
		if 'zone' not in button_info:
			zone_value = 0
		else:
			zone_value = button_info['zone']
		brightness |= zone_value & 0b111

		# Compute message
		body = [color, brightness, button_id, message_id]

		# Compute whole message
		message = header + body

341
342
343
344
345
346
347




348
349
350
351
352
353
354
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368







+
+
+
+







		self._send_button({
			'button': 'zone_on',
			'zone': zone
		})
		return False

	def _unpair_rgbw(self, zone):
		self._send_button({
			'button': 'zone_on',
			'zone': zone
		})
		self._send_button({
			'button': 'zone_white',
			'zone': zone
		})
		return False

	def _get_next_message_id(self):
519
520
521
522
523
524
525

526

527
528
529
530
531
532
533
533
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548







+
-
+








	def raw_send_button(self, button_info):
		return self._send_button(button_info)

	def raw_read_button(self):
		channel = self._config['channels'][0]
		self._radio.set_syncword(self._config['syncword'])
		self._radio.start_listening(channel)
		data = self._radio.receive(channel = channel, wait = True, wait_time = 1)
		data = self._radio.receive(channel = channel, wait = True, wait_time = 0)
		message = self._parse_button_message(data)
		return message

	def set_brightness(self, brightness, zone = None):
		if 'has_brightness' not in self._config['features']:
			return False

567
568
569
570
571
572
573

574
575





576
577
578

579
580
581
582
583
584
585
582
583
584
585
586
587
588
589


590
591
592
593
594
595
596

597
598
599
600
601
602
603
604







+
-
-
+
+
+
+
+


-
+







			else:
				return False

		# If the bulbs do not support color, nothing needs to be done
		if 'has_color' not in self._config['features']:
			return False

		# Press the correct color button
		# Turn on the appropriate zone to select it
		self.on(zone, try_hard = False)
		if zone is None:
			message = {'button': 'set_color'}
		else:
			message = {'button': 'zone_set_color', 'zone': zone}
		message['color'] = value

		# Press the button
		return self._send_button({'button': 'set_color', 'color': value})
		return self._send_button(message)

	def set_temperature(self, kelvins, zone = None):
		if 'has_temperature' not in self._config['features']:
			return False

		temperature_input_low = self._config['temperature_input_range'][0]
		temperature_input_high = self._config['temperature_input_range'][1]