Category: Blog

  • time-taken-to

    time-taken-to

    A simple idea I came up with while working on something else. Seemed like a fun mini-project, so decided to package it xD

    ttt-demo

    Installation

    npm i -g time-taken-to
    

    This installs the binary to PATH after which it can be accessed either using time-taken-to or ttt.

    Alternatively, can be run using npx without local installation.

    Usage

    ⚠️ If your command is interactive (requires runtime input), time-taken-to will stall and not do anything. This case is currently not handled and will be fixed in a later patch.
    🟢 Hence if interactive, hard-code your command.

    time-taken-to [OPTIONS] <your_command>
    

    Measures the time taken to execute <your_command>.

    ttt [OPTIONS] <your_command>
    

    Also does the same thing.

    Using npx,

    npx time-taken-to <your_command>
    

    <your_command> must be specified as a string if it consists of more than one word.

    $ ttt "ls -s"
    

    is different from

    $ ttt ls -s
    

    Options

    The various available options can be viewed by running

    ttt -h
    
    • --round-to or -r – Rounds off the result to the number of digits provided as argument. The default value is 6.
    • --show-stdou or -s – If specified, ttt also displays the stdout produced by the command.
    • --iterations or -i – Runs the command for the specified number of times and returns the average for a more accurate result. Default is 1.
    • --version or -v – Displays current version of time-taken-to.
    • --help or -h – Displays the help page.
    Visit original content creator repository https://github.com/jun6000/time-taken-to
  • LockIt

    LockIt

    Digital Well-being in Android TV for your kids, (wirelessly) managed!

    Left: WiLock Remote Control App
    Right: LockIt (this app)

    Note: The app cannot be run in emulators, since local service discovery/registration is not supported

    Phone Remote Locker app (WiLock) is available here

    Android-TV + Phone: Application which locks down selected apps for a child, which can only be unlocked from a Parent’s device.

    Phone (Redevelopment TODO): Application which sets a timer, within which the child is allowed to use a restricted set of Apps

    … Why?

    With the day-to-day work by parents, it becomes a difficulty to manage their child’s device usage. When given a device with the child assuring “I’ll play for 5 mins plsplspls”, it usually doesn’t happen that way, and the child ends up using for hours :laugh:.

    Now, coming to Android TVs, popular App Lock solutions require to enter a PIN in the big picture. Let’s not underestimate a child’s image processing abilities to pick up the PIN.

    Features

    • Android TV + Phone: Remotely Lock/Unlock Android TV device. No requirement to enter PIN in the TV.

    • Phone: Decide the time within which child can use restricted apps. Phone Locks once time’s over.

    Issues / TODO

    • Let’s face the truth: Kids are intelligent enough to remove the app (Android TV doesn’t have Device Administrator Service, so we’re vulnerable to uninstallation)

      • PackageInstaller is blocked now, gotta make it operable (to allow user to uninstall if insisted)
    • Issue when the remote locker device is lost OR the the remote locker app is uninstalled

      • How to get back in the system? Something to think on
    • Authentication

    • [FEATURE] TV App listing in the remote control phone itself. It would remove need of a frontend for TV, we can just package the server, and a minimal UI to provide info and get things started.

    • Manage Disconnection Failures

    • See if LockService advertising forever can be tackled Current implementation works only when device is awake. Still, can look out for some more reduction.
      Well, a TV is always awake 🤷…

    • Big TODO: Use Bluetooth/WiFi P2P based communication. Can eliminate the “overkill” requirement of a hosted function. – Suggestions are welcome for this. The issue is that neither of this communication methods can be kicked off in the background, easily.

    Issue details:

    • Moved to Google Nearby Connections API

    Pairing takes considerable time (5 seconds), is juice consuming, and is unreliable (connectivity time changes randomly)

    • Moved to Android NsdManager (for discovery of service) + TCP Sockets (for Server)

    NsdManager’s interaction with mdns android daemon works very well (Device Logs and Wireshark Capture Logs say so). But the app isn’t informed about any such events at all.

    • Moved to Rx2DNSSD + TCP Sockets (Server)

    Interaction with mdnsd works, App’s informed about it, Discovery and Connection takes a few ms! Safe to say we’ve reached the peak.

    • Manage Permissions Not required in current implementation

    • Prevent Multiple instances of LockActivity to open up (this was an issue with FCM, when a burst of messages were sent to the device)

    Working

    Android TV (Locked Device) + Phone (Key):

    Fresh Start:

    1. (Fresh Start) TV and Phone must connect with each other for the first time. Connections to the TV are open until the remote client connects to it.
    2. Connections hereon will be made directly with the UUID known to the device pair

    After Fresh Start:

    1. Lock can either be started manually in the TV App OR can be done directly from the phone
    2. Restricted set of apps will be accessible to the child
    3. Parent can unlock the TV device from their phone, with Biometric ID before every Lock/Unlock transaction

    Phone (Redevelopment TODO, not present rn):

    1. Upon Locking, selected apps won’t open up.
    2. Above two restrictions are applied for a given time limit by the parent
    3. On crossing the time limit, the Phone is Locked (Sent to Lockscreen)

    LICENSE

    Project uses the MIT License, you can obtain it at LICENSE

    Visit original content creator repository https://github.com/a7r3/LockIt
  • eva

    heroimg.png

    eva

    simple calculator REPL, similar to bc(1), with syntax highlighting and persistent history

    eva.png

    installation

    • Homebrew
    $ brew install eva
    • crates.io
    $ cargo install eva
    • manual
    $ git clone https://github.com/nerdypepper/eva
    $ cd eva
    $ cargo run

    usage

    eva 0.3.1
    NerdyPepper <akshayoppiliappan@gmail.com>
    Calculator REPL similar to bc(1)
    
    USAGE:
        eva [OPTIONS] [INPUT]
    
    ARGS:
        <INPUT>    Optional expression string to run eva in command mode
    
    OPTIONS:
        -b, --base <RADIX>    Radix of calculation output (1 - 36) [default: 10]
        -f, --fix <FIX>       Number of decimal places in output (1 - 64) [default: 10]
        -h, --help            Print help information
        -r, --radian          Use radian mode
        -V, --version         Print version information
    

    type out an expression and hit enter, repeat.

    > 1 + sin(30)
    1.5
    > floor(sqrt(3^2 + 5^2))
    5
    > 5sin(45) + cos(0)
    4.53553

    updating

    • crates.io
    $ cargo install eva --force
    • manual
    $ cargo install --force --path /path/to/eva

    operators

    • binary operators: + - * / ^ **
    • unary operators: + -

    constants

    some constants available in rust standard library.

    e      pi
    

    examples:

    pi * 5^2  # πr²
    

    functions

    all trigonometric functions expect input in degrees.

    1 argument:
    sin    cos     tan    csc    sec    cot    sinh   cosh   tanh
    asin   acos    atan   acsc   asec   acot   ln     log2   log10
    sqrt   ceil    floor  abs
    
    2 arguments:
    log    nroot
    
    deg(x) - convert x to degrees
    rad(x) - convert x to radians
    

    examples:

    sqrt(sin(30)) # parentheses are mandatory for functions
    
    log10100      # no
    log10(100)    # yes
    
    log(1, 10)    # function with two arguments
    

    quality of life features

    • auto insertion of * operator
    >12sin(45(2))             # 12 * sin(45 * (2))
    12
    
    • auto balancing of parentheses
    >ceil(sqrt(3^2 + 5^2      # ceil(sqrt(3^2 + 5^2))
    6
    
    • use previous answer with _
    > sin(pi)
    0.0548036650
    > _^2
    0.0030034417
    >
    
    • super neat error handling
    > 1 + ln(-1)
    Domain Error: Out of bounds!
    
    • syntax highlighting

    todo

    • add support for variables (pi, e, _ (previous answer))
    • syntax highlighting
    • multiple arg functions
    • screenshots
    • create logo
    • unary operators (minus, plus)
    • add detailed error handler
    • add unit tests
    • lineditor with syntax highlighting
    • add more functions

    contributors

    the rust community has helped eva come a long way, but these devs deserve a special mention for their contributions:

    Ivan Tham
    Milan Marković
    asapokl

    Visit original content creator repository https://github.com/oppiliappan/eva
  • WebToolBox

    Web Toolbox

    Web Toolbox is a deadsimple web app that is meant to provide an easy way for users to convert different types of data into different formats in order to ease stress about finding a tool online they could use. Since it just uses vanilla HTML, CSS and Javascript, it can be easily extended to support new and different type of conversions.

    🧐 Features

    • Fully responsive
    • Supports PWA installation
    • Easily etendable
    • Simple and intuitive workflow
    • Lightning fast browsing speeds thanks to prefetching

    🛠️ Installation Steps

    1. Clone the repository
    git clone https://github.com/callowaysutton/WebToolBox.git
    1. Change the working directory
    cd WebToolBox
    1. Install dependencies
    npm install
    1. Run the app
    npm run dev
    1. You can also export as a static site to the __sapper__/export directory
    npm run export

    🌟 You are all set!

    🍰 Contributing

    DeepSource

    Navigate to the file /src/routes/tools/_tools.js and open that up inside of a new Webstorm tab. Using this template:

    {
            title: 'Example Title',
            slug: 'theURL-cannothavespaces',
            description: 'Example Description',
            html: `
              <html>
                <head>
                  <script>
                    
                  </script>
                  <style>
                  
                  </style>
                </head>
                <body>
                  
                </body>
              </html>
            `
        },

    Copy and paste that to the top of the array and use that as your starting point for creating your converter. Afterwards, use simple HTML, CSS and Javascript to finish creating your page and make a Pull Request on Github where me, and possibly others, can review the code, add suggestion and eventually push it through into production.

    Please contribute using GitHub Flow. Create a branch, add commits, and open a pull request.

    Please read CONTRIBUTING for details on our CODE OF CONDUCT, and the process for submitting pull requests to us.

    PWA and Extra Features

    This website is almost 100% PWA ready and is almost ready to be shipped to the Progressive Web App Store, however I’m running into some issues with the cache not working after you close the app, which means no offline access, and help would be very much appreciated.

    The web app also should be mostly mobile friendly, however I do not have any modern day devices to test out how it performs and looks on real hardware.

    TODO

    • Dark Mode
    • Fully Offline PWA
      • PWA Support
    • Switching from Webpack to Rollup
    • Make Example Converters
    Visit original content creator repository https://github.com/callowaysutton/WebToolBox
  • Nonsense

    Nonsense

    Nonsense is an esoteric programming language (or esolang) where pretty much any English sentence you could concoct is a valid program. The catch is, though, that most “useful” programs are usually nonsensical jumbles of words rather than coherent sentences. For example, here’s “Hello world!”:

    72 ey 100 envoy nab 108 eyry em 111 entry 32 ey eon 87 ey try 114 ey my by nay

    While reminiscent of a monkey picking words from a dictionary, Nonsense has some nice structure built around the phonetics and syntax of English itself. And, unlike some other languages which utilize English letters for commands, all Nonsense commands must be valid English words (or numbers or punctuation) where case does not matter, with the structure of word itself being critical (rather than just the order of the letters). It’s also Turing-complete since any BrainFuck program can be translated to Nonsense (see bf_convert.py).

    Nonsense interprets words by splitting them into syllables, each containing consonants and vowels (where y is a vowel). Consonants correspond to variables, while vowels correspond to instructions. Integers (or chars; see interpreter.py) can be stored in consonant variables as well as the array (denoted S here), an arbitrarily long list of integers (initialized to zeroes) which is accessed by indexing (see the section on the letter e below). The zeroth entry in the array is called result, and is always updated with the value of the most recent command (think of it like Ans in TI-Basic).

    To run Nonsense programs for yourself, simply download interpreter.py and the associated words_dictionary.json file into the same directory; the dictionary file is used to check that all words are valid English words, and is actually quite lenient for what does count as word. Run interpreter.py with your program (or as it is called, a paragraph) as the first argument. The interpreter will display any output and ask for any inputs during execution (these are prompted by a single :).

    To aid debugging, a paragraph can be executed via interpreter.py with the -i or --inspect flag, which will display the current state of all consonants, the array, and the stack after each instruction execution. Note that the array is not enlarged until necessary, and only nonzero consonants are displayed.

    Syllables

    Words are decomposed into syllables which have consonants at either endpoint and vowels in-between. For example, the word candid is split into can, nd, and did; notice how syllables overlap at their endpoints. Each syllable is a single instruction, with the beginning consonant corresponding to a stored value (called the operand) and the ending consonant corresponding to a destination (called the location); the vowels in between are the instructions themselves, and can be compounded via diphthongs.

    All words and syllables in Nonsense must start and end with a consonant, though, so when no constant begins or ends a syllable the interpreter creates the “invisible” consonant 0, a null value. When being accessed 0 always returns zero, while as a destination 0 corresponds to result.

    Consonants

    Consonants are easy. There are precisely twenty of them, b, c, d, ..., x, z, and each one can hold an integer value (all initialized to zero). A consonant in a word is either a retrieval of that consonant’s value (when at the beginning of a syllable, as the operand) or a specification of the destination of a result (when at the end of a syllable, as the location).

    Vowels

    These are the fun ones. Each vowel is a unique operation (either unary or binary), and some have some odd but useful edge cases when they begin or end syllables, or combine into diphthongs.

    _: STORE

    The STORE command is invoked whenever a syllable is composed of just consonants, and simply stores the operand at location.

    • nd : n->d
    • str : s->t; t->r
    • g : g (place g in result)

    a: ADD

    The ADD command is pretty straightforward; take the operand, add it to the value at location, and store it back at location. You can effectively replace any a with a “+” sign (in fact that is more-or-less what the interpreter does).

    • ban : b+n->n
    • band : b+n->n; n->d
    • baa : b+0 (the second a has no additional effect)
    • act : 0+c->c; c->t

    e: INDEX

    The INDEX command accesses the array either by designating the operand as the index at which to pull from the array for an instruction, or specifying that the location is actually an array entry (rather than a consonant variable).

    • bet : S[b]->t
    • beet : S[S[b]]->t
    • err : S[0]->r; r->r (due to the implicit 0)
    • cane : c+S[n]->S[n]; S[n] (here, the syllable must look ahead a letter to see if the location is an array entry, and always does)
    • aerate : S[0]+r->r; r+S[t]->S[t] (indexing “passes through” other vowels; ae behaves identically to ea)

    i: MINUS

    The MINUS command is precisely what you think it is: the inverse operation of ADD. Again, you could replace any i with a “-” sign and be totally correct.

    • wig : w-g->g
    • wing : w-n->n; n->g
    • skiing : s->k; k+n->n; n->g (since “–” makes a “+”)
    • ice : -S[c]->S[c] (easy negation!)
    • braid : b->r; r-d->d (since “+-” makes a “-“, as would “-+”)
    • icicle : -c->c; c-c->c; c->S[l] (easy zeroing!)

    o: ONE

    ONE is one. Just like, the number one. What more do you need?
    But seriously, the ONE command will increment (or decrement, if subtracting) the operand by one and store it to the location. If a syllable ends with the implicit 0, in addition to storing to result, the ONE command does in-place increment/decrement.

    • row : r+1->w
    • roe : S[r]+1->S[r]
    • road : r+1->d (did you expect it to be different?)
    • avoid : 0+v->v; v-1->d
    • oat : 0+1->t (easy 1-ing!?)
    • toon : t+2->n (1+1=2)
    • moo : m+2->m

    u: NULL

    The NULL command is a bit unique, and is mostly a construct to make writing Nonsense programs easier. Basically, any letters following a u in a word (including the u itself) are struck from the word, as if they didn’t exist; the rules for adding implicit 0‘s still follow. This implement helps in ensuring commands are valid English words, even when certain consonant combinations are difficult to produce.

    • gruff : g->r
    • bus: b
    • undo : (literally nothing)
    • bleu : b->S[l]
    • caribou : c+r->r; r-b->b; b+1->b

    y: I/O

    The I/O command is for inputting integers and outputting text in a program. When at the start of a syllable, y calls for input from the user; all other instances output the result as an ASCII character.

    • my : print m
    • yam : input()+m->m
    • yes : S[input()]->s
    • you : input()+1
    • cyan : c+n->n; print n (note that printing always occurs after syllable execution using result)
    • syzygy : s->z; print z; z->g; print g; print g
    • oyster : 0+1->s; print S[0]; s->S[t]; S[t]->r

    Some Big Ol’ Words, Parsed

    • invalidation : -n->n; n->v; v+l->l; l-d->d; d+t->t; t-1->n
    • beautiful : S[b]
    • elementary : S[0]->S[l]; S[l]->S[m]; S[m]->n; n->t; t+r->r; print r
    • onomatopoeia : 1+n->n; n+1->m; m+t->t; t+1->p; S[p-1]
    • spaghetti : s->p; p+g->g; g->S[h]; S[h]->t
    • liaison : l+s->s; s+1->n

    Punctuation

    Punctuation marks are used to construct simple loops and conditionals within a Nonsense paragraph. The four valid punctuation marks are the comma (,), question mark (?), period (.), and exclamation point (!). It is intended that they are written into a paragraph akin to usual English punctuation, being directly adjacent to a word and followed by whitespace.

    • , : Start of a while loop, which uses result as the loop condition; a result of zero will skip to the corresponding period.
    • ? : Start of an if conditional, again using result; a result of zero will skip to the corresponding period.
    • . : End of a while loop or if conditional; the interpreter will always return to the corresponding , or ? upon arrival.
    • ! : Break conditional, again using result; a nonzero result instantly terminates the program.

    Numbers

    Numbers can be used to insert direct values into result, so that incrementing a variable a hundred times can be done in one syllable. When a number appears in a Nonsense paragraph, it must appear without any letters adjacent to it.

    Visit original content creator repository
    https://github.com/kg583/Nonsense

  • ProjectorController9000

    ProjectorController9000

    The objective of this experiment is to discard the laborious task of manually turning on/off a projector when delivering presentations on a Raspberry Pi. The approach undertaken to automate this is to catch HDMI connect/disconnect events and send appropriate signals to the projector through an IR Transmitter.

    (Done as a part of VL 855 – Device Driver Development coursework at IIIT-B)

    Preparation

    • Installed LIRC packages on Raspbian Buster with kernel 4.19.75-v7+ with a patch [1].

    • Issued IR Emitter (IR333-A) and GPIO Utility Board with IR Receiver (TSOP1738).

    • Revised slides: part08-udev, part16-pin, part17-dts, part18-libgpio, part21-lirc.

    Procedure and Test Cases

    • Setup the IR Transmitter circuit; with a 5V source (in my case its from the RaspberryPi itself), a 400ohm resistor, a NPN transistor and an IR emitter (detailed schematic is given in LIRC section).

    • Connect the RaspberryPi to a power source (in my case its a laptop) with the loaded modules (‘ssh’ with Ethernet cable could be used for debugging) and ensure the initial state of the whole setup is that the projector is ON and the HDMI cable is connected.

    • Ensure the IR emitter is directed towards the projector and there’s no obstruction in-between.

    • The expected output is that once we disconnect the HDMI connector for the RaspberryPi, the IR emitter sends a POWER_OFF signal (can be seen through a phone camera with no IR-filter) and the projector turns off after 3-4 secs (depends on polling frequency) of the disconnect event. In the case of plugging in the HDMI connector when the projector is OFF (red light), the IR emitter should send POWER_ON signal and the projector should turn on in 3-4 secs.

    Experiments and Analysis

    GPIO

    “GPIO is half-baked hardware” – with this statement in my head, I set out to discover how one can setup functions for a GPIO cell to act like an IR receiver and a transmitter. I figured de-compiling the device-tree (which is currently being used by the kernel) to check for overlays that have defined the GPIO pin numbers for IR-rx and IR-tx could be a valid approach.

    $ sudo dtc -I fs /sys/firmware/devicetree/base -O dts -o loaded\_device\_tree.dts saved my de-compiled device-tree in ‘loaded_device_tree.dts’. There I looked for ir-rx and ir-tx which gave me:

    ir-receiver@11 in loaded_device_tree.dts

    gpio-ir-transmitter@12 in loaded_device_tree.dts

    Here, we can see that receiver is to be connected to GPIO 17 (0x11) and emitter at GPIO 18 (0x12). The same information is available in /boot/overlay/README (under gpio-ir and gpio-ir-tx). Although to enable infrared communication and for the overlay to take reflect in the device-tree, one had to uncomment a few lines in /boot/config.txt (and then reboot for the new device-tree to be picked up by the kernel) as shown here:

    After uncommenting; to enable infrared communication.

    I also examined the description of the device-tree bindings [2] [3] for more clarity on how the IR rx and tx works before proceeding with the practical experiments.

    LIRC

    I, first, set up the initial circuitry composed of only the IR rx to decode the 38KHz infrared signals from the CASIO projector’s remote using lircd daemon. I noticed the device special file created by LIRC driver: /dev/lirc0 (Tx) and /dev/lirc1 (Rx) were exposed in devfs, as discussed in the class. To see the receive raw (pulse-space) codes from the remote, I used the command line utility provided by LIRC: mode2. Although, that didn’t work as expected even after numerous tries and re-reading the man pages. The output I was getting were decoded keycodes which were also different everytime even for the same button press, as shown here:

    mode2 with erroneous output.

    This diverted my attention towards other utilities provided by LIRC; irrecord, after it directed me to a database of remotes with their corresponding keycodes [4] to an unfruitful search, also proved to be erroneous because after recording KEY_POWER for the CASIO projector’s remote, my keycode didn’t match with my colleagues’ keycodes for the same button! This threw me off to use ir-ctl which after reading the man pages revealed that it could be used to do both rx and tx but with raw IR codes! So, the lircd daemon was no use in this case since I didn’t have to decode.

    $ ir-ctl -1 - -receive=KEY\_POWER.txt -d/dev/lirc1 was used to receive the raw codes of the POWER button and save it in the KEY_POWER.txt file.
    After this, testing of the rx part was done successfully. Before delving into the circuitry of the tx part, I was warned by my colleague Shivam to use a transistor to amplify the current supplied to the IR emitter such that its able to send the infrared signals to the projector with high-enough amplitude. Keeping this in mind the schematic of the circuit is given below:

    Circuit schematic (made using https://www.circuit-diagram.org/

    $ ir-ctl - -send=KEY\_POWER.txt -d /dev/lirc0 was used to emit the raw codes of the POWER button saved in the key_power.txt file. This completes my testing of tx part as well. Now, I just had to devise a solution to the question “When do I send the POWER signal to the projector?”

    Mailbox

    Unaware of the presence of Broadcom VideoCore VI processor on my Raspberry Pi Model 2B which handles the detection of HDMI instead of the ARM Cortex-A7 processor, I hypothesised that the HDMI event detection mechanism incorporated by my HP Pavilion 15 laptop should be the same in case of the Raspberry Pi. With this assumption, I carried out some unnecessary but enlightening experiments involving the ‘drm’ subsystem. It had a device in sysfs named under card0-HDMI-A-1 which had exposed attributes on the state of HDMI connection, device-specific information in EDID (Extended Display Identification Data) [5] format, etc (see figure below).

    Attributes of device under drm subsystem.

    This gave me an illusion on the complexity of the project in Raspberry Pi. This illusion was erased once I re-read the problem statement and discovered the absence of the ‘drm’ subsystem in RaspberryPi. But, borrowing ideas from the above experiment, I used the EDID format to detect the presence of an HDMI connect/disconnect event which I shall discuss in the report later.

    Mentioned in the hints, I turned my attention towards using ‘tvservice’ and investigated how it uses Mailbox, an inter-processor communication mechanism between the ARM core and the VideoCore, to detect the state of HDMI connection when one uses the command-line utility: $ tvservice -s or $ tvservice -M. Upon reading the source code [6], I stumbled upon the different values (bitmask) the state can take. This proved to be useful in deciphering what the state code meant when one executed $ tvservice -s. Although, I wasn’t able to trace how ‘tvservice’ uses the Mailbox channels for the communication. Surfing through the ‘userland’ repository, I found the source code for ‘vcmailbox’ [7] utility. This had evident traces of how it uses the Mailbox1 (ARM to VC) to send request on channel 8 (search for MBOX_CHAN_PROPERTY) with property tags and how the response is received on Mailbox0 (VC to ARM) in the same buffer, which is in sync with the documentation [8]. I even tried out a few examples by using the command-line utility $ /opt/vc/bin/vcmailbox \[words\] and tried to exercise the same code as this [9]. This was too tedious when I tried to request EDID blocks with the property ‘Get EDID Block’ as mentioned here [10] as I got confused on request format. This is when my colleague Vijay suggested me to use Mailbox utility from kernel-modules [11]! This seemed like a more reasonable approach as this would be a kernel-space-based solution rather than a user-space one, where one would ideally just write a ‘bash’ script to continuously poll over tvservice’s utility.

    Tracing the source code [12] [13] [14], the whole communication interface between ARM and VC was much clearer. All I had to do now was write a miscellaneous device module which exposes an attribute called ‘status’ which, when read, sends a ‘Get EDID Block’ request to VC over the mailbox channel and with some further logic (discussed later) tells us if HDMI is connected or not. I used this approach (of exposing an attribute) for testing purposes and I soon realised how an ‘uevent’ mechanism would be much structured in this case.

    uevents

    On my colleague Mohana’s recommendation, I decided to look through the source code for how one can generate ‘uevents’ from kernel modules [15]. I devised a mechanism which generates a ‘uevent’ with CHANGE action and under a defined “myHDMI” subsystem whenever there is a change in state of HDMI connection; disconnected to connected and connected to disconnected. A corresponding .rules file was implemented which executes my previous findings on matching with my generated ‘uevent’; sending a POWER infrared signal using ir-ctl.

    hdmi_dev.c – Misc Device

    Inspired by goonj.c and blinker.c, I wrote a misc_device module which sets up a timer to send a ‘Get EDID Block’ request (with workqueues because the requests are not atomic due to presence of locks [16]) to VC through a mailbox channel at a pre-defined rate and detects state change to generate an ‘uevent’ with some internal logic. The logic is that, when no HDMI device is connected, the reponse by VC should not contain any information to my request of ‘Get EDID Block’ and when some HDMI device is connected, I get some device-related data. I encountered a few errors involving devices which can send multiple blocks of data in the request but those were cleared after a thorough read of the EDID v1.3 (bytes 18 and 19 tell the EDID version) specification issued by VESA [17] [18] which said that the 127th byte tells us about the remaining extension blocks to come. Once I received all the EDID extensions correctly, I used edidparser to make sense of the received data which reflected the flawlessly execution of my module.

    HPD in HDMI

    The above approach of using a mailbox channel become obsolete when I discovered that GPIO 46 is connected to pin 19 (Hot Plug Detect) of the HDMI connector [19] in Raspberry Pi Model 2B. I even traced the lines in the schematic (page 2) [20] just to confirm! Upon learning more on about the detection process [21], it made a lot of sense for me to take this approach rather than the EDID one because it’s much more “cleaner” and that pin must be solely meant to do HDMI detection. With this, I updated my hdmi_dev-w-edid.c to hdmi_dev-w-gpio.c which uses the get\_gpio\_value() framework to read the level of GPIO 46. The other logic remains the same. Note: It’s not necessary to use workqueues in this case although it made sense for me that a separate kernel-thread does the polling for me rather than the kernel module itself.

    Modes in CASIO projectors

    After numerous experiments, Mohana and I realised that the projector stays in STANDBY mode when the RED light is displayed. At this state, even if the HDMI connector is plugged in, it’s not plausible to detect if it has been plugged in (we are assuming the power is not let through the connector). In response to this, I believe it’s not possible to switch ON the projector when HDMI cable is plugged in; it must already be in state ON for it to detect the connection. This behaviour is not seen in cases of Monitors. I even explored other options apart from POWER signal like BLANK signal (puts the projector in low-power mode by switching off the display) but then I realised I was diverting away from the original problem statement.

    Conclusion

    The output matched the expectation in the case of HDMI disconnect event but not for the HDMI connect event because it does not seem possible to know if the HDMI is connected when the CASIO projector is OFF. Although, when the projector is ON and we plug in the HDMI connector, we can detect it. Below is the output:\

    HDMI connect event; no uevent generated

    HDMI disconnect event; appropriate uevent generated

    This project educated me on how to look through source code to interpret the author’s intentions. It also enabled me to question my design choices through-out the process for example: kernel-space-based solution vs. user-space-based solution, misc_device vs. platform_device, the polling time, etc.

    References

    [1] RaspberryPi.org-Forums, “[stretch/buster] using lirc with kernel 4.19.x and gpio-ir.” [Online].Available: https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=235256

    [2] SeanYoung, “gpio-ir-tx.txt.” [Online]. Available:https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/leds/irled/gpio-ir-tx.txt

    [3] SeanYoung., “pwm-ir-tx.txt.” [Online]. Available:https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/leds/irled/pwm-ir-tx.txt

    [4] irrecord-remotes database, “lirc-remotes.” [Online]. Available:https://sourceforge.net/p/lirc-remotes/code/ci/master/tree/remotes/

    [5] Wikipedia, “Edid.” [Online]. Available:https://en.wikipedia.org/wiki/ExtendedDisplayIdentificationData

    [6] RaspberryPi-userland, “tvservice.c.” [Online].
    Available:https://github.com/raspberrypi/userland/blob/master/hostapplications/linux/apps/tvservice/tvservice.c

    [7] RaspberryPi-userland., “vcmailbox.c.” [Online]. Available: https://github.com/raspberrypi/userland/blob/master/hostapplications/linux/apps/vcmailbox/vcmailbox.c

    [8] R. firmware wiki, “Mailboxes wiki.” [Online]. Available: https://github.com/raspberrypi/firmware/wiki/Mailboxes

    [9] AndrewFromMelbourne, “serialnummailbox.c.” [Online]. Available:https://github.com/AndrewFromMelbourne/raspiserialnumber/blob/master/serialnumbermailbox.c

    [10] R. firmware wiki, “Mailbox property interface – edid.” [Online]. Available:https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#get-edid-block

    [11] RaspberryPi-documentation,“Mailboxusage.”[Online].Available:https://github.com/raspberrypi/documentation/tree/JamesH65-mailboxdocs/configuration/mailboxes#using-the-mailboxes-from-kernel-modules

    [12] elixir bootlin, “mailbox-controller.h.” [Online]. Available: https://elixir.bootlin.com/linux/latest/source/include/linux/mailboxcontroller.h#L117

    [13] elixir bootlin., “raspberrypi.c.” [Online]. Available: https://elixir.bootlin.com/linux/latest/source/drivers/firmware/raspberrypi.c#L145

    [14] elixir bootlin, “mailbox.c.” [Online]. Available: https://elixir.bootlin.com/linux/latest/source/drivers/mailbox/mailbox.c#L53

    [15] ——, “kobjectuevent.c.” [Online]. Available: https://elixir.bootlin.com/linux/latest/source/lib/kobjectuevent.c#L456

    [16] Cesati and Bovet, “Ldd-3-workqueues.” [Online]. Available: https://www.oreilly.com/library/view/understanding-the-linux/0596005652/ch04s08.html

    [17] VESA, “Edid standard.” [Online]. Available:http://read.pudn.com/downloads110/ebook/456020/E-EDID%20Standard.pdf

    [18] Miseli, “Xorg – edid.” [Online]. Available: https://www.x.org/wiki/Events/XDC2007/Notes/Xorg2007-EDID-JMiseli.pdf

    [19] RaspberryPi-Forum, “Detecting if hdmi is present.” [Online]. Available:https://www.raspberrypi.org/forums/viewtopic.php?t=18292#p933055

    [20] RaspberryPi, “Schematic raspi 2b.” [Online]. Available: https://www.raspberrypi.org/app/uploads/2012/04/Raspberry-Pi-Schematics-R1.0.pdf

    [21] datapro.net, “Hpd, ddc and edid.” [Online]. Available: https://www.datapro.net/techinfo/hotplugdetection.html10

    Visit original content creator repository https://github.com/layman-n-ish/ProjectorController9000
  • anran758.github.io

    anran758’s Homepage

    Travis (.com) Commitizen friendly GitHub

    web example website.

    TDDO

    • Mock Browser component
    • 支持配置路由

    交互优化

    • [Skeleton] list
    • [Skeleton] images
    • error handle
    • empty handle

    ✨ Feature

    • Mock Browser 支持基础的 URL 输入和 reload Demo page 的功能

    start

    # 开发模式
    npm run start
    
    # 生产打包
    npm run start
    
    # 校验 TypeScript 是否符合规范
    npm run lint:ts
    
    # 编译 TypeScript 为 js
    npm run tsc
    
    # 打开 commit 推荐信息,通过指示来提交 commit
    npm run cz

    commit

    commit 结构 (注意换行):

    <type>[optional scope]: [emoji]<description>
    
    [optional body]
    
    [optional footer(s)]
    
    • type: 本次 commit 类型
    • optional scope: 可选的改动范围
    • description: 本次 commit 简短的描述
    • emoji: 约定的 emoji

    以下是各类型的含义,还可以增加可选的 emoji 增强语义:

    feat

    新增功能。

    • 🎉 初次提交
    • ✨ 引入新功能

    fix

    修复 bug。

    • 🐛 修复 bug
    • 🚑 修复紧急 bug
    • 🍎 修复 MacOS 上的问题
    • 🐧 修复 Linux 上的问题
    • 🏁 修复 Windows 上的问题
    • 🤖 解决 AndroidOS 上的问题
    • 🍏 解决 ios 上的问题

    perf

    本次的代码修改可提升性能。

    • ⚡ 提升页面性能
    • 🚸 改善用户体验/可用性
    • ♿ 改善无障碍

    docs

    仅修改文档类。

    • 📝 编写文档
    • 📄 添加或更新 License

    style

    样式不会影响代码含义的更改。

    • 🎨 改进代码的结构 / 格式 / 分号补全等
    • ✏️ 修改文案,错别字等文字相关的工作

    refactor

    既不修复错误也不增加功能的代码更改。

    • ♻️ 代码重构
    • 📈 添加分析或埋点代码等

    build

    影响构建系统或外部依赖项的更改。例如 webpacknpmnginx 等。

    • 🔧 更改配置文件
    • 📦 更新构建相关的逻辑

    test

    添加或修改测试内容。

    chore

    不会涉及到 src 或测试文件的更改。比如修改 .gitignore,package.jsonyarn.json 等文件。

    • 📌 将依赖关系固定到特定的版本
    • ➕ 添加依赖项
    • ➖ 移除依赖项
    • ⬆️ 升级依赖
    • ⬇️ 降级依赖

    ci

    对 CI 配置文件和脚本的更改。

    • 👷 添加 CI 构建系统
    • 💚 修复 CI 构建
    • 🐳 处理 docker 相关的工作

    revert

    ⏪ 回退旧版本

    commit example

    feat(html): HTML 模板新增 favicon
    fix: 纠正代码中的错别字
    
    有关已修正错字的详细信息,请参见 issue
    
    closes issue #12
    style: :pencil2:修改文案错别字
    
    # or
    style: ✏️修改文案错别字
    build(webpack): 调整 webpack 构建方式
    ci(travis): travis-ci 添加 commitlint-travis 脚本

    更多示例参见: 约定式提交

    分支

    branch 用途
    master Github Pages 服务
    develop 触发构建的开发分支

    由于 <username>.github.io 储存库只有 master 分支才可以使用 Github Pages 服务,因此 master branch 不是 source code.

    Visit original content creator repository https://github.com/anran758/anran758.github.io
  • pilihdhewe-apps-laravel

    Voting Application Project

    Welcome to the Voting Application Project repository! This repository contains all the information and code you need to understand, contribute to, and develop an innovative voting application using Laravel and React JS. This application is designed to facilitate efficient and secure voting processes, providing a seamless experience for users.

    About the Project

    The Voting Application Project is our endeavor to develop a modern solution for conducting voting. By harnessing the power of the Laravel and React JS frameworks, along with other advanced features, this application aims to address challenges in traditional voting systems. Utilizing cutting-edge technology, we aim to ensure vote integrity and enhance participation in the democratic process.

    Key Features

    • Online Voting: Enables voters to cast their votes online, saving time and effort.
    • Ensured Security: Incorporates a robust security system to protect voter data and prevent vote manipulation.
    • Intuitive Interface: Built with React JS, providing a user-friendly interface that caters to users from various backgrounds.
    • Real-time Monitoring: Monitors real-time voting results and generates accurate statistical reports.

    Tech Stack

    • Frontend: React JS 18.2.0
    • Backend: Laravel 9 (PHP 8.1.2)
    • Database: MySQL
    • Styling : Tailwind CSS, HeadlessUI, Heroicons, Bootstrap Icons

    How to Contribute

    • We highly value contributions from all parties. If you wish to contribute to the development of the Voting Application Project, follow these steps:
    • Fork the Repository: Begin by forking this repository.
    • Clone the Repository: Clone the forked repository to your local machine.
    • Create a Branch: Before making any changes, create a new branch with a clear description of the changes you intend to make.
    • Make Changes: Implement changes and enhancements aligned with your goals, using Laravel and React JS technologies.
    • Testing: Thoroughly test all your changes to ensure they do not disrupt overall functionality.
    • Create a Pull Request: Submit a pull request with detailed information about the changes you’ve made and their purpose.

    We hope that this application will be a valuable contribution in advancing the democratic process and facilitating better voting experiences. If you have questions, suggestions, or wish to participate, feel free to raise issues or submit pull requests. Thank you for joining us in this project!

    — Pilih Dhewe Team

    Visit original content creator repository
    https://github.com/dendik-creation/pilihdhewe-apps-laravel

  • nlp-chatbot

    nlp-chatbot

    Stack Overflow Assistant Telegram Chatbot, based on templates from Potapenko et al, HSE, Russia.

    Accessing the bot:

    Simply go to t.me/prannerta100_bot and start chatting!

    The bot has been hosted on a Google Cloud VM, so you might face some server-side latency.

    Here is a sample conversation with the bot:

    Bot image

    Dependencies:

    1. nltk
    2. chatterbot corpus
    3. sklearn

    Description:

    Here is how the bot works:

    1. read the message, use a classifier to classify its intent as non-programming or programming
    2. If non-programming, then invoke a pre-trained, off-the-shelf chatbot (here I used Ron Obvious from the chatterbot module)
    3. If programming, then show the relevant Stack Overflow link that matches the question description the best

    Training data:

    • The first classifier (programming versus non-programming) was trained by mixing 2 datasets:
    1. tagged_posts.tsv — StackOverflow posts, tagged with one programming language (positive samples).
    2. dialogues.tsv — dialogue phrases from movie subtitles (negative samples).
    • The second classifier (given a programming question, find the relevant Stack Overflow link) works by finding the closest StarSpace embedding.

    Relevant files:

    • The most relevant file here is nlp-chatbot/nlp-chatbot-main/dialogue_manager.py. The entered question is transformed into a TF-IDF feature vector. A model is trained to identify the most relevant question and tag.

    Send feedback to prannerta100@gmail.com.

    Visit original content creator repository https://github.com/prannerta100/nlp-chatbot
  • registration-bot

    Bogazici University Registration Bot

    DISCLAIMER: This software is for educational purposes only. Your account might be suspended because of script usage. USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHORS ASSUME NO RESPONSIBILITY FOR RESULTS.

    Registration Bot

    Requirements

    NOTE: It works with the old registration system, I didn’t try it with new BUIS system. But BUIS pages are similar to old registration pages, I think it needs small changes.

    Usage

    from registration import Registration
    
    # Create instance
    reg = Registration(STUDENT_ID, STUDENT_PASSWORD)
    
    # Set debug true for printing logs to console
    reg.set_debug(True)
    
    # Get quota for HUM102.01
    reg.get_quota("HUM", "102", 11)
    
    # If login your account is successful
    if reg.login():
        # Take CMPE493.01 course
        reg.take_course("CMPE", "493", 1)
        
        # Take CMPE49J.01 course non-credit
        reg.take_course("CMPE", "49J", 1, non_credit=True)
    
        # Take HTR312.01 course credit and with-repeat
        reg.take_course("HTR", "312", 11, non_credit=False, repeat_with="HTR 312 DD")
    
        # Try to change HTR312 section 11 to 14
        for section in range(11, 15):
            reg.change_section("HTR", "312", section)
    Visit original content creator repository https://github.com/enescakir/registration-bot