mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-28 05:06:43 +00:00
fd628: remove addon
This commit is contained in:
parent
0019bbb7db
commit
91594773df
@ -1,13 +0,0 @@
|
|||||||
110
|
|
||||||
- Rewrite add-on from scratch
|
|
||||||
- Add support for APPS, SETUP, CVBS (X92) and POWER (A1 Max) indicators.
|
|
||||||
- Add a configuration dialog:
|
|
||||||
* Adjust display brightness.
|
|
||||||
* Storage access indication.
|
|
||||||
* Advanced hardware configuration of the display.
|
|
||||||
- Fix crash if aml_fd628 module is not loaded (led_on, led_off files don't exist)
|
|
||||||
- Fix disable add-on from Kodi UI.
|
|
||||||
- Turn off indicators when add-on is disabled.
|
|
||||||
|
|
||||||
100
|
|
||||||
- Initial add-on
|
|
Binary file not shown.
Before Width: | Height: | Size: 31 KiB |
@ -1,30 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
PKG_NAME="fd628"
|
|
||||||
PKG_VERSION="1.1"
|
|
||||||
PKG_REV="100"
|
|
||||||
PKG_ARCH="any"
|
|
||||||
PKG_LICENSE="GPL"
|
|
||||||
PKG_SITE="https://libreelec.tv"
|
|
||||||
PKG_URL=""
|
|
||||||
PKG_DEPENDS_TARGET="toolchain"
|
|
||||||
PKG_SECTION="service"
|
|
||||||
PKG_SHORTDESC="fd628: Kodi service to light up additional icons on devices with FD628 display"
|
|
||||||
PKG_LONGDESC="fd628: Kodi service to light up additional icons on devices with FD628 display"
|
|
||||||
PKG_TOOLCHAIN="manual"
|
|
||||||
|
|
||||||
PKG_IS_ADDON="yes"
|
|
||||||
PKG_ADDON_NAME="service.fd628"
|
|
||||||
PKG_ADDON_PROJECTS="S905 S912"
|
|
||||||
PKG_ADDON_TYPE="xbmc.service"
|
|
||||||
|
|
||||||
make_target() {
|
|
||||||
sed -e "s|@PKG_VERSION@|$PKG_VERSION|g" \
|
|
||||||
-i addon.xml
|
|
||||||
}
|
|
||||||
|
|
||||||
addon() {
|
|
||||||
mkdir -p $ADDON_BUILD/$PKG_ADDON_ID
|
|
||||||
cp -R $PKG_BUILD/* $ADDON_BUILD/$PKG_ADDON_ID
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
<addon id="service.fd628"
|
|
||||||
name="FD628 Display"
|
|
||||||
version="@PKG_VERSION@"
|
|
||||||
provider-name="Team LibreELEC">
|
|
||||||
<requires>
|
|
||||||
<import addon="xbmc.python" version="2.1.0"/>
|
|
||||||
</requires>
|
|
||||||
<extension point="xbmc.service"
|
|
||||||
library="resources/lib/service.py"
|
|
||||||
start="startup">
|
|
||||||
</extension>
|
|
||||||
<extension point="xbmc.addon.metadata">
|
|
||||||
<summary>Service for controlling FD628 VFD display icons</summary>
|
|
||||||
<description>Service for controlling FD628 VFD display icons, e.g. Ethernet/WiFi connection status and Time</description>
|
|
||||||
<platform>all</platform>
|
|
||||||
<assets>
|
|
||||||
<icon>resources/icon.png</icon>
|
|
||||||
</assets>
|
|
||||||
</extension>
|
|
||||||
</addon>
|
|
||||||
|
|
@ -1,136 +0,0 @@
|
|||||||
# Kodi Media Center language file
|
|
||||||
# Addon Name: FD628 Display
|
|
||||||
# Addon id: service.fd628
|
|
||||||
# Addon Provider: Team LibreELEC
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: XBMC-Addons\n"
|
|
||||||
"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
|
|
||||||
"POT-Creation-Date: 2018-02-12 17:48+0200\n"
|
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
||||||
"Language-Team: LANGUAGE\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"Language: en_GB\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
|
||||||
|
|
||||||
# Kodi Settings
|
|
||||||
msgctxt "#30000"
|
|
||||||
msgid "General"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30001"
|
|
||||||
msgid "Turn on display"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30002"
|
|
||||||
msgid "Display brightness"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30003"
|
|
||||||
msgid "Advanced settings"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30004"
|
|
||||||
msgid "Display type"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30026"
|
|
||||||
msgid "Common anode display (transposed ram)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30013"
|
|
||||||
msgid "Enable storage access (RW) indicator"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30014"
|
|
||||||
msgid "Select which icon is to be used as the access indicator"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30028"
|
|
||||||
msgid "Clock colon (:) always on"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30015"
|
|
||||||
msgid "play"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30016"
|
|
||||||
msgid "pause"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30017"
|
|
||||||
msgid "hdmi"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30018"
|
|
||||||
msgid "cvbs"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30019"
|
|
||||||
msgid "eth"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30020"
|
|
||||||
msgid "wifi"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30021"
|
|
||||||
msgid "setup"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30022"
|
|
||||||
msgid "apps"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30023"
|
|
||||||
msgid "usb"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30024"
|
|
||||||
msgid "sd"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30025"
|
|
||||||
msgid "alarm"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30027"
|
|
||||||
msgid "power"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30012"
|
|
||||||
msgid "Reorder character indexes"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30005"
|
|
||||||
msgid "Index 0"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30006"
|
|
||||||
msgid "Index 1"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30007"
|
|
||||||
msgid "Index 2"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30008"
|
|
||||||
msgid "Index 3"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30009"
|
|
||||||
msgid "Index 4"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30010"
|
|
||||||
msgid "Index 5"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgctxt "#30011"
|
|
||||||
msgid "Index 6"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# Max index 30028
|
|
@ -1,78 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import os
|
|
||||||
import struct
|
|
||||||
from fd628utils import *
|
|
||||||
|
|
||||||
_led_cmd = '/sys/class/leds/le-vfd/led_cmd'
|
|
||||||
|
|
||||||
class fd628Dev:
|
|
||||||
def __init__(self):
|
|
||||||
import ioctl
|
|
||||||
import ctypes
|
|
||||||
size = ctypes.sizeof(ctypes.c_int(0))
|
|
||||||
self._FD628_IOC_MAGIC = ord('M')
|
|
||||||
self._FD628_IOC_SMODE = ioctl.IOW(self._FD628_IOC_MAGIC, 1, size)
|
|
||||||
self._FD628_IOC_GMODE = ioctl.IOR(self._FD628_IOC_MAGIC, 2, size)
|
|
||||||
self._FD628_IOC_SBRIGHT = ioctl.IOW(self._FD628_IOC_MAGIC, 3, size)
|
|
||||||
self._FD628_IOC_GBRIGHT = ioctl.IOR(self._FD628_IOC_MAGIC, 4, size)
|
|
||||||
self._FD628_IOC_POWER = ioctl.IOW(self._FD628_IOC_MAGIC, 5, size)
|
|
||||||
self._FD628_IOC_GVER = ioctl.IOR(self._FD628_IOC_MAGIC, 6, size)
|
|
||||||
self._FD628_IOC_STATUS_LED = ioctl.IOW(self._FD628_IOC_MAGIC, 7, size)
|
|
||||||
self._FD628_IOC_GDISPLAY_TYPE = ioctl.IOR(self._FD628_IOC_MAGIC, 8, size)
|
|
||||||
self._FD628_IOC_SDISPLAY_TYPE = ioctl.IOW(self._FD628_IOC_MAGIC, 9, size)
|
|
||||||
self._FD628_IOC_SCHARS_ORDER = ioctl.IOW(self._FD628_IOC_MAGIC, 10, 7)
|
|
||||||
self._FD628_IOC_USE_DTB_CONFIG = ioctl.IOW(self._FD628_IOC_MAGIC, 11, size)
|
|
||||||
self._FD628_IOC_MAXNR = 12
|
|
||||||
|
|
||||||
def enableDisplay(self, value):
|
|
||||||
self.__writeFD628(self._FD628_IOC_POWER, int(value))
|
|
||||||
|
|
||||||
def getBrightness(self):
|
|
||||||
return self.__readFD628(self._FD628_IOC_GBRIGHT)
|
|
||||||
|
|
||||||
def setBrightness(self, value):
|
|
||||||
self.__writeFD628(self._FD628_IOC_SBRIGHT, value)
|
|
||||||
|
|
||||||
def getDisplayType(self):
|
|
||||||
return self.__readFD628(self._FD628_IOC_GDISPLAY_TYPE)
|
|
||||||
|
|
||||||
def setDisplayType(self, value):
|
|
||||||
self.__writeFD628(self._FD628_IOC_SDISPLAY_TYPE, value)
|
|
||||||
|
|
||||||
def setCharacterOrder(self, value):
|
|
||||||
pack = struct.pack('BBBBBBB', value[0], value[1], value[2], value[3], value[4], value[5], value[6])
|
|
||||||
self.__writeFD628(self._FD628_IOC_SCHARS_ORDER, pack, True)
|
|
||||||
|
|
||||||
def useDtbConfig(self):
|
|
||||||
self.__writeFD628(self._FD628_IOC_USE_DTB_CONFIG, 0)
|
|
||||||
|
|
||||||
def __readFD628(self, cmd, isBuf = False):
|
|
||||||
import ioctl
|
|
||||||
ret = None
|
|
||||||
if (ioctl.DIR(cmd) == ioctl.READ and self.__writeFD628(cmd, 0)):
|
|
||||||
with open(_led_cmd, "rb") as vfd:
|
|
||||||
ret = vfd.read()
|
|
||||||
if (ret == ''):
|
|
||||||
ret = None
|
|
||||||
if (not isBuf and ret != None):
|
|
||||||
ret = int(ret, 0)
|
|
||||||
kodiLog('fd628Dev.__readFD628: value = {0}'.format(str(ret)))
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __writeFD628(self, cmd, value, isBuf = False):
|
|
||||||
ret = False
|
|
||||||
if (os.path.isfile(_led_cmd)):
|
|
||||||
if isBuf:
|
|
||||||
value = ''.join([struct.pack('I', cmd), value])
|
|
||||||
else:
|
|
||||||
value = struct.pack('Ii', cmd, value)
|
|
||||||
kodiLog('fd628Dev.__writeFD628: value = {0}'.format(repr(value)))
|
|
||||||
try:
|
|
||||||
with open(_led_cmd, "wb") as vfd:
|
|
||||||
vfd.write(value)
|
|
||||||
ret = True
|
|
||||||
except Exception as inst:
|
|
||||||
kodiLogError(inst)
|
|
||||||
return ret
|
|
@ -1,95 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import xbmcaddon
|
|
||||||
|
|
||||||
addon = xbmcaddon.Addon(id='service.fd628')
|
|
||||||
|
|
||||||
def getSetting(id):
|
|
||||||
return addon.getSetting(id)
|
|
||||||
|
|
||||||
def getSettingBool(id):
|
|
||||||
value = getSetting(id).lower()
|
|
||||||
if (value == 'true'):
|
|
||||||
value = True
|
|
||||||
else:
|
|
||||||
value = False
|
|
||||||
return value
|
|
||||||
|
|
||||||
def getSettingInt(id):
|
|
||||||
return int(getSetting(id))
|
|
||||||
|
|
||||||
def getSettingNumber(id):
|
|
||||||
return float(getSetting(id))
|
|
||||||
|
|
||||||
class fd628Settings:
|
|
||||||
def __init__(self):
|
|
||||||
self.readValues()
|
|
||||||
|
|
||||||
def isDisplayOn(self):
|
|
||||||
return self._displayOn
|
|
||||||
|
|
||||||
def isAdvancedSettings(self):
|
|
||||||
return self._displayAdvanced
|
|
||||||
|
|
||||||
def getBrightness(self):
|
|
||||||
return self._displayBrightness
|
|
||||||
|
|
||||||
def getDisplayType(self):
|
|
||||||
return self._displayType
|
|
||||||
|
|
||||||
def isCommonAnode(self):
|
|
||||||
return self._commonAnode
|
|
||||||
|
|
||||||
def getDisplay(self):
|
|
||||||
value = self.getDisplayType()
|
|
||||||
if (self.isCommonAnode()):
|
|
||||||
value = value + (1 << 16)
|
|
||||||
return value
|
|
||||||
|
|
||||||
def getCharacterIndex(self, i):
|
|
||||||
return self._characterIndexes[i]
|
|
||||||
|
|
||||||
def getCharacterIndexes(self):
|
|
||||||
return self._characterIndexes
|
|
||||||
|
|
||||||
def isStorageIndicator(self):
|
|
||||||
return self._storageIndicator
|
|
||||||
|
|
||||||
def getStorageIndicatorIcon(self):
|
|
||||||
return self._storageIndicatorIcon
|
|
||||||
|
|
||||||
def isColonOn(self):
|
|
||||||
return self._colonOn
|
|
||||||
|
|
||||||
def readValues(self):
|
|
||||||
self._displayAdvanced = False
|
|
||||||
self._displayOn = getSettingBool('display.on')
|
|
||||||
if (self._displayOn):
|
|
||||||
self._displayBrightness = getSettingInt('display.brightness')
|
|
||||||
self._storageIndicator = getSettingBool('display.storage.indicator')
|
|
||||||
self._storageIndicatorIcon = getSetting('display.storage.indicator.icon')
|
|
||||||
self._colonOn = getSettingBool('display.colon.on')
|
|
||||||
self._displayAdvanced = getSettingBool('display.advanced')
|
|
||||||
if (self._displayAdvanced):
|
|
||||||
self._displayType = getSettingInt('display.type')
|
|
||||||
self._commonAnode = getSettingBool('display.common.anode')
|
|
||||||
self._characterIndexes = []
|
|
||||||
for i in range(7):
|
|
||||||
self._characterIndexes.append(getSettingInt('display.char.index{0}'.format(i)))
|
|
||||||
else:
|
|
||||||
self.__initDefaultValues()
|
|
||||||
else:
|
|
||||||
self.__initDefaultValues()
|
|
||||||
|
|
||||||
def __initDefaultValues(self):
|
|
||||||
if not (self._displayOn):
|
|
||||||
self._displayBrightness = 7
|
|
||||||
self._storageIndicator = False
|
|
||||||
self._storageIndicatorIcon = ''
|
|
||||||
self._colonOn = False
|
|
||||||
self._displayAdvanced = False
|
|
||||||
if not (self._displayAdvanced):
|
|
||||||
self._displayType = 0
|
|
||||||
self._commonAnode = False
|
|
||||||
self._characterIndexes = range(0, 7)
|
|
@ -1,187 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import xbmc
|
|
||||||
import os
|
|
||||||
from fd628utils import *
|
|
||||||
|
|
||||||
class fd628State(object):
|
|
||||||
def __init__(self, ledName):
|
|
||||||
self._value = False
|
|
||||||
self._hasChanged = False
|
|
||||||
self._ledName = ledName
|
|
||||||
|
|
||||||
def _getStr(self, className):
|
|
||||||
return '{0} ({1})'.format(className, self._ledName)
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def getValue(self):
|
|
||||||
return self._value
|
|
||||||
|
|
||||||
def hasChanged(self):
|
|
||||||
return self._hasChanged
|
|
||||||
|
|
||||||
def getLedName(self):
|
|
||||||
return self._ledName
|
|
||||||
|
|
||||||
def _update(self, value):
|
|
||||||
if (value != self._value):
|
|
||||||
self._hasChanged = True
|
|
||||||
self._value = value
|
|
||||||
else:
|
|
||||||
self._hasChanged = False
|
|
||||||
|
|
||||||
class fd628IconIndicator(fd628State):
|
|
||||||
def __init__(self, on, ledName):
|
|
||||||
super(fd628IconIndicator, self).__init__(ledName)
|
|
||||||
self._on = on
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._getStr('fd628IconIndicator')
|
|
||||||
|
|
||||||
def turnOn(self):
|
|
||||||
self._on = True
|
|
||||||
|
|
||||||
def turnOff(self):
|
|
||||||
self._on = False
|
|
||||||
|
|
||||||
def toggle(self):
|
|
||||||
self._on = not self._on
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
self._update(self._on)
|
|
||||||
|
|
||||||
class fd628CondVisibility(fd628State):
|
|
||||||
def __init__(self, ledName, cmd):
|
|
||||||
super(fd628CondVisibility, self).__init__(ledName)
|
|
||||||
self._cmd = cmd
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._getStr('fd628CondVisibility')
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
value = xbmc.getCondVisibility(self._cmd)
|
|
||||||
self._update(value)
|
|
||||||
|
|
||||||
class fd628FileContains(fd628State):
|
|
||||||
def __init__(self, ledName, path, strings):
|
|
||||||
super(fd628FileContains, self).__init__(ledName)
|
|
||||||
self._path = path
|
|
||||||
self._strings = strings
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._getStr('fd628FileContains')
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
if (os.path.isfile(self._path)):
|
|
||||||
with open(self._path, 'rb') as state:
|
|
||||||
content = state.read()
|
|
||||||
value = self.__checkContent(content)
|
|
||||||
self._update(value)
|
|
||||||
else:
|
|
||||||
self._update(False)
|
|
||||||
|
|
||||||
def __checkContent(self, content):
|
|
||||||
ret = False
|
|
||||||
for s in self._strings:
|
|
||||||
if (s in content):
|
|
||||||
ret = True
|
|
||||||
break
|
|
||||||
return ret
|
|
||||||
|
|
||||||
class fd628WindowChecker(fd628State):
|
|
||||||
def __init__(self, ledName, windows):
|
|
||||||
super(fd628WindowChecker, self).__init__(ledName)
|
|
||||||
self._windows = windows
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._getStr('fd628WindowChecker')
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
value = False
|
|
||||||
for id in self._windows:
|
|
||||||
if (xbmc.getCondVisibility('Window.IsVisible({0})'.format(id))):
|
|
||||||
value = True
|
|
||||||
break
|
|
||||||
self._update(value)
|
|
||||||
|
|
||||||
class fd628ExtStorageChecker(fd628State):
|
|
||||||
def __init__(self, ledName, path):
|
|
||||||
super(fd628ExtStorageChecker, self).__init__(ledName)
|
|
||||||
self._path = path
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._getStr('fd628ExtStorageChecker')
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
value = False
|
|
||||||
for folder, subs, files in os.walk('/dev/disk/by-uuid'):
|
|
||||||
for filename in files:
|
|
||||||
path = os.path.realpath(os.path.join(folder, filename))
|
|
||||||
if (path.startswith(self._path)):
|
|
||||||
value = True
|
|
||||||
break
|
|
||||||
self._update(value)
|
|
||||||
|
|
||||||
class fd628ExtStorageCount(fd628State):
|
|
||||||
def __init__(self, ledName, drives, type):
|
|
||||||
super(fd628ExtStorageCount, self).__init__(ledName)
|
|
||||||
if (drives == None): # Monitor all drives
|
|
||||||
self._drives = None
|
|
||||||
drives = self.__getAllDrives()
|
|
||||||
else: # Monitor listed drives
|
|
||||||
self._drives = drives
|
|
||||||
drives = self.__getSelectedDrives()
|
|
||||||
self._driveStats = {key: self.__readStatus(key) for key in drives}
|
|
||||||
kodiLogNotice('fd628ExtStorageCount.__init__: Drive stats ' + str(self._driveStats))
|
|
||||||
self._read = False
|
|
||||||
self._write = False
|
|
||||||
if (type == 'r'):
|
|
||||||
self._read = True
|
|
||||||
elif (type == 'w'):
|
|
||||||
self._write = True
|
|
||||||
elif (type == 'rw'):
|
|
||||||
self._read = True
|
|
||||||
self._write = True
|
|
||||||
else:
|
|
||||||
raise Exception('\'type\' must be \'r\', \'w\' or \'rw\'.')
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
value = False
|
|
||||||
if (self._drives == None):
|
|
||||||
drives = self.__getAllDrives()
|
|
||||||
else:
|
|
||||||
drives = self.__getSelectedDrives()
|
|
||||||
for drive in drives:
|
|
||||||
if (not drive in self._driveStats):
|
|
||||||
self._driveStats[drive] = None
|
|
||||||
kodiLogNotice('fd628ExtStorageCount.update: New drive found \'{0}\''.format(drive))
|
|
||||||
for path, stats in self._driveStats.iteritems():
|
|
||||||
newStats = self.__readStatus(path)
|
|
||||||
if (stats != None and newStats != None):
|
|
||||||
if (self._read):
|
|
||||||
value = value or stats[0] != newStats[0]
|
|
||||||
if (self._write):
|
|
||||||
value = value or stats[1] != newStats[1]
|
|
||||||
self._driveStats[path] = newStats
|
|
||||||
self._update(value)
|
|
||||||
|
|
||||||
def __readStatus(self, path):
|
|
||||||
path = os.path.join('/sys/block', path, 'stat')
|
|
||||||
if (os.path.isfile(path)):
|
|
||||||
with open(path, 'rb') as status:
|
|
||||||
values = status.read().split()
|
|
||||||
return (values[2], values[6])
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def __getAllDrives(self):
|
|
||||||
drives = []
|
|
||||||
for folder, subs, files in os.walk('/sys/block'):
|
|
||||||
drives = [sub for sub in subs if (not sub.startswith('loop'))]
|
|
||||||
return drives
|
|
||||||
|
|
||||||
def __getSelectedDrives(self):
|
|
||||||
return [drive for drive in self.__getAllDrives() if ([d for d in self._drives if drive.startswith(d)])]
|
|
@ -1,19 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import xbmc
|
|
||||||
import xbmcaddon
|
|
||||||
|
|
||||||
addonName = xbmcaddon.Addon(id='service.fd628').getAddonInfo('name')
|
|
||||||
|
|
||||||
def kodiLog(message, level = xbmc.LOGDEBUG):
|
|
||||||
xbmc.log('{0} -> {1}'.format(addonName, str(message)), level)
|
|
||||||
|
|
||||||
def kodiLogError(message):
|
|
||||||
kodiLog(message, xbmc.LOGERROR)
|
|
||||||
|
|
||||||
def kodiLogWarning(message):
|
|
||||||
kodiLog(message, xbmc.LOGWARNING)
|
|
||||||
|
|
||||||
def kodiLogNotice(message):
|
|
||||||
kodiLog(message, xbmc.LOGNOTICE)
|
|
@ -1,89 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
"""
|
|
||||||
Author: SpliFF
|
|
||||||
License: Public Domain
|
|
||||||
|
|
||||||
Python ioctl constants and functions module
|
|
||||||
|
|
||||||
Mostly follows specifications in asm-generic/ioctl.h from linux 2.5.36
|
|
||||||
|
|
||||||
Notable differences:
|
|
||||||
* no architecture dependant stuff
|
|
||||||
* size parameters are all passed as bytes, not types (ie pass 4, not int)
|
|
||||||
|
|
||||||
!! WARNING EXPERIMENTAL SOFTWARE !!
|
|
||||||
Make sure the values returned by these functions are properly tested before using fcntl on anything remotely valuable!
|
|
||||||
"""
|
|
||||||
|
|
||||||
NRBITS = 8
|
|
||||||
TYPEBITS = 8
|
|
||||||
|
|
||||||
# may be arch dependent
|
|
||||||
|
|
||||||
SIZEBITS = 14
|
|
||||||
DIRBITS = 2
|
|
||||||
|
|
||||||
NRMASK = (1 << NRBITS) - 1
|
|
||||||
TYPEMASK = (1 << TYPEBITS) - 1
|
|
||||||
SIZEMASK = (1 << SIZEBITS) - 1
|
|
||||||
DIRMASK = (1 << DIRBITS) - 1
|
|
||||||
|
|
||||||
NRSHIFT = 0
|
|
||||||
TYPESHIFT = NRSHIFT + NRBITS
|
|
||||||
SIZESHIFT = TYPESHIFT + TYPEBITS
|
|
||||||
DIRSHIFT = SIZESHIFT + SIZEBITS
|
|
||||||
|
|
||||||
# may be arch dependent
|
|
||||||
|
|
||||||
NONE = 0x0
|
|
||||||
WRITE = 0x1
|
|
||||||
READ = 0x2
|
|
||||||
|
|
||||||
# for the drivers/sound files...
|
|
||||||
|
|
||||||
IN = WRITE << DIRSHIFT
|
|
||||||
OUT = READ << DIRSHIFT
|
|
||||||
INOUT = (WRITE | READ) << DIRSHIFT
|
|
||||||
IOCSIZE_MASK = SIZEMASK << SIZESHIFT
|
|
||||||
IOCSIZE_SHIFT = SIZESHIFT
|
|
||||||
|
|
||||||
# used to create numbers ...
|
|
||||||
|
|
||||||
def IO( _type, nr):
|
|
||||||
return IOC(NONE, _type, nr, 0)
|
|
||||||
|
|
||||||
def IOC(direction, _type, nr, size):
|
|
||||||
return (direction << DIRSHIFT) | (_type << TYPESHIFT) | (nr << NRSHIFT) | (size << SIZESHIFT)
|
|
||||||
|
|
||||||
def IOR( _type, nr, size):
|
|
||||||
return IOC(READ, _type, nr, size)
|
|
||||||
|
|
||||||
def IOW(_type, nr, size):
|
|
||||||
return IOC(WRITE, _type, nr, size)
|
|
||||||
|
|
||||||
def IOWR(_type, nr, size):
|
|
||||||
return IOC(READ|WRITE, _type, nr, size)
|
|
||||||
|
|
||||||
def IOR_BAD(_type, nr, size):
|
|
||||||
return IOC(READ, _type, nr, size)
|
|
||||||
|
|
||||||
def IOW_BAD(_type, nr, size):
|
|
||||||
return IOC(WRITE, _type, nr, size)
|
|
||||||
|
|
||||||
def IOWR_BAD(_type, nr, size):
|
|
||||||
return IOC(READ|WRITE, _type, nr, size)
|
|
||||||
|
|
||||||
# used to decode ioctl numbers..
|
|
||||||
|
|
||||||
def DIR(nr):
|
|
||||||
return (nr >> DIRSHIFT) & DIRMASK
|
|
||||||
|
|
||||||
def TYPE(nr):
|
|
||||||
return (nr >> TYPESHIFT) & TYPEMASK
|
|
||||||
|
|
||||||
def NR(nr):
|
|
||||||
return (nr >> NRSHIFT) & NRMASK
|
|
||||||
|
|
||||||
def SIZE(nr):
|
|
||||||
return (nr >> SIZESHIFT) & SIZEMASK
|
|
@ -1,143 +0,0 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
|
|
||||||
|
|
||||||
import xbmcaddon
|
|
||||||
import threading
|
|
||||||
import os
|
|
||||||
import fd628states
|
|
||||||
import fd628dev
|
|
||||||
import fd628settings
|
|
||||||
from fd628utils import *
|
|
||||||
|
|
||||||
addon = xbmcaddon.Addon(id='service.fd628')
|
|
||||||
|
|
||||||
class fd628Monitor(xbmc.Monitor):
|
|
||||||
def __init__(self):
|
|
||||||
super(fd628Monitor, self).__init__()
|
|
||||||
self._settingsChangedCallback = None
|
|
||||||
|
|
||||||
def setSettingsChangedCallback(self, callbackObject):
|
|
||||||
self._settingsChangedCallback = callbackObject
|
|
||||||
|
|
||||||
def onSettingsChanged(self):
|
|
||||||
kodiLog('Enter fd628Monitor.onSettingsChanged')
|
|
||||||
if (self._settingsChangedCallback != None):
|
|
||||||
self._settingsChangedCallback.onSettingsChanged()
|
|
||||||
|
|
||||||
class fd628Addon():
|
|
||||||
def __init__(self, monitor):
|
|
||||||
self._fd628 = fd628dev.fd628Dev()
|
|
||||||
self._states = []
|
|
||||||
self._monitor = monitor
|
|
||||||
self._monitor.setSettingsChangedCallback(self)
|
|
||||||
self._settings = fd628settings.fd628Settings()
|
|
||||||
self._vfdon = '/sys/class/leds/le-vfd/led_on'
|
|
||||||
self._vfdoff = '/sys/class/leds/le-vfd/led_off'
|
|
||||||
self._rlock = threading.RLock()
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
firstLoop = True
|
|
||||||
while not self._monitor.abortRequested():
|
|
||||||
if self._monitor.waitForAbort(0.5):
|
|
||||||
break
|
|
||||||
if (not os.path.isfile(self._vfdon) or not os.path.isfile(self._vfdoff)):
|
|
||||||
firstLoop = True
|
|
||||||
continue
|
|
||||||
if (firstLoop):
|
|
||||||
self.onSettingsChanged()
|
|
||||||
firstLoop = False
|
|
||||||
self.__updateIndicators()
|
|
||||||
self.__cleanUp()
|
|
||||||
|
|
||||||
def __updateIndicators(self):
|
|
||||||
ledon = []
|
|
||||||
ledoff = []
|
|
||||||
if (self._rlock.acquire()):
|
|
||||||
for state in self._states:
|
|
||||||
state.update()
|
|
||||||
if (state.hasChanged()):
|
|
||||||
if (state.getValue()):
|
|
||||||
ledon.append(state.getLedName())
|
|
||||||
else:
|
|
||||||
ledoff.append(state.getLedName())
|
|
||||||
self.__writeFile(self._vfdon, ledon)
|
|
||||||
self.__writeFile(self._vfdoff, ledoff)
|
|
||||||
self._rlock.release()
|
|
||||||
|
|
||||||
def __cleanUp(self):
|
|
||||||
self.__turnOffIndicators()
|
|
||||||
self._monitor = None
|
|
||||||
|
|
||||||
def __turnOffIndicators(self):
|
|
||||||
if (self._rlock.acquire()):
|
|
||||||
ledoff = [state.getLedName() for state in self._states]
|
|
||||||
self.__writeFile(self._vfdoff, ledoff)
|
|
||||||
self._rlock.release()
|
|
||||||
|
|
||||||
def __writeFile(self, path, values):
|
|
||||||
if (os.path.isfile(path)):
|
|
||||||
with open(path, "wb") as vfd:
|
|
||||||
for j in values:
|
|
||||||
vfd.write(j)
|
|
||||||
vfd.flush()
|
|
||||||
|
|
||||||
def onSettingsChanged(self):
|
|
||||||
kodiLog('Enter fd628Addon.onSettingsChanged')
|
|
||||||
self._settings.readValues()
|
|
||||||
if (self._rlock.acquire()):
|
|
||||||
self.__createStates()
|
|
||||||
self._fd628.enableDisplay(self._settings.isDisplayOn())
|
|
||||||
if (self._settings.isDisplayOn()):
|
|
||||||
self._fd628.setBrightness(self._settings.getBrightness())
|
|
||||||
if (self._settings.isAdvancedSettings()):
|
|
||||||
self._fd628.setDisplayType(self._settings.getDisplay())
|
|
||||||
self._fd628.setCharacterOrder(self._settings.getCharacterIndexes())
|
|
||||||
else:
|
|
||||||
self._fd628.useDtbConfig()
|
|
||||||
if (self._colonIcon != None and self._settings.isColonOn()):
|
|
||||||
self._colonIcon.turnOn()
|
|
||||||
self.__updateIndicators()
|
|
||||||
self._rlock.release()
|
|
||||||
kodiLog('isDisplayOn = {0}'.format(self._settings.isDisplayOn()))
|
|
||||||
kodiLog('getBrightness = {0}'.format(self._settings.getBrightness()))
|
|
||||||
kodiLog('isAdvancedSettings = {0}'.format(self._settings.isAdvancedSettings()))
|
|
||||||
kodiLog('getDisplayType = {0}'.format(self._settings.getDisplayType()))
|
|
||||||
kodiLog('isCommonAnode = {0}'.format(self._settings.isCommonAnode()))
|
|
||||||
kodiLog('getCharacterIndexex = {0}'.format(self._settings.getCharacterIndexes()))
|
|
||||||
|
|
||||||
def __createStates(self):
|
|
||||||
settingsWindows = ['settings', 'systeminfo', 'systemsettings', 'servicesettings', 'pvrsettings', \
|
|
||||||
'playersettings', 'mediasettings', 'interfacesettings', 'profiles', 'skinsettings', 'videossettings', \
|
|
||||||
'musicsettings', 'appearancesettings', 'picturessettings', 'weathersettings', 'gamesettings', \
|
|
||||||
'service-LibreELEC-Settings-mainWindow.xml', 'service-LibreELEC-Settings-wizard.xml', \
|
|
||||||
'service-LibreELEC-Settings-getPasskey.xml']
|
|
||||||
appsWindows = ['addonbrowser', 'addonsettings', 'addoninformation', 'addon', 'programs']
|
|
||||||
states = []
|
|
||||||
states.append(fd628states.fd628IconIndicator(True, 'power'))
|
|
||||||
states.append(fd628states.fd628CondVisibility('play', 'Player.Playing'))
|
|
||||||
states.append(fd628states.fd628CondVisibility('pause', 'Player.Paused'))
|
|
||||||
states.append(fd628states.fd628FileContains('hdmi', '/sys/class/amhdmitx/amhdmitx0/hpd_state', ['1']))
|
|
||||||
states.append(fd628states.fd628FileContains('cvbs', '/sys/class/display/mode', ['cvbs']))
|
|
||||||
states.append(fd628states.fd628FileContains('eth', '/sys/class/net/eth0/operstate', ['up', 'unknown']))
|
|
||||||
states.append(fd628states.fd628FileContains('wifi', '/sys/class/net/wlan0/operstate', ['up']))
|
|
||||||
states.append(fd628states.fd628WindowChecker('setup', settingsWindows))
|
|
||||||
states.append(fd628states.fd628WindowChecker('apps', appsWindows))
|
|
||||||
states.append(fd628states.fd628ExtStorageChecker('usb', '/dev/sd'))
|
|
||||||
states.append(fd628states.fd628ExtStorageChecker('sd', '/dev/mmcblk'))
|
|
||||||
self._colonIcon = fd628states.fd628IconIndicator(False, 'colon')
|
|
||||||
states.append(self._colonIcon)
|
|
||||||
if (self._settings.isStorageIndicator()):
|
|
||||||
for state in states:
|
|
||||||
if (state.getLedName() == self._settings.getStorageIndicatorIcon()):
|
|
||||||
states.remove(state)
|
|
||||||
break
|
|
||||||
states.append(fd628states.fd628ExtStorageCount(self._settings.getStorageIndicatorIcon(), None, 'rw'))
|
|
||||||
kodiLog('Active states: ' + str([str(state) for state in states]))
|
|
||||||
self.__turnOffIndicators()
|
|
||||||
self._states = states
|
|
||||||
|
|
||||||
monitor = fd628Monitor()
|
|
||||||
fd628 = fd628Addon(monitor)
|
|
||||||
kodiLog('Service start.')
|
|
||||||
fd628.run()
|
|
||||||
kodiLog('Service stop.')
|
|
@ -1,21 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
|
||||||
<settings>
|
|
||||||
<category label="30000">
|
|
||||||
<setting label="30001" type="bool" id="display.on" default="true" />
|
|
||||||
<setting label="30002" type="slider" id="display.brightness" default="7" range="0,7" option="int" visible="eq(-1,true)" />
|
|
||||||
<setting label="30013" type="bool" id="display.storage.indicator" default="false" visible="eq(-2,true)" />
|
|
||||||
<setting label="30014" type="labelenum" id="display.storage.indicator.icon" lvalues="30025|30015|30016|30017|30018|30019|30020|30021|30022|30023|30024|30027" default="30025" visible="eq(-3,true) + eq(-1,true)" subsetting="true" />
|
|
||||||
<setting label="30028" type="bool" id="display.colon.on" default="false" visible="eq(-4,true)" />
|
|
||||||
<setting label="30003" type="bool" id="display.advanced" default="false" visible="eq(-5,true)" />
|
|
||||||
<setting label="30004" type="enum" id="display.type" values="0|1|2|3|4|5|6" default="1" visible="eq(-6,true) + eq(-1,true)" subsetting="true" />
|
|
||||||
<setting label="30026" type="bool" id="display.common.anode" default="false" visible="eq(-7,true) + eq(-2,true)" subsetting="true" />
|
|
||||||
<setting type="lsep" label="30012" visible="eq(-8,true) + eq(-3,true)" />
|
|
||||||
<setting label="30005" type="enum" id="display.char.index0" values="0|1|2|3|4|5|6" default="0" visible="eq(-9 ,true) + eq(-4,true)" subsetting="true" />
|
|
||||||
<setting label="30006" type="enum" id="display.char.index1" values="0|1|2|3|4|5|6" default="1" visible="eq(-10,true) + eq(-5,true)" subsetting="true" />
|
|
||||||
<setting label="30007" type="enum" id="display.char.index2" values="0|1|2|3|4|5|6" default="2" visible="eq(-11,true) + eq(-6,true)" subsetting="true" />
|
|
||||||
<setting label="30008" type="enum" id="display.char.index3" values="0|1|2|3|4|5|6" default="3" visible="eq(-12,true) + eq(-7,true)" subsetting="true" />
|
|
||||||
<setting label="30009" type="enum" id="display.char.index4" values="0|1|2|3|4|5|6" default="4" visible="eq(-13,true) + eq(-8,true)" subsetting="true" />
|
|
||||||
<setting label="30010" type="enum" id="display.char.index5" values="0|1|2|3|4|5|6" default="5" visible="false" subsetting="true" />
|
|
||||||
<setting label="30011" type="enum" id="display.char.index6" values="0|1|2|3|4|5|6" default="6" visible="false" subsetting="true" />
|
|
||||||
</category>
|
|
||||||
</settings>
|
|
Loading…
x
Reference in New Issue
Block a user