{"id":15294073,"url":"https://github.com/getsenic/nuimo-linux-python","last_synced_at":"2025-10-08T20:23:29.344Z","repository":{"id":53615485,"uuid":"63823854","full_name":"getsenic/nuimo-linux-python","owner":"getsenic","description":"Nuimo Python SDK for Linux to connect and communicate with Nuimo controllers made by Senic","archived":false,"fork":false,"pushed_at":"2021-03-20T18:20:42.000Z","size":101,"stargazers_count":54,"open_issues_count":6,"forks_count":23,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-09-01T07:39:23.326Z","etag":null,"topics":["bluez","linux","nuimo-sdk","python"],"latest_commit_sha":null,"homepage":"https://senic.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/getsenic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-07-21T00:30:24.000Z","updated_at":"2025-04-29T03:24:47.000Z","dependencies_parsed_at":"2022-09-02T22:11:56.664Z","dependency_job_id":null,"html_url":"https://github.com/getsenic/nuimo-linux-python","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/getsenic/nuimo-linux-python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsenic%2Fnuimo-linux-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsenic%2Fnuimo-linux-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsenic%2Fnuimo-linux-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsenic%2Fnuimo-linux-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/getsenic","download_url":"https://codeload.github.com/getsenic/nuimo-linux-python/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsenic%2Fnuimo-linux-python/sbom","scorecard":{"id":424573,"data":{"date":"2025-08-11","repo":{"name":"github.com/getsenic/nuimo-linux-python","commit":"1918e6e51ad6569eb134904e891122479fafa2d6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 2/28 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 6 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-19T01:58:07.953Z","repository_id":53615485,"created_at":"2025-08-19T01:58:07.953Z","updated_at":"2025-08-19T01:58:07.953Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000659,"owners_count":26082817,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bluez","linux","nuimo-sdk","python"],"created_at":"2024-09-30T16:57:20.044Z","updated_at":"2025-10-08T20:23:29.328Z","avatar_url":"https://github.com/getsenic.png","language":"Python","readme":"# Nuimo Python SDK\n[Nuimo](https://senic.com) is a universal smart device controller made by [Senic](https://senic.com).\n\nThe Nuimo Python SDK for Linux allows you to integrate your Nuimo(s) into any type of Linux application or script that can execute Python code.\n\n## Prerequisites\nThe Nuimo SDK requires [Python 3.4+](https://www.python.org) and a recent installation of [BlueZ](http://www.bluez.org/). It is tested to work fine with BlueZ 5.44, slightly older versions should however work, too.\n\n## Installation\nThese instructions assume a Debian-based Linux.\n\nOn Linux the [BlueZ](http://www.bluez.org/) library is necessary to access your built-in Bluetooth controller or Bluetooth USB dongle. Some Linux distributions provide a more up-to-date BlueZ package, some other distributions only install older versions that don't implement all Bluetooth features needed for this SDK. In those cases you want to either update BlueZ or build it from sources.\n\n### Updating/installing BlueZ via apt-get\n\n1. `bluetoothd --version` Obtains the version of the pre-installed BlueZ. `bluetoothd` daemon must run at startup to expose the Bluetooth API via D-Bus.\n2. `sudo apt-get install --no-install-recommends bluetooth` Installs BlueZ\n3. If the installed version is too old, proceed with next step: [Installing BlueZ from sources](#installing-bluez-from-sources)\n\n### Installing BlueZ from sources\n\nThe `bluetoothd` daemon provides BlueZ's D-Bus interfaces that is accessed by the Nuimo SDK to communicate with Nuimo Bluetooth controllers. The following commands download BlueZ 5.44 sources, built them and replace any pre-installed `bluetoothd` daemon. It's not suggested to remove any pre-installed BlueZ package as its deinstallation might remove necessary Bluetooth drivers as well.\n\n1. `sudo systemctl stop bluetooth`\n2. `sudo apt-get update`\n3. `sudo apt-get install libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev libdbus-glib-1-dev unzip`\n4. `cd`\n5. `mkdir bluez`\n6. `cd bluez`\n7. `wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.44.tar.xz`\n8. `tar xf bluez-5.44.tar.xz`\n9. `cd bluez-5.44`\n10. `./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-library`\n11. `make`\n12. `sudo make install`\n13. `sudo ln -svf /usr/libexec/bluetooth/bluetoothd /usr/sbin/`\n14. `sudo install -v -dm755 /etc/bluetooth`\n15. `sudo install -v -m644 src/main.conf /etc/bluetooth/main.conf`\n16. `sudo systemctl daemon-reload`\n17. `sudo systemctl start bluetooth`\n18. `bluetoothd --version` # should now print 5.44\n\nPlease note that some distributions might use a different directory for system deamons, apply step 13 only as needed.\n\n### Enabling your Bluetooth adapter\n\n1. `echo \"power on\" | sudo bluetoothctl` Enables your built-in Bluetooth adapter or external Bluetooth USB dongle\n\n### Using BlueZ commandline tools\nBlueZ also provides an interactive commandline tool to interact with Bluetooth devices. You know that your BlueZ installation is working fine if it discovers any Bluetooth devices nearby.\n\n`sudo bluetoothctl` Starts an interactive mode to talk to BlueZ\n  * `power on` Enables the Bluetooth adapter\n  * `scan on` Start Bluetooth device scanning and lists all found devices with MAC addresses\n  * `connect AA:BB:CC:DD:EE:FF` Connects to a Nuimo controller with specified MAC address\n  * `exit` Quits the interactive mode\n\n### Installing Nuimo Python SDK\n\nTo install Nuimo module and the Python3 D-Bus dependency globally, run:\n\n```\nsudo pip3 install nuimo\nsudo apt-get install python3-dbus\n```\n\n#### Running the Nuimo control script\n\nTo test if your setup is working, run the following command. Note that it must be run as root because on Linux, Bluetooth discovery is a restricted operation.\n\n```\nsudo nuimoctl --discover\nsudo nuimoctl --connect AA:BB:CC:DD:EE:FF # Replace the MAC address with your Nuimo's MAC address\nsudo nuimoctl --help # To list all available commands\n```\n\n## SDK Usage\n\n### Discovering nearby Nuimo controllers\n\nThe SDK entry point is the `ControllerManager` class. Check the following example to dicover any Nuimo controller nearby.\n\nPlease note that communication with your Bluetooth adapter happens over BlueZ's D-Bus API, hence an event loop needs to be run in order to receive all Bluetooth related events. You can start and stop the event loop via `run()` and `stop()` calls to your `ControllerManager` instance.\n\n\n```python\nimport nuimo\n\nclass ControllerManagerPrintListener(nuimo.ControllerManagerListener):\n    def controller_discovered(self, controller):\n        print(\"Discovered Nuimo controller\", controller.mac_address)\n\nmanager = nuimo.ControllerManager(adapter_name='hci0')\nmanager.listener = ControllerManagerPrintListener()\nmanager.start_discovery()\nmanager.run()\n```\n\n### Connecting to a Nuimo controller and receiving user input events\n\nOnce `ControllerManager` has discovered a Nuimo controller you can use the `controller` object that you retrieved from `ControllerManagerListener.controller_discovered()` to connect to it. Alternatively you can create a new instance of `Controller` using the name of your Bluetooth adapter (typically `hci0`) and Nuimo's MAC address.\n\nMake sure to assign a `ControllerListener` object to the `listener` attribute of your controller instance. It will notify you about all Nuimo controller related events such connection, disconnection and user input events.\n\nThe following example connects to a Nuimo controller and uses the predefined `ControllerPrintListener` class to print all controller events:\n\n```python\nimport nuimo\n\nmanager = nuimo.ControllerManager(adapter_name='hci0')\n\ncontroller = nuimo.Controller(mac_address='AA:BB:CC:DD:EE:FF', manager=manager)\ncontroller.listener = nuimo.ControllerListener() # Use an instance of your own nuimo.ControllerListener subclass\ncontroller.connect()\n\nmanager.run()\n```\n\nAs with Nuimo controller discovery, remember to start the Bluetooth event loop with `ControllerManager.run()`.\n\n### Write to Nuimo's LED matrix\n\nOnce a Nuimo controller is connected you can send an LED matrix to its display. Therefor create an `LedMatrix` object by initializing it with a string. That string should contain 81 characters: each character, starting from top left corner, tells whether the corresponding LED should be on or off. `' '` and `'0'` signal LED off all other characters power the corresponding LED. The following example shows a cross:\n\n```python\nmatrix = nuimo.LedMatrix(\n    \"*       *\"\n    \" *     * \"\n    \"  *   *  \"\n    \"   * *   \"\n    \"    *    \"\n    \"   * *   \"\n    \"  *   *  \"\n    \" *     * \"\n    \"*       *\"\n)\ncontroller.display_matrix(matrix)\n```\n\nYou can pass additional parameters to `display_matrix()` to control the following options:\n* `interval: float` # Display interval in seconds, default: `2.0` seconds\n* `brightness: float` # LED matrix brightness, default: `1.0` (100%)\n* `fading: bool` # Whether to fade the previous matrix into the next one, aka \"onion skinning effect\", default: `False`\n* `ignore_duplicates: bool` # Whether or not send an LED matrix to a Nuimo controller if it's already being displayed, default: `False`\n\n## Support\n\nPlease open an issue or drop us an email to [developers@senic.com](mailto:developers@senic.com).\n\n## Contributing\n\nContributions are welcome via pull requests. Please open an issue first in case you want to discus your possible improvements to this SDK.\n\n## License\n\nThe Nuimo Python SDK is available under the MIT License.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetsenic%2Fnuimo-linux-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgetsenic%2Fnuimo-linux-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetsenic%2Fnuimo-linux-python/lists"}