omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Accessing the LED flashlight

    Pythonista
    9
    21
    17900
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • chiefenne
      chiefenne last edited by

      Is it possible to access the LED flashlight of an iPhone using Pythonista?

      1 Reply Last reply Reply Quote 0
      • omz
        omz last edited by

        Sorry, this isn't possible.

        1 Reply Last reply Reply Quote 0
        • ccc
          ccc last edited by

          Not even with all your new ctypes tricks? Turning on and off the iPhone flashlight appears to be not many lines of Objective C. In particular, this code or this code seemed to be quite compact.

          1 Reply Last reply Reply Quote 0
          • omz
            omz last edited by

            @ccc That's a great idea! Just tried it out, and yes, this works (in the current beta):

            from ctypes import c_void_p, c_char_p, c_int, c_bool, cdll
            
            objc = cdll.LoadLibrary(None)
            objc.sel_getName.restype = c_char_p
            objc.sel_getName.argtypes = [c_void_p]
            objc.sel_registerName.restype = c_void_p
            objc.sel_registerName.argtypes = [c_char_p]
            objc.objc_getClass.argtypes = [c_char_p]
            objc.objc_getClass.restype = c_void_p
            
            # Some helper methods:
            def msg(obj, restype, sel, argtypes=None, *args):
            	if argtypes is None:
            		argtypes = []
            	objc.objc_msgSend.argtypes =  [c_void_p, c_void_p] + argtypes
            	objc.objc_msgSend.restype = restype
            	res = objc.objc_msgSend(obj, objc.sel_registerName(sel), *args)
            	return res
            
            def cls(cls_name):
            	return objc.objc_getClass(cls_name)
            
            def nsstr(s):
            	return msg(cls('NSString'), c_void_p, 'stringWithUTF8String:', [c_char_p], s)
            
            def toggle_flashlight():
            	AVCaptureDevice = cls('AVCaptureDevice')
            	device = msg(AVCaptureDevice, c_void_p, 'defaultDeviceWithMediaType:', [c_void_p], nsstr('vide'))
            	has_torch = msg(device, c_bool, 'hasTorch')
            	if not has_torch:
            		raise RuntimeError('Device has no flashlight')
            	current_mode = msg(device, c_int, 'torchMode')
            	mode = 1 if current_mode == 0 else 0
            	msg(device, None, 'lockForConfiguration:', [c_void_p], None)
            	msg(device, None, 'setTorchMode:', [c_int], mode)
            	msg(device, None, 'unlockForConfiguration')
            
            if __name__ == '__main__':
            	toggle_flashlight()
            
            1 Reply Last reply Reply Quote 0
            • chiefenne
              chiefenne last edited by

              Thank you very much. I'll test it and will give feedback. May take some time though.

              Background on my app:
              I am currently writing an app which translates text to the NATO phonetic alphabet and also Morse code.
              The translated text is spoken by using the speech modul in several languages (works really well) and the Morse code of the translation shall be flashing on pushing a button.
              I'll also have predefined radio text and so on.

              1 Reply Last reply Reply Quote 0
              • omz
                omz last edited by

                @chiefenne Sounds cool. Just to be clear: This will only work in the current beta version of Pythonista (1.6), not in the current version from the App Store (1.5). If you don't have the beta yet, feel free to send me an email with your Apple ID, and I'll invite you via TestFlight: http://omz-software.com/contact

                1 Reply Last reply Reply Quote 0
                • ccc
                  ccc last edited by ccc

                  A working prototype of a ui that lets you type in ascii letters and numbers and it will send out corresponding Morse code via the iOS flashlight. You need to have three files in the same directory: MorseView.py and morse_code.py and OMZ's code above put into a file called toggle_flashlight.py.

                  Run MorseView and change the text if you want and then tap the button. Of course this will only work if your iOS device has flashlight capabilities.

                  1 Reply Last reply Reply Quote 0
                  • chiefenne
                    chiefenne last edited by

                    Wow. @ccc. Very cool. Thanks a lot. Though I did already some of the work;)

                    @omz. I'll apply for the beta. Thank you.

                    Thank you all.

                    1 Reply Last reply Reply Quote 0
                    • ccc
                      ccc last edited by

                      Great... Please take the best of your work and the best of @omz's and mine and create something even better.

                      I would be interested in feedback. I don't "speak" Morse code so I would be interested to understand if real practitioners can understand the messages that this app sends. Is 2/10th of a second for dot_secs too fast or too slow for folks who really know their Morse code by heart? Would a slider to set the delay time be useful or unnecessary? If a slider would be useful, what would be the fastest and slowest times on that slider? If too fast, perhaps older/slower iPhone models might not process the on/off fast enough to provide clean messages.

                      Maybe you should edit the title of this thread to read: Accessing the LED flashlight to send Morse code

                      1 Reply Last reply Reply Quote 0
                      • polymerchm
                        polymerchm last edited by

                        I haven't had a chance to play with this, but the engineer in me asks if there are an accessible light sensors in the iphone that can "read" the incoming morse code?

                        1 Reply Last reply Reply Quote 0
                        • ccc
                          ccc last edited by

                          @omz I have been updating my scripts to run on Python3... I have the sense that your toggle_flashlight code above could be streamlined these daze but I am not sure how to make it work under P3.

                          1 Reply Last reply Reply Quote 0
                          • omz
                            omz last edited by omz

                            @ccc Yes, much less boilerplate code is required now:

                            from objc_util import ObjCClass
                            
                            def toggle_flashlight():
                                AVCaptureDevice = ObjCClass('AVCaptureDevice')
                                device = AVCaptureDevice.defaultDeviceWithMediaType_('vide')
                                if not device.hasTorch():
                                    raise RuntimeError('Device has no flashlight')
                                mode = device.torchMode()
                                device.lockForConfiguration_(None)
                                device.setTorchMode_((mode + 1) % 2)
                                device.unlockForConfiguration()
                            
                            if __name__ == '__main__':
                                toggle_flashlight()
                            
                            1 Reply Last reply Reply Quote 0
                            • Phuket2
                              Phuket2 last edited by

                              This is not as Flash 😁 But the way the new Iphones use the screen as a flash for the front facing camera is an interesting possibility, also for devices that don't have a flash. I don't know, but could prove more reliable depending on distance etc. just a thought

                              1 Reply Last reply Reply Quote 0
                              • blmacbeth
                                blmacbeth last edited by

                                @Phuket2 quoted from the Apple developer forums:

                                Retina Flash
                                iPhone 6s and 6s Plus contain a custom display chip that allows the retina display to briefly flash 3 times brighter than its usual maximum illuminance. No new API was added to support this feature. Since iOS 4, AVCaptureDevice has supported the -hasFlash, -isFlashModeSupported: and -flashMode properties. The iPhone 6s and 6s Plus front-facing cameras are the first front-facing iOS cameras to respond YES to the -hasFlash property. By setting the front-facing camera's flashMode to AVCaptureFlashModeOn or AVCaptureFlashModeAuto, the retina flash fires when a still image is captured (see AVCaptureStillImageOutput’s captureStillImageAsynchronouslyFromConnection:completionHandler:), just as the True Tone flash fires for rear-facing camera stills.

                                Hope this. Only works on 6s, 6s+, and SE.
                                B.

                                Phuket2 1 Reply Last reply Reply Quote 0
                                • Phuket2
                                  Phuket2 @blmacbeth last edited by Phuket2

                                  @blmacbeth , ok thanks. I didn't know how they did it, was just nice, I have tried it several times on my 6s. But I think for the application here, you could still just fake it. Well, I think you could. I think somehow, it could be a better option to fake it with the screen as you have control over the timing and can calibrate etc. I just assume this would be hard to do with the flash. But I can see why the flash is appealing.
                                  I brought my 6s without even knowing that it had the screen flash option.when I seen it, I just thought really, this is so simple and genius. But I get your point about the special API. Timing and white point/Lums etc... Critical.
                                  Edit: but not so critical for dot, dash

                                  1 Reply Last reply Reply Quote 0
                                  • Tizzy
                                    Tizzy last edited by

                                    @omz @Phuket2 @ccc would any of you happen to know how to set a custom brightness for the flashlight as some apps in the App Store can do? Passing anything other than an integer to setTorchMode() throws an error...

                                    I tried as to do device.setTorchModeOnWithLevel_() as per some objective c, and trying to recognize patterns between the. Objc c code on stack overflow and your Python example..., but get error no method found for selector..

                                    Tbh, I have no idea what I'm doing with objc_util .... :(

                                    Tizzy 1 Reply Last reply Reply Quote 0
                                    • Tizzy
                                      Tizzy @Tizzy last edited by

                                      As a side note I would gladly pay for a Pythonista objc-util tutorial for dummies.

                                      1 Reply Last reply Reply Quote 0
                                      • dgelessus
                                        dgelessus last edited by

                                        @Tizzy According to a random Stack Overflow question I googled, the call looks like this in Objective-C:

                                        BOOL success = [device setTorchModeOnWithLevel:0.2 error:&outError];
                                        

                                        There is a second error argument that you need to pass, so in Python the call would look like this:

                                        device.setTorchModeOnWithLevel_error_(0.2, 0)
                                        

                                        (assuming that error can be NULL - if not, you need to pass something else there, but I know nothing about Objective-C, so I can't help you with that)

                                        1 Reply Last reply Reply Quote 0
                                        • JonB
                                          JonB last edited by

                                          I believe you can usually use None for error arguments (often you see error:nil in stackoverflow). I suspect passing zero is the same thing.

                                          1 Reply Last reply Reply Quote 0
                                          • omz
                                            omz last edited by omz

                                            You can't pass zero for a parameter that expects a pointer.

                                            This should work:

                                            device.setTorchModeOnWithLevel_error_(0.2, None)
                                            

                                            I noticed that passing 0.0 for the level crashes (haven't checked why exactly, it probably throws an exception), so you'd need to use setTorchMode_ (as above) to turn it back off again.

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Powered by NodeBB Forums | Contributors