idoodler

• iOS Developer
• Web Developer
• Homeautomator
• Electronics lover
Facts
  • Name:
    David Gölzhäuser
  • Synonym:
    idoodler
  • Age:
    21
  • Nationality:
    German 🇩🇪
  • Job:
    Software Developer at Loxone Electronics GmbH in Austria 🇦🇹
  • Capabilities:
    Swift, Objective-C, , , , , MySQL, C#,
  • Operating Systems:
  • Other:
    Basic understanding of PCB design
  • Certifications:
    MCP 70-480
Web Presence
Twitter

I am having this Twitter account since 2011, but I am mostly active since 2013.

Followers: 797

Twitter
Followers 797
Stackoverflow

This account is active since 2012, I am constantly improving my reputation.

Reputation: 1900

Stackoverflow
Reputation 1900
Badges

79

34

7

Accept Rate 38
Github

You aren't a real developer if you don't have a Github account, active since 2014.

Followers: 8

Github
Followers 8
Public Repos 15
Reddit

I may be a bit late to join the Reddit party, but better late then never! Account active since 2016

Comment Karma: 454

Reddit
Post Karma 459
Comment Karma 454
Comments 25
Instagram

And just for reference, I also have a semi active Instagram account.

Followers: 36

Instagram
Followers 36
Uploads 81
Github
Github Organizations I am a part of
My Github avatar Loxone My Github avatar bslinz2
My projects available on Github
  • alerts-and-pickers (Swift)

    Swift 4.0 Platform: iOS XCode 9+ iOS 11 Licence MIT

    Alerts & Pickers

    Advanced usage of native UIAlertController with TextField, TextView, DatePicker, PickerView, TableView, CollectionView and MapView.

    Features

    • Custom pickers based on UITextField, UITextView, UIDatePicker, UIPickerView, UITableView, UICollectionView and MKMapView.
    • Example using a Storyboard.
    • Easy contentViewController placement.
    • Attributed title label and message label.
    • Button customization: image and title color.
    • Understandable action button placement.
    • Easy presentation.
    • Pure Swift 4.

    Usage

    • New Alert
    let alert = UIAlertController(style: .alert, title: "Title", message: "Message")
    // or
    let alert = UIAlertController(style: .alert)
    • Set and styling title
    alert.set(title: "Title", font: .systemFont(ofSize: 20), color: .black)
    // or
    alert.setTitle(font: .systemFont(ofSize: 20), color: .black)
    • Set and styling message
    alert.set(message: "Message", font: .systemFont(ofSize: 16), color: .black)
    // or
    alert.setMessage(font: .systemFont(ofSize: 16), color: .black)
    • Add button with image
    alert.addAction(image: image, title: "Title", color: .black, style: .default) { action in
        // completion handler
    }
    • Show Alert
    // show alert
    alert.show()
    
    // or show alert with options
    alert.show(animated: true, vibrate: true) {
        // completion handler
    }

    Set Content ViewController

    When setting your own custom UIViewController into UIAlertController keep in mind to set prefferedContentSize.height of the controller otherwise it will no effect. You can not set prefferedContentSize.width.

    let alert = UIAlertController(style: .alert, title: "Title")
    let vc = CustomViewController()
    vc.preferredContentSize.height = height
    alert.setValue(vc, forKey: "contentViewController")
    alert.show()
    
    // or
    let alert = UIAlertController(style: .alert, title: "Title")
    let vc = CustomViewController()
    alert.set(vc: vc, height: height)
    alert.show()

    Pickers

    For UX better to use .actionSheet style in UIAlertController when set picker into contentViewController. If you like you can use .alert style as well, buy .actionSheet style is wider and User can see more as well as action button is placing at bottom that also more convenience for User to touch it.

    UITextField In native UIAlertController you can only add UITextField to .alert style with default style and you can not change such properties as .borderColor, .borderWidth, .frame.size and so on. But if you make your own UIViewController with UITextField, it will solve all these problems.

    One TextField Picker

    You can use both styles .alert and .actionSheet of UIAlertController.

    let alert = UIAlertController(style: self.alertStyle, title: "TextField")                  
    let config: TextField.Config = { textField in
        textField.becomeFirstResponder()
        textField.textColor = .black
        textField.placeholder = "Type something"
        textField.left(image: image, color: .black)
        textField.leftViewPadding = 12
        textField.borderWidth = 1
        textField.cornerRadius = 8
        textField.borderColor = UIColor.lightGray.withAlphaComponent(0.5)
        textField.backgroundColor = nil
        textField.keyboardAppearance = .default
        textField.keyboardType = .default
        textField.isSecureTextEntry = true
        textField.returnKeyType = .done
        textField.action { textField in
            // validation and so on
        }
    }              
    alert.addOneTextField(configuration: config)
    alert.addAction(title: "OK", style: .cancel)
    alert.show()

    Two TextFields Picker

    You can use both styles .alert and .actionSheet of UIAlertController.

    let alert = UIAlertController(style: .alert, title: "Login")
    
    let configOne: TextField.Config = { textField in
        textField.left(image: user), color: .black)
        textField.leftViewPadding = 16
        textField.leftTextPadding = 12
        textField.becomeFirstResponder()
        textField.backgroundColor = nil
        textField.textColor = .black
        textField.placeholder = "Name"
        textField.clearButtonMode = .whileEditing
        textField.keyboardAppearance = .default
        textField.keyboardType = .default
        textField.returnKeyType = .done
        textField.action { textField in
            // action with input
        }
    }
    
    let configTwo: TextField.Config = { textField in
        textField.textColor = .black
        textField.placeholder = "Password"
        textField.left(image: lock, color: .black)
        textField.leftViewPadding = 16
        textField.leftTextPadding = 12
        textField.borderWidth = 1
        textField.borderColor = UIColor.lightGray.withAlphaComponent(0.5)
        textField.backgroundColor = nil
        textField.clearsOnBeginEditing = true
        textField.keyboardAppearance = .default
        textField.keyboardType = .default
        textField.isSecureTextEntry = true
        textField.returnKeyType = .done
        textField.action { textField in
            // action with input
        }
    }
    // vInset - is top and bottom margin of two textFields   
    alert.addTwoTextFields(vInset: 12, textFieldOne: configOne, textFieldTwo: configTwo)
    alert.addAction(title: "OK", style: .cancel)
    alert.show()

    DatePicker

    UIDatePicker does not look very much in .alert style.

    let alert = UIAlertController(style: .actionSheet, title: "Select date")
    alert.addDatePicker(mode: .dateAndTime, date: date, minimumDate: minDate, maximumDate: maxDate) { date in
        // action with selected date
    }
    alert.addAction(title: "OK", style: .cancel)
    alert.show()

    PickerView

    Example how to use UIPickerView as contentViewController and change height of the UIAlertController.

    let alert = UIAlertController(style: .actionSheet, title: "Picker View", message: "Preferred Content Height")
    
    let frameSizes: [CGFloat] = (150...400).map { CGFloat($0) }
    let pickerViewValues: [[String]] = [frameSizes.map { Int($0).description }]
    let pickerViewSelectedValue: PickerViewViewController.Index = (column: 0, row: frameSizes.index(of: 216) ?? 0)
    
    alert.addPickerView(values: pickerViewValues, initialSelection: pickerViewSelectedValue) { vc, picker, index, values in
        DispatchQueue.main.async {
            UIView.animate(withDuration: 1) {
                vc.preferredContentSize.height = frameSizes[index.row]
            }
        }
    }
    alert.addAction(title: "Done", style: .cancel)
    alert.show()

    Locale Pickers

    • Country Picker

    let alert = UIAlertController(style: .actionSheet, message: "Select Country")
    alert.addLocalePicker(type: .country) { info in
        // action with selected object
    }
    alert.addAction(title: "OK", style: .cancel)
    alert.show()
    • Phone Code Picker

    let alert = UIAlertController(style: .actionSheet, title: "Phone Codes")
    alert.addLocalePicker(type: .phoneCode) { info in
        // action with selected object
    }
    alert.addAction(title: "OK", style: .cancel)
    alert.show()
    • Currency Picker

    let alert = UIAlertController(style: .actionSheet, title: "Currencies")
    alert.addLocalePicker(type: .currency) { info in
        alert.title = info?.currencyCode
        alert.message = "is selected"
        // action with selected object
    }
    alert.addAction(title: "OK", style: .cancel)
    alert.show()

    Image Picker

    • Horizontal Image Picker with paging and single selection:
    let alert = UIAlertController(style: .actionSheet)
    let photos: [UIImage] = images
    alert.addImagePicker(
        flow: .horizontal,
        paging: true,
        images: photos,
        selection: .single(action: { [unowned self] image in
            // action with selected image
        }))
    alert.addAction(title: "OK", style: .cancel)
    alert.show()
    • Vertical Image Picker w/o paging and with multiple selection:
    let alert = UIAlertController(style: .actionSheet)
    let photos: [UIImage] = images
    alert.addImagePicker(
        flow: .vertical,
        paging: false,
        height: UIScreen.main.bounds.height,
        images: photos,
        selection: .multiple(action: { [unowned self] images in
            // action with selected images
        }))
    alert.addAction(title: "OK", style: .cancel)
    alert.show()

    PhotoLibrary Picker

    let alert = UIAlertController(style: .actionSheet)
    alert.addPhotoLibraryPicker(
        flow: .horizontal,
        paging: true,
        selection: .single(action: { image in
            // action with selected image
        }))
    alert.addAction(title: "Cancel", style: .cancel)
    alert.show()

    ColorPicker

    Example how to use UIViewController instantiated from Storyboard with Autolayout as contentViewController in the UIAlertController.

    let alert = UIAlertController(style: .actionSheet)
    alert.addColorPicker(color: color) { color in
        // action with selected color
    }
    alert.addAction(title: "Done", style: .cancel)
    alert.show()

    Contacts Picker

    let alert = UIAlertController(style: .actionSheet)
    alert.addContactsPicker { contact in
        // action with contact
    }
    alert.addAction(title: "Cancel", style: .cancel)
    alert.show()

    Location Picker

    let alert = UIAlertController(style: .actionSheet)
    alert.addLocationPicker { location in
        // action with location
    }
    alert.addAction(title: "Cancel", style: .cancel)
    alert.show()

    Telegram Picker

    let alert = UIAlertController(style: .actionSheet)
    alert.addTelegramPicker { result in
        switch result {
          case .photo(let assets):
            // action with assets
          case .contact(let contact):
            // action with contact
          case .location(let location):
            // action with location
        }
    }
    alert.addAction(title: "Cancel", style: .cancel)
    alert.show()

    TextViewer

    let alert = UIAlertController(style: .actionSheet)
    alert.addTextViewer(text: .attributedText(text))
    alert.addAction(title: "OK", style: .cancel)
    alert.show()

    Alerts vs. Action Sheets

    There are some things to keep in mind when using .actionSheet and .alert styles:

    • Pickers better to use in .actionSheet style.
    • UITextField can be used in both styles.

    Installing

    Manually

    Download and drop /Source folder in your project.

    Requirements

    • Swift 4
    • iOS 11 or higher

    Authors

    Communication

    • If you found a bug, open an issue.
    • If you have a feature request, open an issue.
    • If you want to contribute, submit a pull request.

    License

    This project is licensed under the MIT License.

    0
    0
    0
    0
  • bootstrap-validator (JavaScript)

    Validator, for Bootstrap 3

    The Validator plugin offers automatic form validation configurable via mostly HTML5 standard attributes. It also provides an unobtrusive user experience, because nobody likes a naggy form.

    Features

    • Configurable via data-api and standard HTML5 attributes
    • Patient to inform user of errors and eager to let them know the errors have been resolved
    • Submit is disabled until the form is valid and all required fields are complete
    • Customizable error messages
    • Custom validator functions
    • Validation of an input field via AJAX

    Installation

    Documentation

    See the project docs at http://1000hz.github.io/bootstrap-validator

    Contributing

    Found an issue?

    Be sure to include a reproducible test case on JS Bin with your report. Here's a template to get started.

    Submitting a pull request?

    Fork this repo and create a new branch for your patch. Try to adhere to the code style of Bootstrap 3's JS as much as possible. Be sure to add any relevant unit tests. Make sure everything's still ok by running grunt test. Lastly, don't pollute your patch branch with any unrelated changes.

    Donating

    If you've found this project particularly useful and feel like giving a little back, you can donate what you want via PayPal or Square Cash.

    Donate via PayPal Donate via Square Cash

    Author

    Cina Saffary

    Thanks to @mdo and @fat for Bootstrap. <3

    Copyright and license

    Copyright 2016 Cina Saffary under the MIT license.

    0
    0
    0
    0
  • electron-builder (TypeScript)

    electron-builder npm version downloads per month donate

    A complete solution to package and build a ready for distribution Electron, Proton Native or Muon app for macOS, Windows and Linux with “auto update” support out of the box.

    See documentation on electron.build.

    • NPM packages management:
    • Code Signing on a CI server or development machine.
    • Auto Update ready application packaging.
    • Numerous target formats:
      • All platforms: 7z, zip, tar.xz, tar.7z, tar.lz, tar.gz, tar.bz2, dir (unpacked directory).
      • macOS: dmg, pkg, mas.
      • Linux: AppImage, snap, debian package (deb), rpm, freebsd, pacman, p5p, apk.
      • Windows: nsis (Installer), nsis-web (Web installer), portable (portable app without installation), AppX (Windows Store), MSI, Squirrel.Windows.
    • Publishing artifacts to GitHub Releases, Amazon S3, DigitalOcean Spaces and Bintray.
    • Advanced building:
      • Pack in a distributable format already packaged app.
      • Separate build steps.
      • Build and publish in parallel, using hard links on CI server to reduce IO and disk space usage.
    • electron-compile support (compile for release-time on the fly on build).
    • Docker images to build Electron app for Linux or Windows on any platform.
    • Proton Native and Muon support.
    Question Answer
    “I want to configure electron-builder” See options
    “I have a question” Open an issue or join the chat
    “I found a bug” Open an issue
    “I want to support development” Donate

    Real project example — onshape-desktop-shell.

    Installation

    Yarn is strongly recommended instead of npm.

    yarn add electron-builder --dev

    Quick Setup Guide

    electron-webpack-quick-start is a recommended way to create a new Electron application. See Boilerplates.

    1. Specify the standard fields in the application package.jsonname, description, version and author.

    2. Specify the build configuration in the package.json as follows:

      "build": {
        "appId": "your.id",
        "mac": {
          "category": "your.app.category.type"
        }
      }

      See all options.

    3. Add icons.

    4. Add the scripts key to the development package.json:

      "scripts": {
        "pack": "electron-builder --dir",
        "dist": "electron-builder"
      }

      Then you can run yarn dist (to package in a distributable format (e.g. dmg, windows installer, deb package)) or yarn pack (only generates the package directory without really packaging it. This is useful for testing purposes).

      To ensure your native dependencies are always matched electron version, simply add script "postinstall": "electron-builder install-app-deps" to your package.json.

    5. If you have native addons of your own that are part of the application (not as a dependency), set nodeGypRebuild to true.

    Please note that everything is packaged into an asar archive by default.

    For an app that will be shipped to production, you should sign your application. See Where to buy code signing certificates.

    Donate

    We do this open source work in our free time. If you'd like us to invest more time on it, please donate. Donation can be used to increase some issue priority.

    Sponsors

    WorkFlowy Tidepool

    0
    0
    0
    0
  • Fily-Issues

    Fily bug tracker

    Please report any issue or feature you have

    Changelog

    1.0 build 1 - still in Developement

    • HTTP-Server to brows and add files
    • Added Webservices for HTTP-Server
    • Filemanager (Delete, Move, Create, Copy files)
    • Added support for Images (also GIF), Text, HTML, PDF, ZIP
    • Costume vector-file-icons
    0
    0
    1
    0
  • homebridge-loxone-ws (JavaScript)

    homebridge-loxone-ws

    Websocket based Loxone plugin for homebridge

    This is a Loxone plugin for Homebridge The plugin will automatically retrieve and communicate with all these items from your Loxone setup:

    • Lights (Switches, Dimmers and Color leds)
    • Other Switches
    • Pushbuttons
    • Window blinds
    • Temperature sensors
    • (other types can be added easily)

    The only configuration needed is the credentials to your Loxone miniserver.

    Benefits

    • Realtime and very fast 2-way updates by using the websocket connection
    • One-touch deployment through automatic import of Loxone controls

    Prerequisites

    Homebridge Follow all the installation steps there.

    Installation

    Install the plugin through npm or download the files from here.

    $ sudo npm install -g homebridge-loxone-ws

    Note: the plugin requires extra node modules, but these should be automatically installed:

    • node-lox-ws-api
    • request
    Homebridge config.json

    Add the platform section to your Homebridge config.json (usually in ~/.homebridge):

    {
        "bridge": {
            "name": "Homebridge",
            "username": "CA:AA:12:34:56:78",
            "port": 51826,
            "pin": "012-34-567"
        },
    
        "description": "Your config file.",
    
        "platforms": [
            {
                "platform": "LoxoneWs",
                "name": "Loxone",
                "host": "192.168.1.2",
                "port": "12345",
                "username": "homebridge",
                "password": "somepassword"
            }
        ]
    }
    

    Replace fields

    • host by the IP of your loxone miniserver
    • port by the port of your miniserver (use 80 if no special port)
    • username by the Loxone username
    • password by the Loxone password

    I strongly suggest to create a dedicate Loxone user through Loxone Config (eg homebridge). Like this you can restrict access to sensitive items or filter out unneeded controls.

    Assumptions

    To create the correct accessory type from Loxone items, some attribute parsing is required. (Eg a Loxone Switch can be a Switch or a LightBulb, and InfoOnlyAnalog type can be a temperature sensor but also anything else.) This is covered in the checkCustomAttrs function in ItemFactory. Adapt it to your needs. Currently these assumptions are made:

    • temperature sensor names start with 'Temperat'
    • light switches are in a Loxone category using the lightbulb icon

    The controls will be named like you named them in Loxone. Rename them through the iOS Home app to make it more intuitive for using with Siri. Eg LIGHT_KITCHEN can be renamed to 'main light' and added to room Kitchen. Then you can ask Siri to 'turn on the main light in the kitchen'.

    Limitations

    rooms The Homebridge/HAP protocol does currently not allow attaching the Loxone rooms to the accessories. That is a manual action to be done once using the IOS Home app (or the Eve app which is much more user-friendly).

    Special note: organizing into rooms can be done from Eve, but renaming the items should (unfortunately) be done from the IOS Home app. Name changes in Eve are not reflected in Home and thus not known by Siri.

    100 items HomeKit has a limit of 100 accessories per bridge. If you have a large Loxone setup, try to filter unneeded items out either through Loxone access or in the checkCustomAttrs function.

    pushbuttons Since Homekit has no pushbutton concept, I implemented pushbuttons as switches in Homekit. Telling Siri to put them On will send a pulse to the pushbutton. In Homekit, they will appear to be On for a second.

    Advanced

    The Event type is foreseen for your convenience, but not currently used. It can be used for pushbuttons when you're only interested in reading from Homekit and not controlling it. That could be useful for setting triggers, eg a Pushbutton event which causes a Homekit scene to become active.

    License

    The plugin is released under MIT license, which means you can do whatever you want with it as long as you give credit.

    Credits

    Attribution goes towards Tommaso Marchionni. The structure of this code is based on his openHAB plugin.

    The original HomeKit API work was done by Khaos Tian in his HAP-NodeJS project.

    The homebridge component on which this plugin is built was created by Nick Farina.

    I've made use of the NodeJS Loxone websocket API created by Ladislav Dokulil

    0
    0
    1
    0
  • MagicMirror (JavaScript)

    MagicMirror²: The open source modular smart mirror platform.

    Dependency Status devDependency Status License Travis Known Vulnerabilities Slack Status

    MagicMirror² is an open source modular smart mirror platform. With a growing list of installable modules, the MagicMirror² allows you to convert your hallway or bathroom mirror into your personal assistant. MagicMirror² is built by the creator of the original MagicMirror with the incredible help of a growing community of contributors.

    MagicMirror² focuses on a modular plugin system and uses Electron as an application wrapper. So no more web server or browser installs necessary!

    Table Of Contents

    Installation

    Raspberry Pi

    Automatic Installation (Raspberry Pi only!)

    Electron, the app wrapper around MagicMirror², only supports the Raspberry Pi 2/3. The Raspberry Pi 0/1 is currently not supported. If you want to run this on a Raspberry Pi 1, use the server only feature and setup a fullscreen browser yourself. (Yes, people have managed to run MM² also on a Pi0, so if you insist, search in the forums.)

    Note that you will need to install the lastest full version of Raspbian, don't use the Lite version.

    Execute the following command on your Raspberry Pi to install MagicMirror²:

    bash -c "$(curl -sL https://raw.githubusercontent.com/MichMich/MagicMirror/master/installers/raspberry.sh)"

    Manual Installation

    1. Download and install the latest Node.js version.
    2. Clone the repository and check out the master branch: git clone https://github.com/MichMich/MagicMirror
    3. Enter the repository: cd MagicMirror/
    4. Install and run the app with: npm install && npm start
      For Server Only use: npm install && node serveronly .

    ⚠️ Important!

    • The installation step for npm install will take a very long time, often with little or no terminal response!
      For the RPi3 this is ~10 minutes and for the Rpi2 ~25 minutes.
      Do not interrupt or you risk getting a 💔 by Raspberry Jam.

    Also note that:

    • npm start does not work via SSH. But you can use DISPLAY=:0 nohup npm start & instead.
      This starts the mirror on the remote display.
    • If you want to debug on Raspberry Pi you can use npm start dev which will start MM with Dev Tools enabled.
    • To access toolbar menu when in mirror mode, hit ALT key.
    • To toggle the (web) Developer Tools from mirror mode, use CTRL-SHIFT-I or ALT and select View.

    Server Only

    In some cases, you want to start the application without an actual app window. In this case, you can start MagicMirror² in server only mode by manually running node serveronly or using Docker. This will start the server, after which you can open the application in your browser of choice. Detailed description below.

    Important: Make sure that you whitelist the interface/ip (ipWhitelist) in the server config where you want the client to connect to, otherwise it will not be allowed to connect to the server. You also need to set the local host address field to 0.0.0.0 in order for the RPi to listen on all interfaces and not only localhost (default).

    var config = {
    	address: "0.0.0.0",	// default is "localhost"
    	port: 8080,		// default
    	ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:172.17.0.1"], // default -- need to add your IP here
    	...
    };

    Client Only

    This is when you already have a server running remotely and want your RPi to connect as a standalone client to this instance, to show the MM from the server. Then from your RPi, you run it with: node clientonly --address 192.168.1.5 --port 8080. (Specify the ip address and port number of the server)

    Docker

    MagicMirror² in server only mode can be deployed using Docker. After a successful Docker installation you just need to execute the following command in the shell:

    docker run  -d \
    	--publish 80:8080 \
    	--restart always \
    	--volume ~/magic_mirror/config:/opt/magic_mirror/config \
    	--volume ~/magic_mirror/modules:/opt/magic_mirror/modules \
    	--name magic_mirror \
    	bastilimbach/docker-magicmirror

    To get more information about the available Dockerfile versions and configurations head over to the respective GitHub repository.

    Configuration

    Raspberry Specific

    The following wiki links are helpful for the initial configuration of your MagicMirror² operating system:

    General

    1. Copy config/config.js.sample to config/config.js.
      Note: If you used the installer script. This step is already done for you.

    2. Modify your required settings.
      Note: You'll can check your configuration running npm run config:check.

    The following properties can be configured:

    Option Description
    port The port on which the MagicMirror² server will run on. The default value is 8080.
    address The interface ip address on which to accept connections. The default is localhost, which would prevent exposing the built-in webserver to machines on the local network. To expose it to other machines, use: 0.0.0.0.
    ipWhitelist The list of IPs from which you are allowed to access the MagicMirror². The default value is ["127.0.0.1", "::ffff:127.0.0.1", "::1"], which is from localhost only. Add your IP when needed. You can also specify IP ranges with subnet masks (["127.0.0.1", "127.0.0.1/24"]) or directly with (["127.0.0.1", ["192.168.0.1", "192.168.0.100"]]). Set [] to allow all IP addresses. For more information see: follow post ipWhitelist HowTo
    zoom This allows to scale the mirror contents with a given zoom factor. The default value is 1.0
    language The language of the interface. (Note: Not all elements will be localized.) Possible values are en, nl, ru, fr, etc., but the default value is en.
    timeFormat The form of time notation that will be used. Possible values are 12 or 24. The default is 24.
    units The units that will be used in the default weather modules. Possible values are metric or imperial. The default is metric.
    modules An array of active modules. The array must contain objects. See the next table below for more information.
    electronOptions An optional array of Electron (browser) options. This allows configuration of e.g. the browser screen size and position (example: electronOptions: { fullscreen: false, width: 800, height: 600 }). Kiosk mode can be enabled by setting kiosk = true, autoHideMenuBar = false and fullscreen = false. More options can be found here.
    customCss The path of the custom.css stylesheet. The default is css/custom.css.

    Module configuration:

    Option Description
    module The name of the module. This can also contain the subfolder. Valid examples include clock, default/calendar and custommodules/mymodule.
    position The location of the module in which the module will be loaded. Possible values are top_ bar, top_left, top_center, top_right, upper_third, middle_center, lower_third, bottom_left, bottom_center, bottom_right, bottom_bar, fullscreen_above, and fullscreen_below. This field is optional but most modules require this field to set. Check the documentation of the module for more information. Multiple modules with the same position will be ordered based on the order in the configuration file.
    classes Additional classes which are passed to the module. The field is optional.
    header To display a header text above the module, add the header property. This field is optional.
    disabled Set disabled to true to skip creating the module. This field is optional.
    config An object with the module configuration properties. Check the documentation of the module for more information. This field is optional, unless the module requires extra configuration.

    Modules

    The following modules are installed by default.

    For more available modules, check out out the wiki page MagicMirror² 3rd Party Modules. If you want to build your own modules, check out the MagicMirror² Module Development Documentation and don't forget to add it to the wiki and the forum!

    Updating

    If you want to update your MagicMirror² to the latest version, use your terminal to go to your Magic Mirror folder and type the following command:

    git pull && npm install

    If you changed nothing more than the config or the modules, this should work without any problems. Type git status to see your changes, if there are any, you can reset them with git reset --hard. After that, git pull should be possible.

    Community

    The community around the MagicMirror² is constantly growing. We even have a forum now where you can share your ideas, ask questions, help others and get inspired by other builders. We would love to see you there!

    Contributing Guidelines

    Contributions of all kinds are welcome, not only in the form of code but also with regards bug reports and documentation.

    Please keep the following in mind:

    • Bug Reports: Make sure you're running the latest version. If the issue(s) still persist: please open a clearly documented issue with a clear title.
    • Minor Bug Fixes: Please send a pull request with a clear explanation of the issue or a link to the issue it solves.
    • Major Bug Fixes: please discuss your approach in an GitHub issue before you start to alter a big part of the code.
    • New Features: please please discuss in a GitHub issue before you start to alter a big part of the code. Without discussion upfront, the pull request will not be accepted / merged.

    Thanks for your help in making MagicMirror² better!

    Manifesto

    A real Manifesto is still to be written. Till then, Michael's response on one of the repository issues gives a great summary:

    "... I started this project as an ultimate starter project for Raspberry Pi enthusiasts. As a matter of fact, for most of the contributors, the MagicMirror project is the first open source project they ever contributed to. This is one of the reasons why the MagicMirror project is featured in several RasPi magazines.

    The project has a lot of opportunities for improvement. We could use a powerful framework like Vue to ramp up the development speed. We could use SASS for better/easier css implementations. We could make it an NPM installable package. And as you say, we could bundle it up. The big downside of of of these changes is that it over complicates things: a user no longer will be able to open just one file and make a small modification and see how it works out.

    Of course, a bundled version can be complimentary to the regular un-bundled version. And I'm sure a lot of (new) users will opt for the bundled version. But this means those users won't be motivated to take a peek under the hood. They will just remain 'users'. They won't become contributors, and worse: they won't be motivated to take their first steps in software development.

    And to be honest: motivating curious users to step out of their comfort zone and take those first steps is what drives me in this project. Therefor my ultimate goal is this project is to keep it as accessible as possible."

    ~ Michael Teeuw


    MagPi Top 50

    0
    0
    0
    0
  • MagicMirrorPi0Installer (Shell)

    MagicMirror 2.6.0 Installer for the Pi Zero

    This installer allows users of the Raspberry Pi Zero to also access the popular MagicMirror personal assistant project which was voted number 1 Pi project by MagPi in 2016.

    Installation

    Raspberry Pi

    Install the most recent available Raspbian Image (This is tested on Raspbian Jessie and Raspbian Stretch). You do not need the 'recommended software', but you do need the 'desktop'. Therefore do not use the 'Lite' version.

    Set up your Internet connection. You may also want to set up SSH and VNC at this time.

    Magic Mirror Installation

    Clone this project into your home directory (It should come down into the folder ~/MagicMirrorPi0Installer)

    git clone https://github.com/ac2799/MagicMirrorPi0Installer
    

    Run the command

    sudo chmod a+x ~/MagicMirrorPi0Installer/RaspberryPi0.sh && sh ~/MagicMirrorPi0Installer/RaspberryPi0.sh
    

    This will make the shell script executable, and if that is successful, it will also run the script.

    This can take up to an hour, depending on how many updates and upgrades need to be made to your Raspbian version. There is minimal interaction required, except to press enter a couple of times to agree to updates outside of the repository (e.g. updates to the raspbian operating system).

    Further details

    The main repository for the Magic Mirror is at https://github.com/MichMich/MagicMirror. All the work was done by them, this is just to hold the Pi Zero script until such time as it can be brought into the main project.

    - Andrew Chu

    0
    0
    0
    0
  • MMM-forecast-io (JavaScript)

    MMM-Forecast-IO

    This an extension for MagicMirror that adds localized weather using the Dark Sky API (originally Forecast.io) -- the same service that powers the Dark Sky App.

    This module makes use of the geolocation API to determine the location of the mirror. This can be turned off by setting latitude and longitude in the module's config (see Configuration options below).

    Unless running headless in a browser, Geolocation requires setting the GOOGLE_API_KEY environment variable.

    screenshot

    Using the module

    To use this module, add it to the modules array in the config/config.js file:

    modules: [
      {
        module: 'MMM-forecast-io',
        position: 'top_right',  // This can be any of the regions.
        config: {
          // See 'Configuration options' for more information.
          apiKey: 'abcde12345abcde12345abcde12345ab', // Dark Sky API key.
          // Only required if geolocation doesn't work:
          latitude:   16.77532,
          longitude: -3.008265
        }
      }
    ]

    Configuration options

    Option Description
    apiKey The Dark Sky API key, which can be obtained by creating an Dark Sky API account.

    This value is REQUIRED
    units What units to use. Specified by config.js

    Possible values: config.units = Specified by config.js, default = Kelvin, metric = Celsius, imperial =Fahrenheit
    Default value: config.units
    language The language of the weather text.

    Possible values: en, nl, ru, etc ...
    Default value: uses value of config.language
    updateInterval How often does the content needs to be fetched? (Milliseconds)

    Forecast.io enforces a 1,000/day request limit, so if you run your mirror constantly, anything below 90,000 (every 1.5 minutes) may require payment information or be blocked.

    Possible values: 1000 - 86400000
    Default value: 300000 (5 minutes)
    animationSpeed Speed of the update animation. (Milliseconds)

    Possible values:0 - 5000
    Default value: 2000 (2 seconds)
    initialLoadDelay The initial delay before loading. If you have multiple modules that use the same API key, you might want to delay one of the requests. (Milliseconds)

    Possible values: 1000 - 5000
    Default value: 0
    retryDelay The delay before retrying after a request failure. (Milliseconds)

    Possible values: 1000 - 60000
    Default value: 2500
    latitude The latitude location in decimal. Set this (and longitude) as the location for the forecast. If this is not set, the module will attempt to approximate using browser geolocation.

    Example value: 16.77532
    Default value: null
    longitude The longitude location in decimal. Set this (and latitude) as the location for the forecast. If this is not set, the module will attempt to approximate using browser geolocation.

    Example value: -3.008265
    Default value: null
    showIndoorTemperature If you have another module that emits the INDOOR_TEMPERATURE notification, the indoor temperature will be displayed.

    Default value: false
    apiBase The Dark Sky API base URL.

    Default value: 'https://api.darksky.net/forecast'
    showForecast Toggles display of the seven-day weather forecast.

    Default value: true
    maxDaysForecast Limit how many days of weather forecast. Useful values 1-7

    Default value: 7
    enablePrecipitationGraph Toggles display of the precipitation graph.

    Default value: true
    alwaysShowPrecipitationGraph Force the precipition graph to always show, and not just when it's raining.

    Default value: false
    precipitationFillColor Choose the color of the precipitation graph. Will accept hex value or color names of Javascript-friendly colors. See this page for a list of colors. "dodgerblue" appears to best mimic the Dark Sky app.

    Default value: white
    precipitationGraphWidth Width of the precipitation graph element in pixels. Scales height to match.

    Default value: 400
    precipitationProbabilityThreshold Probability threshold at which rain is rendered onto the precipitation graph.
    See the Darksky.net API documentation for more details.

    Default value: 0.1
    iconTable The conversion table to convert the weather conditions to weather-icons.

    Default value:
    iconTable: {
          'clear-day':           'wi-day-sunny',
          'clear-night':         'wi-night-clear',
          'rain':                'wi-rain',
          'snow':                'wi-snow',
          'sleet':               'wi-rain-mix',
          'wind':                'wi-cloudy-gusts',
          'fog':                 'wi-fog',
          'cloudy':              'wi-cloudy',
          'partly-cloudy-day':   'wi-day-cloudy',
          'partly-cloudy-night': 'wi-night-cloudy',
          'hail':                'wi-hail',
          'thunderstorm':        'wi-thunderstorm',
          'tornado':             'wi-tornado'
        }
    1
    1
    1
    0
  • MMM-Loxone (JavaScript)

    MMM-Loxone

    This is a module for the MagicMirror².

    MMM-Loxone connects to your Loxone Miniserver and lets it communicate to your MagicMirror².

    Disclaimer

    This package has been written for the Raspberry Pi and has only be tester on the Raspberry Pi please report any incompatibilities.

    Security

    This module doesn't transmit the defined credentials, it uses tokens to talk to your Loxone Miniserver.

    Please create an user for your MagicMirror² to keep your personal credentials secure!

    Dependencies

    Upcoming features

    • Support controls like Alarm, WindowMonitor, Simple Virtual outputs, Weather in a modular way
    • Further power saving features (Ability to switch off the monitors AC power via an relay)
    • Quick overview, whats up in your home

    Installation

    Navigate into your MagicMirror's modules folder:

    cd ~/MagicMirror/modules

    Clone this repository:

    git clone https://github.com/idoodler/MMM-Loxone

    Navigate to the new MMM-Loxone folder and install the node dependencies.

    npm install

    Update the module

    Navigate into the MMM-Loxone folder with cd ~/MagicMirror/modules/MMM-Loxone and get the latest code from github with git pull.

    If you haven't changed the modules, this should work without any problems. Type git status to see your changes, if there are any, you can reset them with git reset --hard. After that, git pull should be possible.

    Using the module

    To use this module, add the following configuration block to the modules array in the config/config.js file:

    var config = {
        modules: [
            {
                module: 'MMM-Loxone',
                config: {
                    // See below for configurable options
                }
            }
        ]
    }

    Configuration options

    Option Description
    host required Defines the Loxone Miniserver host. It can be an IP or your CloudDNS address

    Example: 192.168.0.46 or dns.loxonecloud.com/EEE00000000

    Type: string
    user required Defines the Loxone Miniserver username.

    Type: string
    pwd required Defines the Loxone Miniserver password.

    Type: string
    roomUuid Optional Defines the room of which the room temperature is displayed

    Info: Modules like the default currentWeather and MMM-forecast-io will display the indoor temperature, please refere to their documentation

    Type: string
    observingUuids optional Defines controls that should be shown on our module. Supported Controls: Virtual State, State

    Type: array

    Default: Empty array
    presence Optional If enabled this module will use the LightControllerV2 in the defined room to set the MagicMirror to sleep or wake it up

    Type: bool

    Default: false
    showInfoNotifications optional If info notifications should be shown.

    Type: bool

    Default: true
    showErrorNotifications optional If error notifications should be shown.
    Type: bool

    Default: true
    showSystemNotifications optional If system notifications should be shown.

    Type: bool

    Default: true
    showNotificationOfControlTypes optional Defines, what controls are able to show notifications on your MagicMirror².

    Type: array

    Default: [ "Intercom", "Alarm", "SmokeAlarm", "Sauna" ]
    allow3rdParty optional If 3rd Party modules are able to use this module to communicate with your Loxone Miniserver.

    Type: bool

    Default: false

    Display the room temperature

    Requirements

    • The room needs to have at lease contain one Intelligent Room Controller (v2)
      • The first Intelligent Room Controller (v2) will be used if multiple are defined in one room
    • roomUuid needs to be defined in the MMM-Loxone configuration in config.js
    • currentWeather or MMM-forecast-io must be installed and correctly configured to display the indoor room temperature

    Display Notifications

    Requirements

    • You must define the alert module in your config.json file.

    Example:

    {
    	module: "alert"
    }

    How to get the roomUuid

    1. Open the Loxone Webinterface
    2. Navigate to the room you want to display the room temperature
    3. Copy the last path component displayed in your browsers URL-Bar
      alt text

    Populate observingUuids

    observingUuids is an array of control uuids

    Example:

    observingUuids: [
        "0d12f989-0060-c82f-ffff2083eaf2523c"
    ]

    alt text

    1. Open the Loxone Webinterface
    2. Navigate to the control you want to display on your mirror
      • Virtual State and State controls are supported
    3. Copy the last path component displayed in your browsers URL-Bar
      alt text

    Developer notes

    Notifications emitted by MMM-Loxone

    NotificationKey Description
    INDOOR_TEMPERATURE Modules like the default currentWeather and MMM-forecast-io will display the indoor temperature. Please implement this notification key if you want to display the indoor temperature in your module.

    Note: roomUUID must be configured in your config.json
    USER_PRESENCE Modules can use this notification to pause or resume your module.

    Example: true if the User is present in the room, false if not.

    Payload: bool

    Note: roomUUID and presence must be configured in your config.json
    LOXONE_STATE Any state emitted by the Loxone Miniserver with its UUID and value. Ready to be used by any other module.

    Payload: Number or String

    Note: allow3rdParty must be configured in your config.json
    LOXONE_STRUCTURE_FILE The current structure file of the Loxone Miniserver as an Object {}.

    Payload: Object

    Note: allow3rdParty must be configured in your config.json
    LOXONE_OSS Out Of Service status of the Loxone Miniserver.

    Example: true if the Miniserver is rebooting, false if the Miniserver is up and running.

    Payload: bool

    Note: allow3rdParty must be configured in your config.json

    License

    The MIT License (MIT)

    Copyright (c) 2018 David Gölzhäuser

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    1
    1
    1
    0
  • MMM-RPI-LED (JavaScript)

    MMM-RPI-LED

    This is a module for the MagicMirror².

    MMM-RPI-LED lets you control the LEDs of your Raspberry Pi

    Dependencies

    Installation

    Navigate into your MagicMirror's modules folder:

    cd ~/MagicMirror/modules

    Clone this repository:

    git clone https://github.com/idoodler/MMM-RPI-LED

    Navigate to the new MMM-RPI-LED folder and install the node dependencies.

    npm install

    Update the module

    Navigate into the MMM-RPI-LED folder with cd ~/MagicMirror/modules/MMM-RPI-LED and get the latest code from github with git pull.

    If you haven't changed the modules, this should work without any problems. Type git status to see your changes, if there are any, you can reset them with git reset --hard. After that, git pull should be possible.

    Using the module

    To use this module, add the following configuration block to the modules array in the config/config.js file:

    var config = {
        modules: [
            {
                module: 'MMM-RPI-LED',
                config: {
                    // See below for configurable options
                }
            }
        ]
    }

    Configuration options

    Option Description
    ledMode required Defines the mode of the Raspberry Pi's LEDs

    Example: 0 = Off, no LED is light up or 1 = Heart beat, the green LED blinks

    Type: number

    License

    The MIT License (MIT)

    Copyright (c) 2018 David Gölzhäuser

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    0
    0
    0
    0
  • node-elgato-stream-deck (JavaScript)

    elgato-stream-deck npm version license Travis Coverage Status Join the chat at https://gitter.im/node-elgato-stream-deck/Lobby

    alt text

    elgato-stream-deck is a Node.js library for interfacing with the Elgato Stream Deck.

    ❗ Please note that node-elgato-stream-deck is NOT a standalone application. It is not something you download and run on its own. It is not an alternative to the official Stream Deck program provided by Elgato. Instead, node-elgato-stream-deck is a code library which provides an API to the Stream Deck. Developers can use this API to make their own applications which interface with the Stream Deck.

    To further clarify: this is not an installable program. There is no user interface, and you cannot do anything with this library on its own. Out of the box, this library does nothing. It's purpose is to provide tools for programmers to build programs from the ground up which interact with a Stream Deck.

    This is a tool for developers to use. It is not a program for end users. It cannot and will not replace the official Stream Deck program. That is not its goal. However, it does enable someone to more easily write a program which does do that.

    Install

    $ npm install --save elgato-stream-deck

    All of this library's native dependencies ship with prebuilt binaries, so having a full compiler toolchain should not be necessary to install node-elgato-stream-deck.

    However, in the event that installation does fail (or if you are on a platform that our dependencies don't provide prebuilt binaries for, such as a Raspberry Pi), you will need to install a compiler toolchain to enable npm to build some of node-elgato-stream-deck's dependencies from source. Expand the details block below for full instructions on how to do so.

    Compiling dependencies from source
    • Windows
      npm install --global windows-build-tools
    • MacOS
      • Install the Xcode Command Line Tools:
      xcode-select --install
    • Linux (including Raspberry Pi)
      • Follow the instructions for Linux in the "Compiling from source" steps for node-hid:
        sudo apt-get install build-essential git
        sudo apt-get install gcc-4.8 g++-4.8 && export CXX=g++-4.8
        sudo apt-get install sudo apt install libusb-1.0-0 libusb-1.0-0-dev
      • Install a recent version of Node.js.:
        curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
        sudo apt-get install -y nodejs 
      • Try installing node-elgato-stream-deck
      • If you still have issues, ensure everything is updated and try again:
        sudo apt-get update && sudo apt-get upgrade

    Table of Contents

    Example

    JavaScript

    const path = require('path');
    const StreamDeck = require('elgato-stream-deck');
    
    // Automatically discovers connected Stream Decks, and attaches to the first one.
    // Throws if there are no connected stream decks.
    // You also have the option of providing the devicePath yourself as the first argument to the constructor.
    // For example: const myStreamDeck = new StreamDeck('\\\\?\\hid#vid_05f3&pid_0405&mi_00#7&56cf813&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}')
    // Device paths can be obtained via node-hid: https://github.com/node-hid/node-hid
    const myStreamDeck = new StreamDeck();
    
    myStreamDeck.on('down', keyIndex => {
    	console.log('key %d down', keyIndex);
    });
    
    myStreamDeck.on('up', keyIndex => {
    	console.log('key %d up', keyIndex);
    });
    
    // Fired whenever an error is detected by the `node-hid` library.
    // Always add a listener for this event! If you don't, errors will be silently dropped.
    myStreamDeck.on('error', error => {
    	console.error(error);
    });
    
    // Fill the second button from the left in the first row with an image of the GitHub logo.
    // This is asynchronous and returns a promise.
    myStreamDeck.fillImageFromFile(3, path.resolve(__dirname, 'github_logo.png')).then(() => {
    	console.log('Successfully wrote a GitHub logo to key 3.');
    });
    
    // Fill the first button form the left in the first row with a solid red color. This is synchronous.
    myStreamDeck.fillColor(4, 255, 0, 0);
    console.log('Successfully wrote a red square to key 4.');

    TypeScript

    import StreamDeck = require('elgato-stream-deck');
    const myStreamDeck = new StreamDeck(); // Will throw an error if no Stream Decks are connected.
    
    myStreamDeck.on('down', keyIndex => {
    	console.log('key %d down', keyIndex);
    });
    
    myStreamDeck.on('up', keyIndex => {
    	console.log('key %d up', keyIndex);
    });
    
    // Fired whenever an error is detected by the `node-hid` library.
    // Always add a listener for this event! If you don't, errors will be silently dropped.
    myStreamDeck.on('error', error => {
    	console.error(error);
    });

    Features

    • Multiplatform support: Windows 7-10, MacOS, Linux, and even Raspberry Pi!
    • Key down and key up events
    • Fill keys with images or solid RGB colors
    • Fill the entire panel with a single image, spread across all keys
    • Set the Stream Deck brightness
    • TypeScript support

    Planned Features

    Contributing

    The elgato-stream-deck team enthusiastically welcomes contributions and project participation! There's a bunch of things you can do if you want to contribute! The Contributor Guide has all the information you need for everything from reporting bugs to contributing entire new features. Please don't hesitate to jump in if you'd like to, or even ask us questions if something isn't clear.

    All participants and maintainers in this project are expected to follow Code of Conduct, and just generally be kind to each other.

    Please refer to the Changelog for project history details, too.

    API

    > streamDeck.write(buffer) -> undefined

    Synchronously writes an arbitrary Buffer instance to the Stream Deck. Throws if an error is encountered during the write operation.

    Example
    // Writes 16 bytes of zero to the Stream Deck.
    streamDeck.write(Buffer.alloc(16));

    > streamDeck.fillColor(keyIndex, r, g, b) -> undefined

    Synchronously sets the given keyIndex's screen to a solid RGB color.

    Example
    // Turn key 4 (the top left key) solid red.
    streamDeck.fillColor(4, 255, 0, 0);

    > streamDeck.fillImageFromFile(keyIndex, filePath) -> Promise

    Asynchronously reads an image from filePath and sets the given keyIndex's screen to that image. Automatically scales the image to 72x72 and strips out the alpha channel. If necessary, the image will be center-cropped to fit into a square.

    Example
    // Fill the second button from the left in the first row with an image of the GitHub logo.
    streamDeck.fillImageFromFile(3, path.resolve(__dirname, 'github_logo.png'))
    	.then(() => {
    		console.log('Successfully wrote a GitHub logo to key 3.');
    	})
    	.catch(err => {
    		console.error(err);
    	});

    > streamDeck.fillImage(keyIndex, buffer) -> undefined

    Synchronously writes a buffer of 72x72 RGB image data to the given keyIndex's screen. The buffer must be exactly 15552 bytes in length. Any other length will result in an error being thrown.

    Example
    // Fill the third button from the left in the first row with an image of the GitHub logo.
    const sharp = require('sharp'); // See http://sharp.dimens.io/en/stable/ for full docs on this great library!
    sharp(path.resolve(__dirname, 'github_logo.png'))
    	.flatten() // Eliminate alpha channel, if any.
    	.resize(streamDeck.ICON_SIZE, streamDeck.ICON_SIZE) // Scale up/down to the right size, cropping if necessary.
    	.raw() // Give us uncompressed RGB.
    	.toBuffer()
    	.then(buffer => {
    		return streamDeck.fillImage(2, buffer);
    	})
    	.catch(err => {
    		console.error(err);
    	});

    > streamDeck.fillPanel(imagePathOrBuffer[, sharpOptions]) -> Promise

    Asynchronously applies an image to the entire panel, spreading it over all keys. The image is scaled down and center-cropped to fit. This method does not currently account for the gaps between keys, and behaves as if each key was directly connected to its neighbors. If you wish to account for the gaps between keys, you'll need to do so via other means, and bake that into the image you provide to fillPanel.

    This method accepts either a path to an image on the disk, or a buffer. The image path or buffer is passed directly to sharp. Therefore, this method accepts all images and buffers which sharp can accept.

    Example
    // Fill the entire panel with a photo of a sunny field.
    streamDeck.fillPanel(path.resolve(__dirname, 'examples/fixtures/sunny_field.png'))
    	.then(() => {
    		console.log('Successfully filled the panel with an image.');
    	})
    	.catch(err => {
    		console.error(err);
    	});

    > streamDeck.clearKey(keyIndex) -> undefined

    Synchronously clears the given keyIndex's screen.

    Example
    // Clear the third button from the left in the first row.
    streamDeck.clearKey(2);

    > streamDeck.clearAllKeys() -> undefined

    Synchronously clears all keys on the device.

    Example
    // Clear all keys.
    streamDeck.clearAllKeys();

    > streamDeck.setBrightness(percentage) -> undefined

    Synchronously set the brightness of the Stream Deck. This affects all keys at once. The brightness of individual keys cannot be controlled.

    Example
    // Set the Stream Deck to maximum brightness
    streamDeck.setBrightness(100);

    Events

    > down

    Fired whenever a key is pressed. keyIndex is the 0-14 numerical index of that key.

    Example
    streamDeck.on('down', keyIndex => {
    	console.log('key %d down', keyIndex);
    });

    > up

    Fired whenever a key is released. keyIndex is the 0-14 numerical index of that key.

    Example
    streamDeck.on('up', keyIndex => {
    	console.log('key %d up', keyIndex);
    });

    > error

    Fired whenever an error is detected by the node-hid library. Always add a listener for this event! If you don't, errors will be silently dropped.

    Example
    streamDeck.on('error', error => {
    	console.error(error);
    });

    Protocol Notes

    Raw protocol notes can be found in NOTES.md. These detail the protocol and method for interacting with the Stream Deck which this module implements.

    0
    0
    0
    0
  • node-keytar (C++)

    keytar - Node module to manage system keychain

    Travis Build Status Windows Build Status Dependency Status

    A native Node module to get, add, replace, and delete passwords in system's keychain. On macOS the passwords are managed by the Keychain, on Linux they are managed by the Secret Service API/libsecret, and on Windows they are managed by Credential Vault.

    Installing

    npm install keytar

    On Linux

    Currently this library uses libsecret so you may need to install it before running npm install.

    Depending on your distribution, you will need to run the following command:

    • Debian/Ubuntu: sudo apt-get install libsecret-1-dev
    • Red Hat-based: sudo yum install libsecret-devel
    • Arch Linux: sudo pacman -S libsecret

    Building

    • Clone the repository
    • Run npm install
    • Run npm test to run the tests

    Docs

    const keytar = require('keytar')

    Every function in keytar is asynchronous and returns a promise. The promise will be rejected with any error that occurs or will be resolved with the function's "yields" value.

    getPassword(service, account)

    Get the stored password for the service and account.

    service - The string service name.

    account - The string account name.

    Yields the string password or null if an entry for the given service and account was not found.

    setPassword(service, account, password)

    Save the password for the service and account to the keychain. Adds a new entry if necessary, or updates an existing entry if one exists.

    service - The string service name.

    account - The string account name.

    password - The string password.

    Yields nothing.

    deletePassword(service, account)

    Delete the stored password for the service and account.

    service - The string service name.

    account - The string account name.

    Yields true if a password was deleted, or false if an entry with the given service and account was not found.

    findPassword(service)

    Find a password for the service in the keychain.

    service - The string service name.

    Yields the string password, or null if an entry for the given service and account was not found.

    findCredentials(service)

    Find all accounts and password for the service in the keychain.

    service - The string service name.

    Yields an array of { account: 'foo', password: 'bar' }.

    0
    0
    0
    0
  • POEditor (Objective-C)

    POEditor

    An easy to use class to get localisations from POEditor

    An easy to use class to get localisations from POEditor. Just drag POEditor.h and POEditor.m to Xcode. Then import POEditor.h and start to use it.

    I recogment to call

    [POEditor downloadDataWithAuthenticationToken:@"Your_Token" andProjectID:@"Your_Project_ID"];

    everytime the user starts the application, so the data always is up-to-date. Then you can replace

    NSLocalizedString(@"String", nil)

    with

    [POEditor localizedStringWithKey:@"String"]

    In addition you can get the contributors of your project. Just call

    [POEditor contributors];

    this will return a

    NSDictionary

    in this formate:

    @{@[Name, Email], Language}

    I implemented Xcodes dokumentation function to make it even easier to understand. Have fun and please make an issue if you miss a feature of find a bug. Have a nice day!

    You may enable "Localized resources can be mixed" in info.plist

    4
    4
    2
    0
  • SBNotification (Swift)

    SBNotification

    Simple Statusbar Notification written in Swift.

    alt tag

    It allows you to display notifications right on the StatusBar. Tap handlers are also supported!

    Either import the ready framework or drag SBNotification.xcodeproj into your project to reference it. Then import SBNotification

    Example:

    import SBNotification
    
    // This toggles a red notification without any tap handler
    SBNotificationManager.showNotification("Awesome Notification", duration: 20, type: .error)
    0
    0
    0
    0
  • ZeroAPS

    ZeroAPS

    Use a Raspberry Pi Zero and a few other components to build your compact close loop with OpenAPS

    I am also working on an ultra compact Intel Edison version

    I found an already working solution working with the Intel Edison, please use a 900MHz Explorer Board for Edison and refere to this guide.


    Deprecated

    Due to the closing of WirelessThings the RF module is not abailable anymore :(


    What you will need

    (Everything in [ ] is only used for the initial setup)

    • 1x Raspberry Pi Zero (Get a starter pack here)
      • 1x Micro SD Card 8GB
        To install Raspbian the OS the Raspberry Pi Zero is running
      • [Some way to connect your Raspberry Pi Zero to the internet]
        • I used an Raspberry Pi 2 I had laying around (I basically set up Raspbian and downloaded everything following on the Raspberry Pi 2/3 and then swap the micro SD card to the Raspberry Pi Zero
        • You also can use a WiFi USB dongle
      • [1x Micro HDMI to HDMI adapter]
      • [1x USB OTG to USB adapter]
      • [Keyboard]
    • 1x Power management aka PowerBoost (Power supply + Battery charger)
    • 1x Battery
    • 1x Radio Module All WirelessThings Products have been discontinued

    *Why I am using the SRF module instead of the SliceOfRadio? Because it basically is just a breakout board of the SRF module and we can do it ourself:)* * 1x [**CC-Debugger**](http://www.aliexpress.com/item/CC-Debugger-CCxxxx-Bluetooth-ZIGBEE-Wireless-Emulator-Programmer-for-RF-System-on-Chips/32417465960.html?spm=2114.13010608.0.55.1gfz18) to flash the chip with a custom software * Some soldering skills + soldering equipment * A steady hand * Tools (tweezers, side cutters, double foam sided tape...) * Basic Linux knowledge (mainly on the commandline) * And of course an [OpenAPS compatible pump](http://openaps.readthedocs.io/en/master/docs/walkthrough/phase-0/hardware.html)

    What you will get

    You will get a small portable Raspberry Pi Zero based device with a decent battery life (> 24 hours) and a much better and stabile communication to your pump. Thats all because we won't use that overpriced crappy CareLink stick.

    What you won't get

    You won't get a finished product that you can clip on like your insulin pump. It's basically just 3 PCBs glued together and bundled with a battery. I'm still working on a clip on option, but I still haven't had the right idea. Feel free to share yours:) You also won't get a complete guide on how to setup your close loop, but I include all the links, so just follow along and I am sure you will make it, if you can master diabetes you can you will master this!

    Don't hesitate to ask me if you have any questions.

    Lets start with the software

    1. You need to setup Raspbian, it is the operating system we use for the Raspberry Pi Zero
    • Download here. We are using Jessie Light because we don't need the fully fledged Raspbian
    • Once downloaded you need to burn the files to the SD card, follow this instructions and you are good to go
    1. Setup OpenAPS
    • The best source is the webpage it self, it is worth reading through the documentation
    • I don't use NightScout because I don't have any internet connectivity. Everything on my close loop happens locally.
    1. Prepare your radio module
    • Follow this tutorial to flash the radio module, below you will find the color codes matching the colors used in the tutorial SRF Footprint

    *This schematic is from [openmicros.org](http://openmicros.org/index.php/articles/88-ciseco-product-documentation/259-srf-technical-data)* 4. Setup [MMowlink](https://github.com/oskarpearson/mmeowlink/wiki/Installing-MMeowlink) (used to allow OpenAPS communicate with the radio module) if you have not already

    Now swap your micro SD card in your Raspberry Pi Zero if you have not already

    • If you want to access your Raspberry Pi Zero via USB there is an option for that 😊

    **(This only works if you don't need the USB OTG port!)** * The Raspberry Pi Zero is capable of emulating USB devices with the USB OTG port, so we can simulate an Ethernet adapter. If you connect your Raspberry Pi Zero with your PC the Raspberry will create its own network. This allows you to directly SSH into your Raspberry Pi Zero. Please keep in mind, that if you enable this you won't be able to use a USB device on your Raspberry Pi Zero anymore. * If you want to extend the battery live of your close loop you can disable the HDMI components and the ACT LED * Disable HDMI **(Keep in mind that you won't get any output on the HDMI port if you do this)** * Edit `rc.local by executing `sudo nano /etc/rc.local` in your Raspberry Pis command line * Add `/usr/bin/tvservice -o` before `exit 0` * Disable ACT LED **(The ACT LED is the little green LED that indicates, that your Raspberry Pi Zero is running)** * Follow [this](http://www.jeffgeerling.com/blogs/jeff-geerling/controlling-pwr-act-leds-raspberry-pi) instructions

    I recommend you to create a backup of your micro SD card, so you won't loos all the hard work!

    Congratulations, the software part is done 👍

    Start with the hardware part

    This may be a bit tricky if this is your first solder job, take your time and don't be frustrated if it is not working the first time.
    I am using an enamelled copper wire, so everything looks cleaner, but you can use normal wires to.
    Make sure, that there is some sort of isolation around the wires, so you won't short out your Raspberry Pi Zero

    1. We want to power the Raspberry Pi Zero
    • We can glue the PowerBoost PCB on the back of the Raspberry Pi Zero like this ZeroAPS with PowerBoost As a pro tip I also desoldered the PWR LED of the PowerBoost PCB (lower right side on the board), so can sleep better and won't get blind when looking at it.

      I am using a very strong double sided foam tape, be careful when placing it on the Raspberry Pi Zero, it is very hard to remove!

    • Next we need to solder the power wires from the PowerBoost to the Raspberry Pi Zero

      • 5V: Solder a wire from the PowerBoosts 5V output (on the lower side of the board) to the Raspberry Pi Zeros 5V GPIO pin 2
      • GND: Solder a wire from the PowerBoosts GND output (also on the lower side of the board) to the Raspberry Pi Zeros GND GPIO pin 6

      **Be careful when soldering directly to the GPIO pins. We are using the Raspberry Pi upside down, so double check what hole you solder to, desoldering is a pain in the arse if you don't have the right tools!**
      When you think everything is soldered correctly you can connect the battery. Your Raspberry Pi Zero should run from the battery if everything went well:) * If you disabled the ACK LED you will only see a very quick flash * You also can connect your Raspberry Pi Zero to the battery and also plug in the USB cable into Raspberry Pi Zeros USB OTG port to SSH into it. * **Disconnect the power again!**
    1. Communicate with the insulin pump
    1. Choose the right frequency
    • By default the MMowlink will use the US frequency which is awesome if you live in the US and have an US pump, but for us non US citizens we need to do an additional step
      • Every time the Raspberry Pi Zero boots we need to execute a little command to tune it for the World Wide frequency band
        • Edit rc.local by executing sudo nano /etc/rc.local in your Raspberry Pis command line
        • Add su pi -c '/home/pi/mmeowlink-source/bin/mmtune.py --port /dev/ttyAMA0 --radio_local WW --serial <PUMP_SERIAL_NUMBER> < /dev/null &' before exit 0

        *WW means World Wide*
    1. [Optional] Increase the range with an antenna
    • With the SRF module we already have a greater range then with the CareLink USB stick, but we can tweak it a bit by soldering an approximately 8cm (3,14 inch) wire to the SRF modules antenna hole. With this you can even penetrate a wall!
    1. Now check if everything works
    • The best way to check if everything works is to communicate with the pump

    Do this by `cd` in your `openaps` directory on your Raspberry Pi Zero, then you can execute `openaps use status` to get the current status of your pump. If you get a response that is formatted like a JSON everything you have done was right!
    If something is not working you need to find the issue. There is a trouble shooting guide below.

    Congratulations, your ZeroAPS is ready to use now 🎉

    Make it more compact

    Please be careful and don't destroy your Raspberry Pi Zero!


    This is more of a bloody hack, but it will make it more compact. My goal is to have only one USB port on the Raspberry Pi, but the PowerBoost won't let us access the data pins of the micro USB, so we will use 2 micro USB ports for now. (I already contacted Adafruit because of that feature)

    You can desolder the HDMI port and both micro USB ports of the Raspberry Pi. This makes it really flat. To compensate the lost USB OTG and power port you can glue an micro USB breakout board to a spare place on the other side of the Raspberry Pi Zero

    1. Desolder the USB ports

    **(First make sure you don't need them in the future, e.g for Dexcom receiver)** * Get power * Solder **GND** to **GND** of the PowerBoost * Solder **VCC (or 5V)** to **Bat** of the PowerBoost * Get data *(Directly solder to the gold pads on the Raspberry Pi)* * Solder **D+** to **PP22** * Solder **D-** to **PP23**
    1. Desolder the HDMI port
    • Yep, thats all 😊

    Thats how my APS is looking right now

    I will update this when I make any changes


    ZeroAPS from the top compared to a Medtronic MiniMed Paradigm 754 ZeroAPS from the top compared to a Paradigm 754 ZeroAPS from the side compared to a Medtronic MiniMed Paradigm 754 ZeroAPS from the side compared to a Paradigm 754

    Nice to know

    The current power consumption is about 140mA (If you disabled the ACT LED and the HDMI)
    With a 4400mAh battery we should have a battery live of about 31 hours which is not bad 😊

    Common issues you might run into

    • Faulty solder connections
      • Check your solder connections with a multimeter
    • Can't communicate with the pump because of "low battery" or "Out of range" error
      • You might use the wrong frequency
        • Step 3 of the the hardware part explains it well
      • Your pumps battery may really be low, go and check it!
      • Antenna soldering issues
        • Desolder the antenna, lay your pump near the Raspberry Pi Zero and try it again
      • SRF module is defect
        • I had an old one laying around, but it was broken. I checked it by measuring the voltage of the "HeartBeat"-Pin (Pin 1 on the SRF module board). The voltage should be around 3.3V when your Pi is connected to power.
    • The Raspberry Pi Zero can't be powered by the PowerBoost, but everything works when connecting the Pi directly to a USB port
      • Check if the PowerBoost is working correctly
        • Measure the voltage on the GND and 5V pins we soldered to (Battery or USB needs to be plugged in to the PowerBoost of course 😊)
        • Measure the voltage of the battery by connecting the multimeter leads to the Bat and GND hole. The voltage should be between 4.1V (Max) to 3.2V (Min, the red LOW LED will light up)
        • Check if the PWR LED is on. If you desoldered it, like I did, you can check the voltage. There should be around 5V.
    • OpenAPS does work with the SRF module
      • Repeat part 4 of "Lets start with the software"

    Contact me

    Please contact me if you are having questions about ZeroAPS.

    I can also borrow you the CC-Debugger if you live in Germany or Austria (Shipment goes on you).

    6
    6
    7
    0
Public Projects
  • Trolling Site (PHP)

    This website is a troll site targeting a german far right group named Reconquista Germanica. Reconquista Germanica is spreading hate against immigrants, refugees, disabled people, journalists, and many more, I just wanted to get the domain, before someone uses it for something bad 😏

  • I build this site for my vocational school colleagues.

  • OpenAppURL (PHP, HTML, SQL)

    OpenAppUrl is the place to find URL-Schemes for iOS, macOS, Android and Windows. All data is provided by you, help building this database!

Vita
HiddenApps
HiddenApps

HiddenApps was my most successful app ever, I got over 64.000 downloads in one day! However Apple blocked my developer account within one day, so I am missing some data. HiddenApps also got pulled from the AppStore real fast.

I was able to troll Apple and sneak this app in the AppStore, it allowed you to hide the default Apps like Passport, Weather, Music, and so on. You also could disabled all iAds!

This application kickstarted my career as a Software developer. I got invited to visit several businesses like Sharky Mobile and Loxone, that's where I work right now.

Going to Berlin
Going to Berlin

I got invited to visit Sharky Mobile in Berlin, approximately a 630km (1.008 miles) away.

It was a really funny and interesting time, I worked on a mobile Application written in Objective-C, but due to Apple "features" the App never made it in the AppStore 😞

iPwnStore
iPwnStore

I was the lead developer of the iPwnStore mobile application for iPhone and iPad. I was responsible for multiple releases.

Also some of the key features like notifications and other UI features do come from my hand.

Fily
Fily

Fily is a free modern file browser, capable of viewing and editing most files you find on your iOS device.

Download it for free on iPwnStore.

Apprenticeship by Loxone
Apprenticeship by Loxone

After HiddenApps I got invited to visit the Loxone basecamp in 2013.

I'm working in the "User Experience Cell", we are responsible for the Mobile App, Webinterface and other user interaction methods.

Vocational College
Vocational College

Because of my apprenticeship at Loxone I need to go to vocational College in Linz, Austria. I am moved in a small flat in the center of Linz, and I was visiting my home on the weekend.

Every new year we needed to do projects, like a promotion application for KlaBu, a digital time table, or a simple Homeautomation solution for one of our teacher.

In the last year we created a farewell clip to say good by to our colleagues and teachers.

It was a good time!

Certificate of apprenticeship with honors
Certificate of apprenticeship with honors

I finally got my certificate of apprenticeship with honors on the 21th of February 2017.

The apprenticeship was the best thing I could have done!

Working at Loxone
Working at Loxone

After I finished my apprenticeship at Loxone I was taken over and since then I am working there as a full time developer.

We are responsible for the Mobile App, Webinterface and other user interaction methods.

OpenAppUrl
OpenAppUrl

I always wanted to have a reliable database of available Url-Schemes.

Users can contribute known schemes their own or request schemes.

Please take a look and contribute your Url-Schemes now 😊

MCP 70-480
MCP 70-480

On the 14th of december 2018 I passed the Microsoft 70-480 exam on my first try 👌

I am now a Microsoft certified professional for HTML5 with JavaScript and CSS3 developer.

Music
My top 3 artist right now! 🎧
Sefa
Listened 227 times
227x
Angerfist
Listened 375 times
375x
Dr Peacock
Listened 124 times
124x
Here are the last tracks I listened to in the last hour, check them out. I really love music 😁
FireLight - (Neokontrol Remix)
For the Neighbors - Original Mix
Hit 'M - Radio Edit
Xtermination
FireLight - (Neokontrol Remix)
Imaginary Thought
The Sacrifice (Max Enforcer Remix)
Define Yourself (I AM HARDSTYLE 2018 Anthem)
Listen To Your Heart
Take It Back
Circles and Squares
Losing Myself
Drop 'Em Down
Instagram

Making #❄️ because nature is too lazy 🙄 #snow #winterlifestyle

@sefavl Thanks for making my year 2018!

Awesome time with #drpeacock at #qlimax in #🇳🇱

Awesome show at #qlimax in #🇳🇱 see you next year! #hardstyleismystyle #qdance

#SD18 #zombie Awesome show:) #qlimax is next😎#hardstyleismylife

Festival 2/4 this year:) #SummerBash #smallbutfun

#notelescope #lunareclipse #🌑 #mars I am surprised, how well the #iphonex makes photos at night!

#elf #vinivici Awesome show!

Travel Map
I love to travel, and one day I will have this map filled out 😊
Homebase
Visited
Next up
🤩 Waiting list
Images