diff --git a/broadlink/__init__.py b/broadlink/__init__.py index d3135501..4afe7e45 100644 --- a/broadlink/__init__.py +++ b/broadlink/__init__.py @@ -10,7 +10,7 @@ from .cover import dooya, dooya2, wser from .device import Device, ping, scan from .hub import s3 -from .light import lb1, lb2 +from .light import lb1, lb2, fl1 from .remote import rm, rm4, rm4mini, rm4pro, rmmini, rmminib, rmpro from .sensor import a1, a2 from .switch import bg1, ehc31, mp1, mp1s, sp1, sp2, sp2s, sp3, sp3s, sp4, sp4b @@ -179,6 +179,9 @@ 0xA5F7: ("LB27 R1", "Broadlink"), 0xA6EF: ("EFCF60WSMT", "Luceco"), }, + fl1: { + 0x647A: {"Castra", "Luceco"}, + }, S1C: { 0x2722: ("S2KIT", "Broadlink"), }, diff --git a/broadlink/light.py b/broadlink/light.py index 1ae87e8f..20ebe2e5 100644 --- a/broadlink/light.py +++ b/broadlink/light.py @@ -8,7 +8,42 @@ from .device import Device -class lb1(Device): +class lb1_base(Device): + """Base for lb1 style devices.""" + + def get_state(self) -> dict: + """Return the power state of the device. + + Example: `{'red': 128, 'blue': 255, 'green': 128, 'pwr': 1, 'brightness': 75, 'colortemp': 2700, 'hue': 240, 'saturation': 50, 'transitionduration': 1500, 'maxworktime': 0, 'bulb_colormode': 1, 'bulb_scenes': '["@01686464,0,0,0", "#ffffff,10,0,#000000,190,0,0", "2700+100,0,0,0", "#ff0000,500,2500,#00FF00,500,2500,#0000FF,500,2500,0", "@01686464,100,2400,@01686401,100,2400,0", "@01686464,100,2400,@01686401,100,2400,@005a6464,100,2400,@005a6401,100,2400,0", "@01686464,10,0,@00000000,190,0,0", "@01686464,200,0,@005a6464,200,0,0"]', 'bulb_scene': '', 'bulb_sceneidx': 255}` + """ + packet = self._encode(1, {}) + response = self.send_packet(0x6A, packet) + e.check_error(response[0x22:0x24]) + return self._decode(response) + + def _encode(self, flag: int, state: dict) -> bytes: + """Encode a JSON packet.""" + # flag: 1 for reading, 2 for writing. + packet = bytearray(14) + data = json.dumps(state, separators=(",", ":")).encode() + p_len = 12 + len(data) + struct.pack_into( + " dict: + """Decode a JSON packet.""" + payload = self.decrypt(response[0x38:]) + js_len = struct.unpack_from(" dict: - """Return the power state of the device. - - Example: `{'red': 128, 'blue': 255, 'green': 128, 'pwr': 1, 'brightness': 75, 'colortemp': 2700, 'hue': 240, 'saturation': 50, 'transitionduration': 1500, 'maxworktime': 0, 'bulb_colormode': 1, 'bulb_scenes': '["@01686464,0,0,0", "#ffffff,10,0,#000000,190,0,0", "2700+100,0,0,0", "#ff0000,500,2500,#00FF00,500,2500,#0000FF,500,2500,0", "@01686464,100,2400,@01686401,100,2400,0", "@01686464,100,2400,@01686401,100,2400,@005a6464,100,2400,@005a6401,100,2400,0", "@01686464,10,0,@00000000,190,0,0", "@01686464,200,0,@005a6464,200,0,0"]', 'bulb_scene': '', 'bulb_sceneidx': 255}` - """ - packet = self._encode(1, {}) - response = self.send_packet(0x6A, packet) - e.check_error(response[0x22:0x24]) - return self._decode(response) - def set_state( self, pwr: Optional[bool] = None, @@ -84,27 +109,6 @@ def set_state( e.check_error(response[0x22:0x24]) return self._decode(response) - def _encode(self, flag: int, state: dict) -> bytes: - """Encode a JSON packet.""" - # flag: 1 for reading, 2 for writing. - packet = bytearray(14) - data = json.dumps(state, separators=(",", ":")).encode() - p_len = 12 + len(data) - struct.pack_into( - " dict: - """Decode a JSON packet.""" - payload = self.decrypt(response[0x38:]) - js_len = struct.unpack_from(" dict: js_len = struct.unpack_from(" dict: + """change state names that contain spaces """ + if "Brightness control" in state: + state["brightness_control"] = state["Brightness control"] + del state["Brightness control"] + if "Delay time" in state: + state["delay_time"] = state["Delay time"] + del state["Delay time"] + + return state + + def get_state(self) -> dict: + return self.fix_state(super().get_state()) + + def set_state( + self, + mode_switch: Optional[int] = None, + lightpwr: Optional[bool] = None, + brightness: Optional[int] = None, + brightness_control: Optional[int] = None, + delay_time: Optional[int] = None, + sensitivity_en: Optional[int] = None, + ) -> dict: + """Set the power state of the device.""" + state = {} + if mode_switch is not None: + state["mode_switch"] = int(mode_switch) + if lightpwr is not None: + state["lightpwr"] = int(bool(lightpwr)) + state["mode_switch"] = 5 + if brightness is not None: + state["brightness"] = int(brightness) + if brightness_control is not None: + state["Brightness control"] = int(brightness_control) + if delay_time is not None: + state["Delay time"] = int(delay_time) + if sensitivity_en is not None: + state["sensitivity_en"] = int(sensitivity_en) + + packet = self._encode(2, state) + response = self.send_packet(0x6A, packet) + e.check_error(response[0x22:0x24]) + + return self.fix_state(self._decode(response)) diff --git a/cli/broadlink_cli b/cli/broadlink_cli index 7913e332..b79506f5 100755 --- a/cli/broadlink_cli +++ b/cli/broadlink_cli @@ -34,6 +34,14 @@ parser.add_argument("--device", help="device definition as 'type host mac'") parser.add_argument("--type", type=auto_int, default=0x2712, help="type of device") parser.add_argument("--host", help="host address") parser.add_argument("--mac", help="mac address (hex reverse), as used by python-broadlink library") +parser.add_argument("--brightness", action="store", help="set lamp brightness") +parser.add_argument("--flmode", action="store", help="set floodlight mode (0, 5, 6, 7)") +parser.add_argument("--flon", action="store_true", help="turn floodlight on") +parser.add_argument("--floff", action="store_true", help="turn floodlight off") +parser.add_argument("--ontime", action="store", help="set floodlight on time (10 - 1800)") +parser.add_argument("--sensitivity", action="store", help="set motion sensitivity (0 - 3)") +parser.add_argument("--brightnesscontrol", action="store", help="set ambient light threshold (5 - 2000)") +parser.add_argument("--getstate", action="store_true", help="get current state") parser.add_argument("--temperature", action="store_true", help="request temperature from device") parser.add_argument("--humidity", action="store_true", help="request humidity from device") parser.add_argument("--energy", action="store_true", help="request energy consumption from device") @@ -74,6 +82,23 @@ if args.host or args.device: if args.joinwifi: broadlink.setup(args.joinwifi[0], args.joinwifi[1], 4) +if args.flmode: + dev.set_state(mode_switch=args.flmode) +if args.flon: + dev.set_state(lightpwr=1) +if args.floff: + dev.set_state(lightpwr=0) +if args.brightness: + dev.set_state(brightness=args.brightness) +if args.ontime: + dev.set_state(delay_time=args.ontime) +if args.sensitivity: + dev.set_state(sensitivity_en=args.sensitivity) +if args.brightnesscontrol: + dev.set_state(brightness_control=args.brightnesscontrol) +if args.getstate: + print(dev.get_state()) + if args.convert: data = bytearray.fromhex(''.join(args.data)) pulses = data_to_pulses(data)