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
#! /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,
			'channels': [9, 40, 71],
			'syncword': [0x258B, 0x147A],
			'features': [
				'can_set_brightness',
				'has_brightness',
				'has_white',
				'has_color'











|
|







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':  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
				'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
			}
		},
		'cct': {
			'retries':  10,
			'delay':    0.5,
			'channels': [4, 39, 74],
			'syncword': [0x55AA, 0x050A],







|







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,
				'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
				'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 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']








>
>
>
>
>
>







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
			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'] == 'set_color':


			color = button_info['color']


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

		# Compute whole message
		message = header + body








|
|

>
|
>
>
|
>







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

		elif button_info['button'] == 'zone_set_color':
			color = button_info['color']

		# The zone number is also encoded into the brightness byte
		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
		self._send_button({
			'button': 'zone_on',
			'zone': zone
		})
		return False

	def _unpair_rgbw(self, zone):




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

	def _get_next_message_id(self):







>
>
>
>







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

	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'])

		data = self._radio.receive(channel = channel, wait = True, wait_time = 1)
		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








>
|







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 = 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
			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


		# Turn on the appropriate zone to select it

		self.on(zone, try_hard = False)



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

	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]







>
|
>
|
>
>


|







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
		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(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]