diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..059295d
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 8e1e610..a699ff6 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ AlienFX is a Linux utility to control the lighting effects of your Alienware com
At present there is a CLI version (``alienfx``) and a gtk GUI version (``alienfx-gtk``). And
has been tested on Debian/Ubuntu/Kali, Fedora and Arch Linux.
-[![Version](https://img.shields.io/badge/version-2.1.2-red.svg)]() [![GitHub license](https://img.shields.io/github/license/trackmastersteve/alienfx.svg)](https://github.com/trackmastersteve/alienfx/tree/2.1.x/LICENSE) [![Python3](https://img.shields.io/badge/python-3.6-green.svg)]() [![GitHub issues](https://img.shields.io/github/issues/trackmastersteve/alienfx.svg)](https://github.com/trackmastersteve/alienfx/issues) [![GitHub stars](https://img.shields.io/github/stars/trackmastersteve/alienfx.svg)](https://github.com/trackmastersteve/alienfx/stargazers) [![GitHub forks](https://img.shields.io/github/forks/trackmastersteve/alienfx.svg)](https://github.com/trackmastersteve/alienfx/network)
+[![Version](https://img.shields.io/badge/version-2.2.0-red.svg)]() [![GitHub license](https://img.shields.io/github/license/trackmastersteve/alienfx.svg)](https://github.com/trackmastersteve/alienfx/tree/2.1.x/LICENSE) [![Python3](https://img.shields.io/badge/python-3.6-green.svg)]() [![GitHub issues](https://img.shields.io/github/issues/trackmastersteve/alienfx.svg)](https://github.com/trackmastersteve/alienfx/issues) [![GitHub stars](https://img.shields.io/github/stars/trackmastersteve/alienfx.svg)](https://github.com/trackmastersteve/alienfx/stargazers) [![GitHub forks](https://img.shields.io/github/forks/trackmastersteve/alienfx.svg)](https://github.com/trackmastersteve/alienfx/network)
## Table of Contents
@@ -25,7 +25,7 @@ For 2.0.6:
```sh
$ sudo pacman -S python2-pyusb python2-setuptools python2-gobject python2-cairo
```
-For 2.1.x:
+For 2.1+:
```sh
$ sudo pacman -S python-pyusb python-setuptools python-gobject python-cairo python-future
```
@@ -104,10 +104,10 @@ At present, AlienFX supports and has been tested on the following Alienware mode
6. M14xR1 Laptop - support by [Ashwin Menon](https://github.com/ashwinm76)
7. M14xR2 Laptop - (Needs the correct Zone Codes)
8. M14xR3 Laptop - (Needs the correct Zone Codes)
-9. M15x Laptop - support by [Gennadiy Chernyshyk](https://github.com/shatur95)
-10. M17x Laptop - support by [trackmastersteve](https://github.com/trackmastersteve)
+9. M15xR1 Laptop - support by [Gennadiy Chernyshyk](https://github.com/shatur95)
+10. M17xR1 Laptop - support by [trackmastersteve](https://github.com/trackmastersteve)
11. M17xR3 Laptop - (Needs the correct Zone Codes)
-12. M17xR4 Laptop - (Needs the correct Zone Codes)
+12. M17xR4 Laptop - support by [Dennis Marx](https://github.com/derco0n)
13. M18xR2 Laptop - (Needs the correct Zone Codes)
14. Aurora Desktop - support by [Bill Ochetski](https://github.com/ochetski)
15. 17R3 Laptop - (Needs the correct Zone Codes)
diff --git a/alienfx/core/controller.py b/alienfx/core/controller.py
index ea69df1..be34cad 100644
--- a/alienfx/core/controller.py
+++ b/alienfx/core/controller.py
@@ -36,6 +36,7 @@
import alienfx.core.usbdriver as alienfx_usbdriver
import alienfx.core.cmdpacket as alienfx_cmdpacket
+import alienfx.core.newcmdpacket as alienfx_newcmdpacket
from alienfx.core.themefile import AlienFXThemeFile
from functools import reduce
@@ -66,7 +67,9 @@ class AlienFXController(object):
ZONE_STATUS_LEDS = "Status LEDs"
ZONE_POWER_BUTTON = "Power Button"
ZONE_HDD_LEDS = "HDD LEDs"
-
+ ZONE_RIGHT_DISPLAY = "Right Display" # LED-bar display right side, as built in the AW17R4
+ ZONE_LEFT_DISPLAY = "Left Display" # LED-bar display left side, as built in the AW17R4
+
# State names
STATE_BOOT = "Boot"
STATE_AC_SLEEP = "AC Sleep"
@@ -75,6 +78,8 @@ class AlienFXController(object):
STATE_BATTERY_SLEEP = "Battery Sleep"
STATE_BATTERY_ON = "Battery On"
STATE_BATTERY_CRITICAL = "Battery Critical"
+
+ ALIENFX_CONTROLLER_TYPE = "old" #Modern Notebooks are using 8 bits per color. older ones just 4
def __init__(self):
self.zone_map = {}
@@ -83,9 +88,23 @@ def __init__(self):
self.state_map = {}
self.vendor_id = 0
self.product_id = 0
+ # if self.ALIENFX_CONTROLLER_TYPE == "new":
+ # New controller
+# self.cmd_packet = alienfx_newcmdpacket.NewAlienFXCmdPacket()
+ # else:
+ # Old Controller
self.cmd_packet = alienfx_cmdpacket.AlienFXCmdPacket()
+
self._driver = alienfx_usbdriver.AlienFXUSBDriver(self)
-
+
+ def switch_to_new_controller(self):
+ self.cmd_packet = alienfx_newcmdpacket.NewAlienFXCmdPacket()
+ return
+
+ def switch_to_old_controller(self):
+ self.cmd_packet = self.cmd_packet = alienfx_cmdpacket.AlienFXCmdPacket()
+ return
+
def get_zone_name(self, pkt):
""" Given 3 bytes of a command packet, return a string zone
name corresponding to it
diff --git a/alienfx/core/controller_m17xr4.py b/alienfx/core/controller_m17xr4.py
index 1bf6571..b17b3ec 100644
--- a/alienfx/core/controller_m17xr4.py
+++ b/alienfx/core/controller_m17xr4.py
@@ -41,34 +41,78 @@ class AlienFXControllerM17xR4(alienfx_controller.AlienFXController):
# the lowest value that will not result in strange blink/morph behaviour.
DEFAULT_SPEED = 200
MIN_SPEED = 50
-
+
+ # reverse-engineer-knowledgebase:
+ # ###############################
+ # NOTICE:
+ # it seems that alienfx is using doubles for base zone adresses...
+ # there are a lot more zone- and command-codes which are doing things we dont know about (yet),
+ # like -for example- setting multiple zones to different colors ans such stuff
+ # i think that these are used (or can be used) by some games
+ #
+ # States: Some zone seem to be only be accessed in some states.
+ # Caution: different settings for a zone in different states may interfere, so that flashing can happen...
+ #
+ # 0x0001 Keyboard right
+ # 0x0002 Keyboard middle-right
+ # 0x0004 Keyboard middle-left
+ # 0x0008 Keyboard left
+ # 0x000F Keyboard: all fields <= interesting: 0x1 + 0x2 + 0x4 + 0x8 = 0xF
+ # 0x0010 unknown...
+ # 0x0020 Alienhead (Display outside)
+ # 0x0040 Alienware-Logo
+ # 0x0050 may be: Alienware logo?
+ # 0x0080 Touchpad
+ # 0x0100 Power button
+ # 0x0200 unknown...
+ #
+ # side-bars:
+ # ==========
+ # 0x0400 seems bottom left
+ # 0x0800 seems bottom right
+ # 0x1000 seems top (display) left
+ # 0x2000 seems top (display) right
+ #
+ # 0x4000 seems keyboard macrokey-bar (left)
+
# Zone codes
- LEFT_KEYBOARD = 0x0008
- MIDDLE_LEFT_KEYBOARD = 0x0004
- MIDDLE_RIGHT_KEYBOARD = 0x0002
- RIGHT_KEYBOARD = 0x0001
- # Both speakers change together
- RIGHT_SPEAKER = 0x0020
- LEFT_SPEAKER = 0x0040
- ALIEN_HEAD = 0x0080
- LOGO = 0x0100
- TOUCH_PAD = 0x0200
- MEDIA_BAR = 0x0800
- POWER_BUTTON = 0x2000
- HDD_LEDS = 0x4000
+ LEFT_KEYBOARD = 0x0008 # Code OK
+ MIDDLE_LEFT_KEYBOARD = 0x0004 # Code OK
+ MIDDLE_RIGHT_KEYBOARD = 0x0002 # Code OK
+ RIGHT_KEYBOARD = 0x0001 # Code OK
+
+ RIGHT_SPEAKER = 0x0800 # Code OK, Bottom - Right light bar
+ LEFT_SPEAKER = 0x0400 # Code OK, Bottom - Left light bar
+ LEFT_DISPLAY = 0x1000 # Code OK, Display - Left light bar
+ RIGHT_DISPLAY = 0x2000 # Code OK, Display - Right light bar
+
+ ALIEN_HEAD = 0x0020 # Code OK
+ LOGO = 0x0040 # Code OK. Alienware-logo below screen.
+ # 0x0060 seems to bee alien head and logo 0x20+0x40=0x60
+
+ # Touchpad:
+ # Seems OK. You may need to set touchpad-lightning to always on in BIOS for this to work,
+ # as the on-touch-event seems to be not recognized correctly
+ TOUCH_PAD = 0x0080 # Code OK. Have a look at your BIOS settings.
+ MEDIA_BAR = 0x4000 # Seems OK. If Media_Bar should be Macro-Key-Bar
+ POWER_BUTTON = 0x0100 # Seems OK. Caution: S1 (Boot) conflicts with settings for other states...
+ # HDD_LEDS = 0xf001 # Inactive: Device has no hdd indicator
# Reset codes
RESET_ALL_LIGHTS_OFF = 3
RESET_ALL_LIGHTS_ON = 4
# State codes
- BOOT = 1
+ BOOT = 1 # Seems some zone can only be defined by Boot-State and have no effect on higher states
AC_SLEEP = 2
AC_CHARGED = 5
AC_CHARGING = 6
BATTERY_SLEEP = 7
BATTERY_ON = 8
BATTERY_CRITICAL = 9
+
+ #Controller Type
+ MYCONTROLLER = "new" #Defines the controllertype: old=pre Alienware 17R4 (4 bits per color) / new=AW17R4 and probably others, which are using 8 bits per color
def __init__(self):
alienfx_controller.AlienFXController.__init__(self)
@@ -77,6 +121,13 @@ def __init__(self):
# USB VID and PID
self.vendor_id = 0x187c
self.product_id = 0x0530
+
+ #Switch Controllertype
+ if self.MYCONTROLLER == "new":
+ self.switch_to_new_controller()
+ else:
+ self.switch_to_old_controller()
+
# map the zone names to their codes
self.zone_map = {
@@ -91,13 +142,16 @@ def __init__(self):
self.ZONE_TOUCH_PAD: self.TOUCH_PAD,
self.ZONE_MEDIA_BAR: self.MEDIA_BAR,
self.ZONE_POWER_BUTTON: self.POWER_BUTTON,
- self.ZONE_HDD_LEDS: self.HDD_LEDS,
+ self.ZONE_LEFT_DISPLAY: self.LEFT_DISPLAY,
+ self.ZONE_RIGHT_DISPLAY: self.RIGHT_DISPLAY
+ # self.ZONE_HDD_LEDS: self.HDD_LEDS, # Not used, as de AW17R4 does not have an HDD indicator
+
}
# zones that have special behaviour in the different power states
self.power_zones = [
- self.ZONE_POWER_BUTTON,
- self.ZONE_HDD_LEDS
+ self.ZONE_POWER_BUTTON # ,
+ # self.ZONE_HDD_LEDS
]
# map the reset names to their codes
diff --git a/alienfx/core/newcmdpacket.py b/alienfx/core/newcmdpacket.py
new file mode 100644
index 0000000..c3b83f2
--- /dev/null
+++ b/alienfx/core/newcmdpacket.py
@@ -0,0 +1,367 @@
+#
+# newcmdpacket.py
+##
+# based on cmdpacket.py of the alienfx-package, developed by the following authors
+# Copyright (C) 2013-2014 Ashwin Menon
+# Copyright (C) 2015-2018 Track Master Steve
+#
+# This Version is modified by Dennis Marx (https://github.com/derco0n) to meet the requirement of newer alienfx-controller-chips
+# as newer chips are using 8 instead of 4 bit per color
+#
+# Alienfx is free software.
+#
+# You may redistribute it and/or modify it under the terms of the
+# GNU General Public License, as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option)
+# any later version.
+#
+# Alienfx is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with alienfx. If not, write to:
+# The Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor
+# Boston, MA 02110-1301, USA.
+#
+
+""" Base class for AlienFX command packets. This may be subclassed for
+specific controllers.
+
+This module provides the following classes:
+AlienFXCmdPacket: base class for AlienFX command packets
+"""
+
+from builtins import hex
+from builtins import object
+
+
+class NewAlienFXCmdPacket(object):
+
+ """Provides facilities to parse and create packets
+
+ This class provides methods to parse binary packets into human readable
+ strings. It also provides methods to create binary packets.
+
+ As this is for newer alienfx controllers which are setting 8-bits per color (256 values from 0-255 each) we have to convert the color.json-values as they are 4-bits (16 values from 0-15)
+
+ """
+
+
+
+ # Command codes
+ CMD_SET_MORPH_COLOUR = 0x1
+ CMD_SET_BLINK_COLOUR = 0x2
+ CMD_SET_COLOUR = 0x3
+ CMD_LOOP_BLOCK_END = 0x4
+ CMD_TRANSMIT_EXECUTE = 0x5
+ CMD_GET_STATUS = 0x6
+ CMD_RESET = 0x7
+ CMD_SAVE_NEXT = 0x8
+ CMD_SAVE = 0x9
+ CMD_SET_SPEED = 0xe
+
+ # Status codes
+ STATUS_BUSY = 0x11
+ STATUS_READY = 0x10
+ STATUS_UNKNOWN_COMMAND = 0x12
+
+ PACKET_LENGTH = 12
+
+ command_parsers = {}
+
+ def __init__(self):
+ self.command_parsers = {
+ self.CMD_SET_MORPH_COLOUR: self._parse_cmd_set_morph_colour,
+ self.CMD_SET_BLINK_COLOUR: self._parse_cmd_set_blink_colour,
+ self.CMD_SET_COLOUR: self._parse_cmd_set_colour,
+ self.CMD_LOOP_BLOCK_END: self._parse_cmd_loop_block_end,
+ self.CMD_TRANSMIT_EXECUTE: self._parse_cmd_transmit_execute,
+ self.CMD_GET_STATUS: self._parse_cmd_get_status,
+ self.CMD_RESET: self._parse_cmd_reset,
+ self.CMD_SAVE_NEXT: self._parse_cmd_save_next,
+ self.CMD_SAVE: self._parse_cmd_save,
+ self.CMD_SET_SPEED: self._parse_cmd_set_speed
+ }
+
+ @staticmethod
+ def _unpack_colour_pair(pkt):
+ """ Unpack two colour values from the given packet and return them as a
+ list of two tuples (each colour is a 3-member tuple)
+
+ TODO: i think this ist still bullshit for the newer controller
+ """
+ red1 = hex(pkt[0] >> 4)
+ green1 = hex(pkt[0] & 0xf)
+ blue1 = hex(pkt[1] >> 4)
+ red2 = hex(pkt[1] & 0xf)
+ green2 = hex(pkt[2] >> 4)
+ blue2 = hex(pkt[2] & 0xf)
+ return [(red1, green1, blue1), (red2, green2, blue2)]
+
+ @staticmethod
+ def _pack_colour_pair(colour1, colour2):
+ """ Pack two colours into a list of bytes and return the list. Each
+ colour is a 3-member tuple
+ """
+ (red1, green1, blue1) = colour1
+ (red2, green2, blue2) = colour2
+ # pkt = []
+ # pkt.append(((red1&0xf)<<4) + (green1&0xf))
+ # pkt.append(((blue1&0xf)<<4) + (red2&0xf))
+ # pkt.append(((green2&0xf)<<4) + (blue2&0xf))
+ pkt = []
+ red8_1 = red1 / float(15) * 255
+ green8_1 = green1 / float(15) * 255
+ blue8_1 = blue1 / float(15) * 255
+ red8_2 = red2 / float(15) * 255
+ green8_2 = green2 / float(15) * 255
+ blue8_2 = blue2 / float(15) * 255
+ pkt.append(int(red8_1))
+ pkt.append(int(green8_1))
+ pkt.append(int(blue8_1))
+ pkt.append(int(red8_2))
+ pkt.append(int(green8_2))
+ pkt.append(int(blue8_2))
+ return pkt
+
+ @staticmethod
+ def _unpack_colour(pkt):
+ """ Unpack a colour value from the given packet and return it as a
+ 3-member tuple
+
+ TODO: This mist still be bullshit too
+ """
+ red = hex(pkt[0] >> 4)
+ green = hex(pkt[0] & 0xf)
+ blue = hex(pkt[1] >> 4)
+ return (red, green, blue)
+
+ @staticmethod
+ def _pack_colour(colour):
+ """ Pack a colour into a list of bytes and return the list. The
+ colour is a 3-member tuple
+ """
+ (red, green, blue) = colour
+ pkt = []
+ # pkt = [255, 0, 255] # DEBUG should set every color to pink (100% red, 0% green, 100% blue)
+ red8 = red / float(15) * 255
+ green8 = green / float(15) * 255
+ blue8 = blue / float(15) * 255
+ # pkt = [255, 255, 0] # DEBUG
+ pkt.append(int(red8))
+ pkt.append(int(green8))
+ pkt.append(int(blue8))
+ return pkt
+
+ @classmethod
+ def _parse_cmd_set_morph_colour(cls, args):
+ """ Parse a packet containing the "set morph colour" command and
+ return it as a human readable string.
+ """
+ pkt = args["pkt"]
+ controller = args["controller"]
+ [(red1, green1, blue1), (red2, green2, blue2)] = (
+ cls._unpack_colour_pair(pkt[6:9]))
+ msg = "SET_MORPH_COLOUR: "
+ msg += "BLOCK: {}".format(pkt[2])
+ msg += ", ZONE: {}".format(controller.get_zone_name(pkt[3:6]))
+ msg += ", ({},{},{})-({},{},{})".format(
+ red1, green1, blue1, red2, green2, blue2)
+ return msg
+
+ @classmethod
+ def _parse_cmd_set_blink_colour(cls, args):
+ """ Parse a packet containing the "set blink colour" command and
+ return it as a human readable string.
+ """
+ pkt = args["pkt"]
+ controller = args["controller"]
+ (red, green, blue) = cls._unpack_colour(pkt[6:8])
+ msg = "SET_BLINK_COLOUR: "
+ msg += "BLOCK: {}".format(pkt[2])
+ msg += ", ZONE: {}".format(controller.get_zone_name(pkt[3:6]))
+ msg += ", ({},{},{})".format(red, green, blue)
+ return msg
+
+ @classmethod
+ def _parse_cmd_set_colour(cls, args):
+ """ Parse a packet containing the "set colour" command and
+ return it as a human readable string.
+ """
+ pkt = args["pkt"]
+ controller = args["controller"]
+ (red, green, blue) = cls._unpack_colour(pkt[6:8])
+ msg = "SET_COLOUR: "
+ msg += "BLOCK: {}".format(pkt[2])
+ msg += ", ZONE: {}".format(controller.get_zone_name(pkt[3:6]))
+ msg += ", ({},{},{})".format(red, green, blue)
+ return msg
+
+ @classmethod
+ def _parse_cmd_loop_block_end(cls, args):
+ """ Parse a packet containing the "loop block end" command and
+ return it as a human readable string.
+ """
+ return "LOOP_BLOCK_END"
+
+ @classmethod
+ def _parse_cmd_transmit_execute(cls, args):
+ """ Parse a packet containing the "transmit execute" command and
+ return it as a human readable string.
+ """
+ return "TRANSMIT_EXECUTE"
+
+ @classmethod
+ def _parse_cmd_get_status(cls, args):
+ """ Parse a packet containing the "get status" command and
+ return it as a human readable string.
+ """
+ return "GET_STATUS"
+
+ @classmethod
+ def _parse_cmd_reset(cls, args):
+ """ Parse a packet containing the "reset" command and
+ return it as a human readable string.
+ """
+ pkt = args["pkt"]
+ controller = args["controller"]
+ return "RESET: {}".format(controller.get_reset_type_name(pkt[2]))
+
+ @classmethod
+ def _parse_cmd_save_next(cls, args):
+ """ Parse a packet containing the "save next" command and
+ return it as a human readable string.
+ """
+ pkt = args["pkt"]
+ controller = args["controller"]
+ return "SAVE_NEXT: STATE {}".format(controller.get_state_name(pkt[2]))
+
+ @classmethod
+ def _parse_cmd_save(cls, args):
+ """ Parse a packet containing the "save" command and
+ return it as a human readable string.
+ """
+ return "SAVE"
+
+ @classmethod
+ def _parse_cmd_set_speed(cls, args):
+ """ Parse a packet containing the "set speed" command and
+ return it as a human readable string.
+ """
+ pkt = args["pkt"]
+ return "SET_SPEED: {}".format(hex((pkt[2] << 8) + pkt[3]))
+
+ @classmethod
+ def _parse_cmd_unknown(cls, args):
+ """ Return a string reporting an unknown command packet.
+ """
+ pkt = args["pkt"]
+ return "UNKNOWN COMMAND : {} IN PACKET {}".format(pkt[1], pkt)
+
+ def pkt_to_string(self, pkt_bytes, controller):
+ """ Return a human readable string representation of a command packet.
+ """
+ if (len(pkt_bytes) != self.PACKET_LENGTH):
+ return "BAD PACKET: {}".format(pkt_bytes)
+ else:
+ cmd = pkt_bytes[1]
+ args = {"pkt": pkt_bytes, "controller": controller}
+ if (cmd in list(self.command_parsers.keys())):
+ return self.command_parsers[cmd](args)
+ else:
+ return self._parse_cmd_unknown(args)
+
+ @classmethod
+ def make_cmd_set_morph_colour(cls, block, zone, colour1, colour2):
+ """ Return a command packet for the "set morph colour" command with the
+ given parameters.
+ """
+ pkt = [0x02, cls.CMD_SET_MORPH_COLOUR, 0, 0, 0, 0, 0, 0, 0]
+ pkt[2] = block & 0xff
+ pkt[3:6] = [(zone&0xff0000) >> 16, (zone&0xff00) >> 8, zone & 0xff]
+ pkt[6:9] = cls._pack_colour_pair(colour1, colour2)
+ return pkt
+
+ @classmethod
+ def make_cmd_set_blink_colour(cls, block, zone, colour):
+ """ Return a command packet for the "set blink colour" command with the
+ given parameters.
+ """
+ pkt = [0x02, cls.CMD_SET_BLINK_COLOUR, 0, 0, 0, 0, 0, 0, 0]
+ pkt[2] = block & 0xff
+ pkt[3:6] = [(zone&0xff0000) >> 16, (zone&0xff00) >> 8, zone & 0xff]
+ pkt[6:8] = cls._pack_colour(colour)
+ return pkt
+
+ @classmethod
+ def make_cmd_set_colour(cls, block, zone, colour):
+ """ Return a command packet for the "set colour" command with the
+ given parameters.
+ """
+ pkt = [0x02, cls.CMD_SET_COLOUR, 0, 0, 0, 0, 0, 0, 0]
+ pkt[2] = block & 0xff
+ pkt[3:6] = [(zone&0xff0000) >> 16, (zone&0xff00) >> 8, zone & 0xff]
+ pkt[6:8] = cls._pack_colour(colour)
+ return pkt
+
+ @classmethod
+ def make_cmd_loop_block_end(cls):
+ """ Return a command packet for the "loop block end" command with the
+ given parameters.
+ """
+ pkt = [0x02, cls.CMD_LOOP_BLOCK_END, 0, 0, 0, 0, 0, 0, 0]
+ return pkt
+
+ @classmethod
+ def make_cmd_transmit_execute(cls):
+ """ Return a command packet for the "transmit execute" command with the
+ given parameters.
+ """
+ pkt = [0x02, cls.CMD_TRANSMIT_EXECUTE, 0, 0, 0, 0, 0, 0, 0]
+ return pkt
+
+ @classmethod
+ def make_cmd_get_status(cls):
+ """ Return a command packet for the "get status" command with the
+ given parameters.
+ """
+ pkt = [0x02, cls.CMD_GET_STATUS, 0, 0, 0, 0, 0, 0, 0]
+ return pkt
+
+ @classmethod
+ def make_cmd_reset(cls, reset_type):
+ """ Return a command packet for the "reset" command with the
+ given parameters.
+ """
+ pkt = [0x02, cls.CMD_RESET, 0, 0, 0, 0, 0, 0, 0]
+ pkt[2] = reset_type & 0xff
+ return pkt
+
+ @classmethod
+ def make_cmd_save_next(cls, state):
+ """ Return a command packet for the "save next" command with the
+ given parameters.
+ """
+ pkt = [0x02, cls.CMD_SAVE_NEXT, 0, 0, 0, 0, 0, 0, 0]
+ pkt[2] = state & 0xff
+ return pkt
+
+ @classmethod
+ def make_cmd_save(cls):
+ """ Return a command packet for the "save" command with the
+ given parameters.
+ """
+ pkt = [0x02, cls.CMD_SAVE, 0, 0, 0, 0, 0, 0, 0]
+ return pkt
+
+ @classmethod
+ def make_cmd_set_speed(cls, speed):
+ """ Return a command packet for the "set speed" command with the
+ given parameters.
+ """
+ pkt = [0x02, cls.CMD_SET_SPEED, 0, 0, 0, 0, 0, 0, 0]
+ pkt[2:4] = [(speed&0xff00) >> 8, speed & 0xff]
+ return pkt
diff --git a/alienfx/core/usbdriver.py b/alienfx/core/usbdriver.py
index 726be03..ff2d52d 100644
--- a/alienfx/core/usbdriver.py
+++ b/alienfx/core/usbdriver.py
@@ -36,6 +36,7 @@
import usb
from usb import USBError
+
class AlienFXUSBDriver(object):
""" Provides low level acquire/release and read/write access to an AlienFX
@@ -80,6 +81,7 @@ def read_packet(self):
return pkt
except USBError as exc:
logging.error("read_packet: {}".format(exc))
+
def acquire(self):
""" Acquire control from libusb of the AlienFX controller."""
diff --git a/alienfx/data/themes/17r4_allblue.json b/alienfx/data/themes/17r4_allblue.json
new file mode 100644
index 0000000..1a871f1
--- /dev/null
+++ b/alienfx/data/themes/17r4_allblue.json
@@ -0,0 +1,439 @@
+{
+ "Battery On": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Boot": [
+ {
+ "zones": [
+ "Right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Alien Head"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Logo"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Touchpad"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Critical": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "blink"
+ }
+ ]
+ }
+ ],
+ "AC Charged": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "AC Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "speed": 200,
+ "AC Charging": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ],
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ }
+ ]
+}
diff --git a/alienfx/data/themes/17r4_allgreen.json b/alienfx/data/themes/17r4_allgreen.json
new file mode 100644
index 0000000..2f1478a
--- /dev/null
+++ b/alienfx/data/themes/17r4_allgreen.json
@@ -0,0 +1,439 @@
+{
+ "Battery On": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Boot": [
+ {
+ "zones": [
+ "Right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Alien Head"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Logo"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Touchpad"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Critical": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "blink"
+ }
+ ]
+ }
+ ],
+ "AC Charged": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "AC Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "speed": 200,
+ "AC Charging": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ],
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ }
+ ]
+}
diff --git a/alienfx/data/themes/17r4_allred.json b/alienfx/data/themes/17r4_allred.json
new file mode 100644
index 0000000..cdd6677
--- /dev/null
+++ b/alienfx/data/themes/17r4_allred.json
@@ -0,0 +1,439 @@
+{
+ "Battery On": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Boot": [
+ {
+ "zones": [
+ "Right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Alien Head"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Logo"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Touchpad"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Critical": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "blink"
+ }
+ ]
+ }
+ ],
+ "AC Charged": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "AC Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "speed": 200,
+ "AC Charging": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ],
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ }
+ ]
+}
diff --git a/alienfx/data/themes/17r4_derco0n_green-red.json b/alienfx/data/themes/17r4_derco0n_green-red.json
new file mode 100644
index 0000000..529ddbb
--- /dev/null
+++ b/alienfx/data/themes/17r4_derco0n_green-red.json
@@ -0,0 +1,745 @@
+{
+ "Battery On": [
+ {
+ "zones": [
+ "Power Button"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Boot": [
+ {
+ "zones": [
+ "Right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ],
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ],
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ],
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ],
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "blink"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "blink"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Alien Head"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Logo"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Touchpad"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 10,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ],
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Critical": [
+ {
+ "zones": [
+ "Power Button"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "blink"
+ }
+ ]
+ }
+ ],
+ "AC Charged": [
+ {
+ "zones": [
+ "Power Button"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Sleep": [
+ {
+ "zones": [
+ "Power Button"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 0
+ ],
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 15,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "AC Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "speed": 200,
+ "AC Charging": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 15,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 0
+ ],
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ }
+ ]
+}
diff --git a/alienfx/data/themes/17r4_flag_fr.json b/alienfx/data/themes/17r4_flag_fr.json
new file mode 100644
index 0000000..7d948a6
--- /dev/null
+++ b/alienfx/data/themes/17r4_flag_fr.json
@@ -0,0 +1,439 @@
+{
+ "Battery On": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Boot": [
+ {
+ "zones": [
+ "Right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Alien Head"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Logo"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Touchpad"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Critical": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "blink"
+ }
+ ]
+ }
+ ],
+ "AC Charged": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "AC Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "speed": 200,
+ "AC Charging": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ],
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ }
+ ]
+}
diff --git a/alienfx/data/themes/17r4_flag_ge.json b/alienfx/data/themes/17r4_flag_ge.json
new file mode 100644
index 0000000..48c9a41
--- /dev/null
+++ b/alienfx/data/themes/17r4_flag_ge.json
@@ -0,0 +1,439 @@
+{
+ "Battery On": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Boot": [
+ {
+ "zones": [
+ "Right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Alien Head"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Logo"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Touchpad"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Critical": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "blink"
+ }
+ ]
+ }
+ ],
+ "AC Charged": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 0
+ ],
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 15,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "AC Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "speed": 200,
+ "AC Charging": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 15,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 0
+ ],
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ }
+ ]
+}
diff --git a/alienfx/data/themes/17r4_flag_it.json b/alienfx/data/themes/17r4_flag_it.json
new file mode 100644
index 0000000..053f147
--- /dev/null
+++ b/alienfx/data/themes/17r4_flag_it.json
@@ -0,0 +1,439 @@
+{
+ "Battery On": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Boot": [
+ {
+ "zones": [
+ "Right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Alien Head"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Logo"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Touchpad"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 15,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Critical": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "blink"
+ }
+ ]
+ }
+ ],
+ "AC Charged": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "AC Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "speed": 200,
+ "AC Charging": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ }
+ ]
+}
diff --git a/alienfx/data/themes/17r4_flag_us.json b/alienfx/data/themes/17r4_flag_us.json
new file mode 100644
index 0000000..a7e326c
--- /dev/null
+++ b/alienfx/data/themes/17r4_flag_us.json
@@ -0,0 +1,439 @@
+{
+ "Battery On": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Boot": [
+ {
+ "zones": [
+ "Right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-right Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Middle-left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Speaker"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Right Display"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Alien Head"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Logo"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Touchpad"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 15,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Critical": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "blink"
+ }
+ ]
+ }
+ ],
+ "AC Charged": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "Battery Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "AC Sleep": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ],
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ },
+ {
+ "zones": [
+ "Left Keyboard",
+ "Middle-left Keyboard",
+ "Middle-right Keyboard",
+ "Right Keyboard",
+ "Right Speaker",
+ "Left Speaker",
+ "Logo",
+ "Touchpad",
+ "Media Bar"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 0
+ ]
+ ],
+ "type": "fixed"
+ }
+ ]
+ }
+ ],
+ "speed": 200,
+ "AC Charging": [
+ {
+ "zones": [
+ "Power Button",
+ "HDD LEDs"
+ ],
+ "loop": [
+ {
+ "colours": [
+ [
+ 0,
+ 0,
+ 15
+ ],
+ [
+ 15,
+ 9,
+ 0
+ ]
+ ],
+ "type": "morph"
+ },
+ {
+ "colours": [
+ [
+ 15,
+ 9,
+ 0
+ ],
+ [
+ 0,
+ 0,
+ 15
+ ]
+ ],
+ "type": "morph"
+ }
+ ]
+ }
+ ]
+}
diff --git a/alienfx/ui/console/__init__.py b/alienfx/ui/console/__init__.py
index 5801304..9d3232c 100644
--- a/alienfx/ui/console/__init__.py
+++ b/alienfx/ui/console/__init__.py
@@ -1,2 +1,4 @@
from __future__ import absolute_import
-from .main import start
+from alienfx.ui.console.main import start
+
+# start() # debug (needed for debugging in pycharm)
diff --git a/alienfx/ui/console/main.py b/alienfx/ui/console/main.py
index dbe81d6..9357ae5 100644
--- a/alienfx/ui/console/main.py
+++ b/alienfx/ui/console/main.py
@@ -36,9 +36,10 @@
import alienfx.core.themefile as alienfx_themefile
import alienfx.core.logger as alienfx_logger
+
def start():
""" Main entry point for the alienfx cli."""
-
+
controller = AlienFXProber.get_controller()
if controller is None:
logging.error("No supported Alien FX controllers found!")
diff --git a/alienfx/ui/gtkui/__init__.py b/alienfx/ui/gtkui/__init__.py
index abf174f..49d576d 100644
--- a/alienfx/ui/gtkui/__init__.py
+++ b/alienfx/ui/gtkui/__init__.py
@@ -1,2 +1,4 @@
from __future__ import absolute_import
-from .gtkui import start
+from alienfx.ui.gtkui.gtkui import start
+
+# start() # debug (needed for debugging in pycharm)
diff --git a/docs/man/alienfx.1 b/docs/man/alienfx.1
index 2909433..5944641 100644
--- a/docs/man/alienfx.1
+++ b/docs/man/alienfx.1
@@ -1,7 +1,7 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.5.
-.TH ALIENFX "1" "April 2018" "alienfx 2.1.2" "User Commands"
+.TH ALIENFX "1" "July 2018" "alienfx 2.2.0" "User Commands"
.SH NAME
-alienfx \- manual page for alienfx 2.1.2
+alienfx \- manual page for alienfx 2.2.0
.SH SYNOPSIS
.B alienfx
[\fIOPTION\fP]...
diff --git a/old_afxcontroller-protocoll-documentaion b/old_afxcontroller-protocoll-documentaion
new file mode 100644
index 0000000..d760f7c
--- /dev/null
+++ b/old_afxcontroller-protocoll-documentaion
@@ -0,0 +1,224 @@
+
+AlienFX device-specific protocol
+================================
+
+Terminology
+-----------
+
+ - **Device**:
+ An AlienFX USB device.
+
+ - **Zone**:
+ A (or a set of) LED which share a sequence.
+
+ - **Action**:
+ The lighting behavior for zones. This includes Morph, Pulse, and Color.
+
+ - **Morph**:
+ - **Pulse**:
+ - **Color**:
+
+ - **Sequence**:
+ An ordered list of actions.
+
+ - **Theme**:
+ A set of sequences and corresponding zones.
+
+
+Device Configuration
+--------------------
+
+ - use configuration 1
+ - occasionally, kernel drivers need to be disabled
+
+
+URB Setup
+---------
+
+### Sending
+
+ - bmRequestType = 0x21
+
+ 0... .... : Host to Device
+ .01. .... : Request Type = Class
+ ...0 0001 : Recipient = Interface
+
+ - bRequest = 9 (Constant)
+ - wValue = 0x0202 (Constant)
+ - wIndex = 0 (Constant)
+ - wLength = 9 (Constant. Smaller message must be padded with 0)
+
+
+### Receiving
+
+ - bmRequestType = 0xa1
+
+ 1... .... : Device to Host
+ .01. .... : Request Type = Class
+ ...0 0001 : Recipient = Interface
+
+ - bRequest = 9 (Constant)
+ - wValue = 0x0202 (Constant)
+ - wIndex = 0 (Constant)
+ - wLength = 9 (Constant)
+
+
+### (Unkown)
+
+ - AFAIK, not sending this packet does no harm.
+ - bmRequestType = 0x21
+ - bRequest = 10
+ - wValue = 0 (Constant)
+ - wIndex = 0 (Constant)
+ - wLength = 0 (Constant)
+
+
+Commands
+--------
+
+### 0x01: Morph ###
+
+ 02:01:nn:00:zz:zz:rg:bR:GB
+
+ n : Sequence ID
+ z : Zone
+ r : Red 1
+ g : Green 1
+ b : Blue 1
+ R : Red 2
+ G : Green 2
+ B : Blue 2
+
+ - The color changes from `rgb` to `RGB`
+
+
+### 0x02: Pulse ###
+
+ 02:02:nn:00:zz:zz:rg:b0:
+
+ n : Sequence ID
+ z : Zone
+ r : Red
+ g : Green
+ b : Blue
+
+
+### 0x03: Color ###
+
+ 02:03:nn:00:zz:zz:rg:b0:
+
+ n : Sequence ID
+ z : Zone
+ r : Red
+ g : Green
+ b : Blue
+
+
+### 0x04: Loop
+
+ 02:04: : : : : : :
+
+ - Without this, LEDs will go off after walking through the user-specified
+ color sequence.
+ - (TODO: how does this know which sequence is the target? The last one
+ mentioned? What happens if sequences are interleaved?)
+
+
+### 0x05: Execute
+
+ 02:05: : : : : : :
+
+ - This must be called at the end.
+ - Start executing color sequences.
+
+
+### 0x06: Update Status code
+
+ 02:06: : : : : : :
+
+ - The status code has to be retrieved manually.
+ (See URB-Receiving)
+
+
+### 0x07: Reset?
+
+ 02:07:tt: : : : : :
+
+ t : type
+
+ - This takes some time, and you should wait until the operation ends.
+ Premature commands might fail.
+
+
+### 0x08: Save-To
+
+ 02:08:ss: : : : : :
+
+ s : slot
+
+ - Save the next command to the specified slot.
+ - Must be followed by an Action or Loop
+ - (TODO: better name?)
+
+### 0x09: Write Slots
+
+ 02:09: : : : : : :
+
+ - Save slots permanently.
+ - If this command is not called, data slots will be lost on reboot.
+ (TODO: direct experiment)
+ - (TODO: better name)
+
+
+### 0x0E: Tempo
+
+ 02:0E:tt:tt: : : : :
+
+ t: Tempo
+
+ - AlienFX sets this value between 00:1e ~ 03:ae
+ - Lower is faster
+
+
+### 0x1C: Dim
+
+ 02:1C:oo:bb: : : : :
+
+ o: 32 (Enable)
+ 64 (Disable)
+ b: 01 (Always)
+ 00 (in Battery Mode Only)
+
+
+### 0x1D: (Unknown)
+
+ 02:1d:03: : : : : : (on apply)
+ 02:1d:81: : : : : : (on go-dark)
+
+
+Contants
+--------
+
+### Reset
+
+ - (TODO: tbh, this section, entirely)
+ - 00: reset keyboard
+ - 01: reset keyboard
+ - 02: (TODO)
+ - 03: reset all
+ this also stops the execution of sequences
+ - 04: (TODO)
+
+
+### Slots
+
+ - 01: Initial State
+ - 02: Plugged in - Sleep
+ + Only the power-button works in this mode?
+ - 05: Plugged in - Normal
+ - 06: Plugged in - Charging
+ - 07: On Battery - Sleep
+ - 08: On Battery - Normal
+ - 09: On Battery - Low
+ - (TODO: better title)
+
diff --git a/setup.py b/setup.py
index 4bbd001..d270441 100644
--- a/setup.py
+++ b/setup.py
@@ -53,7 +53,7 @@
setup(
name = "alienfx",
- version = "2.1.2",
+ version = "2.2.0",
fullname = "AlienFX Configuration Utility",
description = "AlienFX Configuration Utility",
author = "Track Master Steve",