Python LimitlessLED via RF

Check-in [f1ab1c6102]
Login

Check-in [f1ab1c6102]

Overview
Comment:Pass in format config and more prototype LYH bulb support
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: f1ab1c61024f549a0fffa0b7f72423a1ebdac9007a88c845a36d02313542f72a
User & Date: rkeene on 2020-05-17 21:16:58
Other Links: manifest | tags
Context
2020-05-17
21:17
limitlessled_rf v0.14 check-in: 2ea910c594 user: rkeene tags: 0.14, trunk
21:16
Pass in format config and more prototype LYH bulb support check-in: f1ab1c6102 user: rkeene tags: trunk
2020-05-10
03:39
limitlessled_rf v0.13 check-in: fe013ba8dd user: rkeene tags: 0.13, trunk
Changes

Modified limitlessled_rf/__init__.py from [0e252d2773] to [f3be2e4306].

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
				'change_color_mode': 0x0D,
				'zone_set_brightness': 0x0E,
				'zone_set_color':  0x0F
			}
		},
		'cct': {
			'retries':  10,
			'delay':    0.1,
			'channels': [4, 39, 74],
			'syncword': [0x55AA, 0x050A],
			'brightness_range': [0, 9],
			'temperature_output_range': [0, 9],
			'temperature_input_range':  [6500, 3000],
			'zones': [1, 2, 3, 4],
			'features': [







|







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
				'change_color_mode': 0x0D,
				'zone_set_brightness': 0x0E,
				'zone_set_color':  0x0F
			}
		},
		'cct': {
			'retries':  10,
			'delay':    0.2,
			'channels': [4, 39, 74],
			'syncword': [0x55AA, 0x050A],
			'brightness_range': [0, 9],
			'temperature_output_range': [0, 9],
			'temperature_input_range':  [6500, 3000],
			'zones': [1, 2, 3, 4],
			'features': [
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
				'brightness_up':    0x0C,
				'brightness_down':  0x04,
				'temperature_up':   0x0E,
				'temperature_down': 0x0F
			}
		},
		'lyh_cct': {
			'retries':  10,
			'delay':    0.1,
			'channels': [24],
			'syncword': [0x6F67, 0xA118],
			'message_length': 14,
			'format_config': {
				'crc_enabled': 0,
				'packet_length_encoded': 0,
				'auto_term_tx': 0
			},
			'brightness_range': [0, 9],
			'temperature_output_range': [0, 9],
			'temperature_input_range':  [6500, 3000],
			'zones': [1, 2, 3],
			'features': [
				'has_max_brightness',
				'has_brightness',
				'has_temperature',
				'is_white'
			],
			'button_map': {
				'on':         0x05,
				'off':        0x09,







|
|


|










<







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
				'brightness_up':    0x0C,
				'brightness_down':  0x04,
				'temperature_up':   0x0E,
				'temperature_down': 0x0F
			}
		},
		'lyh_cct': {
			'retries':  50,
			'delay':    0.2,
			'channels': [24],
			'syncword': [0x6F67, 0xA118],
			'message_length': 13,
			'format_config': {
				'crc_enabled': 0,
				'packet_length_encoded': 0,
				'auto_term_tx': 0
			},
			'brightness_range': [0, 9],
			'temperature_output_range': [0, 9],
			'temperature_input_range':  [6500, 3000],
			'zones': [1, 2, 3],
			'features': [

				'has_brightness',
				'has_temperature',
				'is_white'
			],
			'button_map': {
				'on':         0x05,
				'off':        0x09,
228
229
230
231
232
233
234




235





















































236










237
238
239
240
241
242
243
			button_name_zone = button_info['button'].split(':')
			button_info['button'] = button_name_zone[0]
			button_info['zone']   = int(button_name_zone[1])

		return button_info

	def _compute_button_message_lyh_cct(self, button_info):




		# XXX





















































		return None











	def _parse_button_message_lyh_cct(self, button_message):
		return {'raw': button_message}
		return None

	def _pair_lyh_cct(self, zone):
		# XXX







>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
			button_name_zone = button_info['button'].split(':')
			button_info['button'] = button_name_zone[0]
			button_info['zone']   = int(button_name_zone[1])

		return button_info

	def _compute_button_message_lyh_cct(self, button_info):
		# XXX: This protocol has not been completely reversed yet
		if 'zone' in button_info:
			if button_info['zone'] is None:
				del button_info['zone']

		message_id = button_info['message_id']

		retval = None

		if button_info['button'] == 'on' and 'zone' not in button_info:
			if 'zone' not in button_info:
				retval = [0x85, 0xb7, 0x80, 0x88, 0x91, 0xb1, 0x6f, 0x00, 0x66, 0x01, 0x59, 0xad, 0x07]
			elif button_info['zone'] == 1:
				retval = [0x85, 0xb7, 0x80, 0x88, 0x91, 0xb1, 0x68, 0x00, 0x67, 0x01, 0xd3, 0xff, 0x46]
			elif button_info['zone'] == 2:
				retval = [0x85, 0xb7, 0x80, 0x88, 0x91, 0x31, 0x69, 0x80, 0x67, 0x01, 0xd4, 0xc8, 0x11]
			elif button_info['zone'] == 3:
				retval = [0x85, 0xb7, 0x80, 0x88, 0x91, 0x31, 0x6a, 0x00, 0x68, 0x81, 0x55, 0xe0, 0x72]

		if button_info['button'] == 'off':
			if 'zone' not in button_info:
				retval = [0x05, 0xb0, 0x80, 0x88, 0x91, 0xb1, 0x6f, 0x80, 0x66, 0x01, 0xd2, 0xf6, 0x46]
			elif button_info['zone'] == 1:
				retval = [0x05, 0xb0, 0x80, 0x88, 0x91, 0xb1, 0x68, 0x80, 0x68, 0x01, 0x4d, 0x4f, 0x0a]
			elif button_info['zone'] == 2:
				retval = [0x05, 0xb0, 0x80, 0x88, 0x91, 0x31, 0x69, 0x00, 0x69, 0x01, 0x4e, 0x80, 0x41]
			elif button_info['zone'] == 3:
				retval = [0x05, 0xb0, 0x80, 0x88, 0x91, 0x31, 0x6a, 0x80, 0x69, 0x81, 0xcf, 0x6f, 0x68]

		if button_info['button'] == 'brightness_up':
			if message_id % 2 == 0:
				retval = [0x05, 0xb3, 0x80, 0x88, 0x91, 0xb1, 0x6f, 0x00, 0x39, 0x81, 0xa7, 0x33, 0x7e]
			else:
				retval = [0x05, 0xb3, 0x80, 0x88, 0x91, 0xb1, 0x6f, 0x00, 0x3c, 0x81, 0x2a, 0x63, 0x18]

		if button_info['button'] == 'brightness_down':
			if message_id % 2 == 0:
				retval = [0x85, 0xb2, 0x80, 0x88, 0x91, 0xb1, 0x6f, 0x00, 0x3d, 0x01, 0x2b, 0xc6, 0x61]
			else:
				retval = [0x85, 0xb2, 0x80, 0x88, 0x91, 0xb1, 0x6f, 0x00, 0x45, 0x01, 0xb3, 0x1d, 0x3f]

		if button_info['button'] == 'temperature_up':
			if message_id % 2 == 0:
				retval = [0x85, 0xb4, 0x80, 0x88, 0x91, 0xb1, 0x6f, 0x00, 0x4b, 0x01, 0xbb, 0x9c, 0x4b]
			else:
				retval = [0x85, 0xb4, 0x80, 0x88, 0x91, 0xb1, 0x6f, 0x80, 0x4e, 0x81, 0x3e, 0x26, 0x00]

		if button_info['button'] == 'temperature_down':
			if message_id % 2 == 0:
				retval = [0x05, 0xb5, 0x80, 0x88, 0x91, 0xb1, 0x6f, 0x80, 0x46, 0x01, 0x37, 0xd5, 0x69]
			else:
				retval = [0x05, 0xb5, 0x80, 0x88, 0x91, 0xb1, 0x6f, 0x80, 0x4a, 0x01, 0x3b, 0x1a, 0x06]

		if button_info['button'] == 'max':
			retval = [0x85, 0xb7, 0x80, 0x88, 0x91, 0xb1, 0x6f, 0x80, 0x66, 0x81, 0xd9, 0x07, 0x22]

		if retval is None:
			self._debug("Unsupported button: {}".format(button_info))
			return None

		# XXX: This probably breaks the CRC :-(
		if 'zone' in button_info:
			retval[6] = (retval[6] & 0xf0) | (0x07 + button_info['zone'])
		else:
			retval[6] = (retval[6] & 0xf0) | 0x0f

		retval.append(0x00)
		retval.append(0x0F)
		return retval

	def _parse_button_message_lyh_cct(self, button_message):
		return {'raw': button_message}
		return None

	def _pair_lyh_cct(self, zone):
		# XXX
465
466
467
468
469
470
471


472
473
474
475
476
477
478
479
480
		else:
			delay = self._config['delay']
		if 'retries' in button_info:
			retries = button_info['retries']
		else:
			retries = self._config['retries']



		self._debug("Sending {}={} n={} times with a {}s delay to queue {}".format(button_info, message, retries, delay, self._config['radio_queue']))
		self._radio.multi_transmit(message, self._config['channels'], retries, delay, syncword = self._config['syncword'], submit_queue = self._config['radio_queue'])

		return True

	def _set_brightness(self, brightness, zone = None):
		if zone is None:
			message = {'button': 'set_brightness'}
		else:







>
>
|
|







531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
		else:
			delay = self._config['delay']
		if 'retries' in button_info:
			retries = button_info['retries']
		else:
			retries = self._config['retries']

		format_config = self._config.get('format_config', None)

		self._debug("Sending {}={} n={} times with a {}s delay to queue {}, format = {}".format(button_info, message, retries, delay, self._config['radio_queue'], format_config))
		self._radio.multi_transmit(message, self._config['channels'], retries, delay, syncword = self._config['syncword'], submit_queue = self._config['radio_queue'], format_config = format_config)

		return True

	def _set_brightness(self, brightness, zone = None):
		if zone is None:
			message = {'button': 'set_brightness'}
		else: