Posts by jojobro1

    I was thinking there was an already made module like rpi-tools or systemtools i could import. But I just imported it into the addon itself and called on it with <extension point="xbmc.python.module" library="resources/lib/serial" />

    IMO this requires some caution. E.g. check of supported HW, already modified config.txt...
    From the UI there should be a deinstallation button.

    As for the config.txt, I made sure I checked for each of them individually and then only add the ones that are missing to the very bottom.
    The uninstaller works in a similar way and is available through the addon's settings window.

    Thank you mglae!

    I'm trying to re-write the addon I created to control the fan inside the Deskpi Pro case.
    (https://github.com/jojobrogess/script.deskpifanservice)

    In order to control the fan, I need the serial. Currently this is how I install it

    https://github.com/pyserial/pyserial
    pyserial_installer.sh, code inside:
    cd ~/
    wget https://github.com/jojobrogess/py…ags/v3.5.tar.gz -O pyserial-3.5.tar.gz
    export tmp_dir=~/install_temp/
    mkdir $tmp_dir
    cd $tmp_dir
    tar -xvf ~/pyserial*.tar.gz
    cd pyserial*
    python setup.py install --user
    cd ~/
    rm $tmp_dir/ -Rf
    rm pyserial-3.5.tar.gz

    I then run that file with install_pyserial.py, code inside:
    os.system(f'cp {addon_directory}/resources/lib/pyserial_installer.sh {user_storage}/')
    os.system(f'sh {user_storage}/pyserial_installer.sh')

    With this method, everything gets installed to:
    /storage/.local/lib/python3.8/site-packages/serial

    What I'm wondering is, is this an accepted install method?
    or should I be creating a subdirectory within my addon with the module inside that.

    As that is what the kodi docs seem to suggest:
    https://kodi.wiki/view/Python_li…s%20inside%20it.

    https://kodi.wiki/view/Add-on:Pyserial
    Although it does say that there are modules available for use and pyserial is one of those modules but I don't know the addon id for it.
    And modules can't be searched, or at least they don't have their own widget category.
    And if I install pyserial with my current methodology, I can't use it as a dependency in addon.xml and it installs in a location outside of the addon directory/addon_data directory.


    *********************************************************************************************************************************

    SIDE note, if a mod reads this:
    My addon needs to modify the /flash/config.txt file, adding "otg_mode=1,dtoverlay=dwc2,dr_mode=host,dtoverlay=gpio-ir,gpio_pin=17" to the EOF:

    Display Spoiler

        mount -o remount,rw /flash
       echo "otg_mode=1,dtoverlay=dwc2,dr_mode=host,dtoverlay=gpio-ir,gpio_pin=17" >> /flash/config.txt
       mount -o remount,ro /flash

    Is an addon "allowed" to modify that file?

    That's no longer the case.

    I just built both because Deskpi refused to admit it would work for over a year after I showed it could be done:

    I DON'T advise purchasing a unit with the intent on using it with Libreelec.

    (The Deskpi Pro case interferes with wifi connections and the software provided is basic at best.

    There is only 1 person updating the software on their Github and he seems to have been assigned elsewhere in the company.

    They just released the Deskpi Lite, which I don't think has software yet.

    And yet again, is probably just the basic amount of code to get it to work.)

    But if you're sitting on a unit like I was...

    I am the only one who has working code atm for Libreelec, and I taught myself how to code just to prove Deskpi wrong.

    And help the people that posted in that thread, who like me bought the unit with the intent on using it with Libreelec.

    Then had to wait a couple months after purchasing to receive a fixed part because they shipped a KNOWN malfunctioning part.

    Just to be told their case WOULD NOT work with Libreelec matrix. So Deskpi would not be investing time into it.(this was when libreelec matrix was still in beta)

    So I invested time. Twice.

    Once to show proof of concept, that hey yeah this is possible. Can you work on it?

    Then pretty much a year later, after feeling terrible I had time to kill in my personal life and enough anger to complete it, lol,

    I started working on it.

    Every night, every spare minute at work, and pretty much all day on my days off of work. And a lot of help from this forum and others.

    To figure the whole thing out. Idk how much time it took me, but I would assume altogether a literal month or two of research and testing.

    Over a span of a year-ish. I didn't know that much about ssh, bash, shell, or python before this.

    yeah, and I still can't code lol

    So yeah fyi, the installer and addon were made extremely noob like, beware.

    Install and control through ssh:

    GitHub - jojobrogess/Libreelec-Deskpi-Installer: This is a unified installer script for Libreelec and the Deskpi Pro case.
    This is a unified installer script for Libreelec and the Deskpi Pro case. - GitHub - jojobrogess/Libreelec-Deskpi-Installer: This is a unified installer script…
    github.com

    Install and control through addon:

    GitHub - jojobrogess/script.deskpifanservice: Libreelec Addon to install Deskpi Fan Service and Control Fan Speed
    Libreelec Addon to install Deskpi Fan Service and Control Fan Speed - GitHub - jojobrogess/script.deskpifanservice: Libreelec Addon to install Deskpi Fan…
    github.com

    If you have any problems please post on the respective github pages.

    PS: I did add IR functionality, but I don't own an IR remote so I couldn't test if it worked or not.

    I added ' dtoverlay=gpio-ir,gpio_pin=17" ' to /flash/config.txt which I think should add the functionality.

    OKAY, so I figured it all somewhat out. I can now do what I was trying to do with this:


    I would assume there is a more dynamic way of doing this, but I don't know how to do that.lol

    Plus ATM when a value is changed within the settings page, the addon needs to be ran after for the settings to be saved within the file.

    Does anyone know of a way for the settings page to "run" the addon?

    The extension point for my addon is xbmc.python.script, should I be using plugin?

    Did I just write my addon incorrectly? and the functions need to be OUTSIDE the class for it to work the way I want? Or something similar.

    Ahh crap I think I just got it.

    The magic code is(depending on what type of content you're dealing with or doing(setting/getting):

    Code
    .getSettingString
    .setSettingInt
    .getSettingBool
    .setSettingBool
    .getSettingNumber

    Example code for addon.py:

    (settemp1 and setspeed1 are the values the user changed(as a string or default as an integer?) in settings.xml)

    Code
    __addon_id__ = 'script.hellotestwindow'
    __Addon = xbmcaddon.Addon(__addon_id__)
    
    def getSettingInt(name):
        return __Addon.getSettingInt(name)
    
    def settings(self):
        settemp1 = utils.getSettingInt('temp1')
        setspeed1 = utils.getSettingString('speed1') 

    Corresponding example settingsxml:

    Code
    <setting label="start temp" type="number" id="settemp1" default="30"/>
    <setting label="start fan speed" type="number" id="setspeed1" default="25"/>

    IF I'M WRONG ON THIS, please let me know =/

    I am literally throwing code at this until it works lol

    Now I just have to figure out how to write those user input values into that .conf file.

    Okay so I cleaned up my code a lot to streamline it so I can understand it better:

    I can open the file and set each line as a reference to be used later.

    I just don't know where to start to have that work in conjunction with my settings.xml code:

    Code
    <setting label="start temp" type="number" id="temp1" default="30"/>
    <setting label="start fan speed" type="number" id="speed1" default="25" subsetting="true"/>

    does anyone know how to do this?

    The values (temp1,speed1,...) represent lines in a file that need to be displayed/changed from within the settings page of an addon.

    So I've gotten a little more understanding of what's actually going on inside the addon python file and have been somewhat able to create a "working" file. Right now I can open a file, read/set lines(INSIDE pycharm python)

    But I am failing to understand how the settings.xml and the addon python file communicate.

    This is what I have written so far:

    **Right now I am testing the code on my windows machine, through kodi(since its a billion times easier for me to check logs and change code). I doubt that should change anything in this case, as this part of the code, I don't think, has anything specifically libreelec.

    I just need to open a .conf file, read line by line, use reference code of lines inside settings page of addon so user can change temp/fan speeds for a serial case fan(which is libreelec specific).

    The code in my settings.xml:

    Code
    <setting label="First Tempurature/Speed Threshold" type="lsep"/>
    <setting label="start temp" type="number" id='temp1' default="30"/>
    <setting label="start fan speed" type="number" id="speed1" default="25" subsetting="true"/>

    The addon.py:


    I DO NOT think I'm doing any of this correctly but especially the last part, the DEF open and DEF set_value.

    How do I "link" the lines read out from a file to the settings id?

    I was looking on codedocs and saw this, which looks to be what is needed. But I can't read it.

    And google isn't liking my crazy specific search terms anymore..

    XBMCAddon::xbmcplugin::getSetting (int handle, const char *id)

    XBMCAddon::xbmcplugin::setSetting (int handle, const String &id, const String &value)


    How do these work?

    IS it:

    XBMCADDON = The AddonID?(script.hellotestwindow)

    xbmcplugin = Script name inside addon?(addon.py)

    get/setSetting = The setting I am getting/setting(temp1 speed1...)

    so:

    script.hellotestwindow.'addon.py'.temp1()

    And then the () has the args for the get/setSetting ?

    And is that what is needed for me to associate the readlines from the file as settings id ?

    Or am I doing this all wrong?

    As always, any type of help is greatly appreciated.

    I finally completed a basic setup of the addon I'm trying to create.

    Example Files for background info:

    Settings.xml:

    Code
    <settings>
    <category label="Dependencies">
    <setting label="30003" type="lsep"/>
    <setting label="30000" type="action" action="RunScript($CWD/resources/scripts/install_pyserial.py)"/>

    script file:

    This is pretty much how everything runs at the moment, because I have no idea how to do this and thought this would be the simplest:

    I have scripts(setfan_100.py, deskpi_installer.sh) that are set as the scripts for the buttons themselves inside the settings page of my addon.

    When a user clicks the button, an action happens(ie install a dependency for the installer, install the installer, set fan speed.)

    And I got all of that to work, with a lot of libreelec forum help.

    I'm just stuck on the last hurdle, making a real addon. lol

    The problem I'm running into is I'm installing a fan service which needs the ability for users to change fan speeds and temp ranges.

    Essentially I need to get 2 sets of 4 values for fan speed and temp ranges. These values are saved into a .conf file (located OUTSIDE the addon in /storage/user/bin/)

    (The installer for this file and the service is here, if you want to check it out to understand how it all works. But I would assume it's pretty basic for this sort of thing.)

    The fan is controlled via serial ttyUSB0. So sending basic code("pwm_050") into /dev/ttyUSB0 will control the 'constant' value of the fan speed.

    Traditionally the fan is configured through a bash configuration tool(read -p, echo $value into file) to allow the user to set custom fan speed and temp ranges.

    After configuration the .conf looks like this:

    30

    25

    35

    50

    40

    75

    45

    100

    How the service works with those inputs:

    if cpu_temp < 30:

    ser.write(b'pwm_000')

    elif cpu_temp > 30 and cpu_temp < 35:

    ser.write(b'pwm_025')

    elif cpu_temp > 35 and cpu_temp < 40:

    ser.write(b'pwm_050')

    elif cpu_temp > 45 and cpu_temp < 50:

    ser.write(b'pwm_075')

    elif cpu_temp > 50:

    ser.write(b'pwm_100')

    So essentially my idea of creating a SUPER BASIC ADDON, that does things in the old skool skript kiddy way. Won't work lol

    So I've been trying to understand how to do things correctly, so I can pass arguments/user inputs into the file from the settings page.

    I know I need to set the extension point in the addon.xml to the main script.

    The script the addon calls is(addon.py):

    # Module: default

    # Author: jojobrogess

    from resources.utils import script

    if __name__ == '__main__':

    script().test()

    That imports a python file(located in script.testwindow/resources/utils.py and starts the class that's called "script")

    which is something like this:

    Python
    import sys
    import xbmc
    import xbmcaddon
    
    class script():
        def __init__(self):

    Which you then use something like this in the settings.xml to call a DEF that's inside the file above:

    Code
    <setting label="start temp" type="number" id="defcode1" default="40"/>

    Runscript() would then be done correctly by doing something like this:

    Code
    <setting label="$ADDON[script.testwindow 30000]" type="action" action="RunScript(script.testwindow,DEF)" option="" />


    But I'm lost on the whole addon.py to utils.py file class:script DEF coding. I don't even know how to type it, that is how far out of my element I am right now.

    Traditionally speaking when I don't understand how something works, I can search up components of the code and slowly piece it together.

    But this is just beyond my understanding.

    I don't understand the syntax/function for the class and def code.

    Or even what that's called. A python function?

    Does anyone have any wiki's or SIMPLE examples for an idiot? lol

    Googling python syntax to understand this better is proving to be difficult

    So I've been trying to use:

    Add-on development - Official Kodi Wiki

    Addon.xml - Official Kodi Wiki

    Add-on settings - Official Kodi Wiki

    HOW-TO:Script addon - Official Kodi Wiki

    As well as opening the kodi addon directory in ST3 so I can scan all my addons for terms to see how others coded.

    But everything seems very specific(or in Kidiwiki case, out of date/old) and I can't seem to understand enough of it to write anything, that works.

    I tried to make a super basic test function, open a notification window, but it doesn't work:

    Code
    <setting label="newtest" type="action" action="RunScript(script.testwindow,test)" option="" />
    <setting label="newtest2" type="action" action="RunScript(script.testwindow,test)"/>

    With every change of code, I get a new error lol and seemingly further from figuring this out.

    I really wish there was more information for the bottom feeders like me who don't really know how to code, so I don't have to come in here and bother people probably doing real stuff lol

    DOES ANYONE HAVE ANY super simple example code? Or anything that could point in the right direction?

    VPETER!!!! <3

    THAT WORKED,

    But when I went to the kodi wiki link you posted it said:

    Quote

    Since we require all used strings to be localized (translatable) we recommend the second option.

    So I decided to use:

    (although I doubt my addon would get implemented in the main repo, or get/need translating.)

    Although the icon isn't coming up. But I think I might be able to figure that out, not a biggie if not though.

    The "i" works perfectly.

    I also saw:

    Which is AWESOME.

    Plus changing .ok to .yesno seems to add some fun options.

    Although I suspect I would have to start implementing more substantial code to have that functionality, and I could barely do this atm.

    There's ALSO some json rpc examples at the bottom.

    THANK YOU!!!! THIS WAS EXACTLY WHAT I NEEDED.

    I've been reading this since you posted it, and trying to search up how to use it. But I just don't understand.

    Do I add that to a script? Python or shell?

    Or do I add that to the settings label?

    I don't understand how to use jsonrpc. Or what it is.

    These two files make up the entirety of my addon:

    Example of My settings.xml:

    Code
    <setting label="Turn On and Off" type="lsep"/>
    <setting label="Set Fan to 100%" type="action" action="RunScript(/storage/.kodi/addons/script.hellotestwindow/resources/scripts/TurnFan_On.py)"/>

    and the TurnFan_On.py

    Code
    import os
    os.system('echo "pwm_100" > /dev/ttyUSB0')

    I do have an installer button, that copies an installer(from within the addon) I made for a case fan(Deskpi Pro) to /storage/ and runs it.

    I tried putting that code in a test.py file and using the code I have above to run it. I also tried an sh file.

    But nothing happens.

    I also added it to the TurnFan_On.py file, and still nothing happens.

    I'm utterly lost.

    How do I use that?

    Do I pass it as a argument?

    I don't know where to put it to even test it.

    And even when I google kodi jsonrpc. The wiki says this:

    JSON-RPC is a HTTP- and/or raw TCP socket-based interface for communicating with Kodi. It replaces the deprecated HTTP API, and offers a more secure and robust mechanism in the same format. It is based upon the JSON-RPC 2.0 specification.

    I don't understand why I would need to connect via http/tcp to send a user notification that a button inside an addon settings was executed/pressed.

    I just don't understand. And I feel like an idiot for it lol

    I have a simple addon that I'm building that essentially installs a case fan installer that I made, through the settings page of the addon.

    At the moment I can do pretty much everything I need to but the whole thing is contingent on RunScript.

    Which works.

    But what I'm running into is there is no notification for when the button is selected.

    All I need is a "confirmation" popup, something that can notify me that the button press was received by kodi.

    (example: Autowidget menu, force refresh widgets has a quick pop up that shows the action was "started")

    How would I go about doing this?

    I've tried google searching terms with "notifications" dialog" but everything was beyond what I'm trying to accomplish.

    Or completely off topic..

    Does anyone know of a way to accomplish this?

    I tried your solution vpeter, but it didn't work.

    I got it to work using

    Code
    action="RunScript(/storage/.kodi/addons/script.hellotestwindow/resources/scripts/TurnFan_On.py)"/>

    which is the same, but inside a resources directory.

    @diederik
    Are you sure about redirecting it to '/dev/ttyUSB0'?

    That is usually a serial console attached to USB (at least that's where I know it from).

    yeah that is where the USB serial bus is located, at least after adding otg_mode=1 in config.txt

    But not at all, idk what I'm doing.

    The company Deskpi created a case for the rpi 4 and haven't been able to create an installer for it for libreelec.

    I impulsively bought one, before they began shipping I guess, and have been sitting on an entire kodi rpi setup for a year and a half.

    So eventually I took their code and got it to work.

    Which is rad, but you can only control it through ssh atm. which I think is lame for realistic long term use.

    Who wants to open an ssh connection to quiet the fan a little, or bump the speed up cuz it's summer.

    So now I'm trying to take that installer that I made, and figure out a way to install it through an addon, set some fan speeds, maybe send code into a .conf file to change overall values. but try to keep it AS SIMPLE AS POSSIBLE.

    Because I can't code, and Idk what I'm doing.

    But I'm trying my hardest to lol

    Thanks for your help!

    I'm trying to execute code through an addon settings page.

    The libreelec kodi.log says it successfully ran the script, but nothing happens.

    And without a readout to see where it exactly failed, I've spent hours trying to get this to work,

    with slight variations, over and over...

    The settings.xml button looks like this:

    Code
    <setting label="Turn On Fan" type="action" action="'RunScript(/storage/.kodi/addons/script.hellotestwindow/script/TurnFan_On.py)')"/>

    The code in the script:

    (Which is a python script, idk if that matters)

    Code
    import os
    os.system("echo pwm_100 > /dev/ttyUSB0")

    I have tried using:

    Code
    import xbmc
    xbmc.executebuiltin('echo "pwm_100" > /dev/ttyUSB0')

    I have also tried test code in which I touch/nano/echo a file, to see where it gets created, or if I can create a file but nothing.

    Maybe I'm not understanding how this process works fully.

    I'm trying to execute code as if it was in the CLI.

    (realistically at this point, I'd settle for anyway of doing this)

    Also if anyone could figure out a way to get to "/storage/" from that code execution that would be awesome as well.

    After this I need to figure out how to run an .sh installer, but all of it hinges on the ability to run code in this way and to be able to get to "storage/".

    Anything will help.

    THANKS IN ADVANCE!!!!!

    I'm trying to make an install script for the Deskpi Fan case.

    While also knowing pretty much nothing about python.

    (this is an import from the thread that was in the wrong https://forum.libreelec.tv/thread/25435-trying-to-make-an-install-script-for-deskpi-pro-case/?postID=167915#post167915 thread)


    I'm having a hard time with this code:

    I'm pretty sure it's a formatting issue, but I can't seem to figure this part out:

    Code
    try: 
    while True: 
    if ser.isOpen(): 
    cpu_temp=subprocess.getoutput("/opt/vc/bin/vcgencmd measure_temp" | "sed -e "s/temp=//" -e "s/\..*'/ /") 
    cpu_temp=int(cpu_temp.split(.)[0])

    I keep getting errors, regardless of my changes. I get "unsupported operand type(s) for "|:" 'str' and 'str' " or just "syntax errors".

    I also tried:

    Code
    cpu_temp=subprocess.getoutput("/opt/vc/bin/vcgencmd.measure_temp") | "grep" "sed -e s/temp=// -e s/\..*'/ /"
    cpu_temp=float(int(cpu_temp.split('.')[0]) 


    Looks like the error I was getting was because I was trying to take a LITERAL(real number) into an Integer.

    You can't do that, so you have to turn it into a FLOAT.

    Adding "float(" in-front of the other code I had(int(cpu_tempt.split....) "fixed" it.

    But now I'm getting an error here:

    Code
    if cpu_temp < 40:
                    ^
    SyntaxError: invalid syntax

    Honestly I can barely read this, it's a little advanced for me. Can someone please point me in the right direction?

    Anything will help.

    Thanks in advance!

    Code
    cpu_temp=subprocess.getoutput("/opt/vc/bin/vcgencmd.measure_temp") | "grep" "sed -e s/temp=// -e s/\..*'/ /"
    cpu_temp=float(int(cpu_temp.split('.')[0]) 


    Looks like the error I was getting was because I was trying to take a LITERAL(real number) into an Integer.

    You can't do that, so you have to turn it into a FLOAT.

    Adding "float(" in-front of the other code I had(int(cpu_tempt.split....) "fixed" it.

    But now I'm getting an error here:

    Code
    if cpu_temp < 40:
    
                    ^
    SyntaxError: invalid syntax

    I'm having a hard time with this code:

    I'm pretty sure it's a formatting issue, but I can't seem to figure this part out:

    Code
    try:
     while True:
     if ser.isOpen():
     cpu_temp=subprocess.getoutput("/opt/vc/bin/vcgencmd measure_temp" | "sed -e "s/temp=//" -e "s/\..*'/ /")
     cpu_temp=int(cpu_temp.split(.)[0])

    I keep getting errors, regardless of my changes. I get "unsupported operand type(s) for "|:" 'str' and 'str' " "syntax errors"

    Honestly I can barely read this. Can someone please point me in the right direction?
    Anything will help.

    Thanks in advance!