New TAP to manage the PVR using HTML/CSS/JavaScript.

TAPs für die SRP- und CRP-Serie
DeltaMikeCharlie
WebController
WebController
Beiträge: 469
Registriert: Di 7. Mai 2013, 05:11
Wohnort: Australia

New TAP to manage the PVR using HTML/CSS/JavaScript.

#1

Beitrag von DeltaMikeCharlie » Sa 10. Aug 2013, 06:54

I have written a proof-of-concept TAP called TMA1. TMA1 stands for Topfield Management Architecture 1.

The aim of TMA1 is to provide an architecture platform upon which a variety of alternate control interfaces can be built. At its most basic, TMA1 is a replacement web server for the TMS series. It will be able to serve any static web page or file stored within TMA1's web store.

In addition to serving static files, TMA1 can recognise specially formatted URLs containing data requests and return that data in JSON notation. This block of data can be converted directly into JavaScript objects for manipulation within a browser.

TMA1 is not an alternate method for delivering remote control commands and viewing the on screen GUI, there are existing systems that do that very well. TMA1 is an architecture platform that extends the concept of the TAP API (with FireBirdLib extensions) to facilitate a total replacement of the PVR command interface using external devices. As it is only a platform, the interface can be completely customised using HTML, CSS & JavaScript.

Although usable from any browser, it is envisioned that it would be most useful from a tablet device or smart phone.

As this is a proof of concept, if you choose to download and run it, please keep in mind that this TAP is designed to prove a concept and is not a stable, complete and functioning application. As such, its functionality is extremely limited and its appearance can only be described as basic.

The proof-of-concept can be downloaded from here.

At the moment, TMA1 can only list timers, list channels and select channels. This limited functionality serves to prove the basic concepts of extracting data from the PVR, presenting it in a browser window and then issuing a command to the PVR based on the data extracted. Future envisioned functionality would include:
  • Listing recoded programmes
  • Getting recorded programme information
  • Commencing playback of recorded programmes
  • Management of recorded programmes (deletion, renaming, move to folder)
  • Getting logo images for channels.
  • Starting manual recordings
  • Creating/editing timers
  • Extracting EPG data
  • Changing volume
  • Getting general PVR settings (language settings, date/time, time zone, etc)
  • Storing/retrieving INI settings for the TAP & JavaScript components
In addition to functionality hard-coded into TMA1, it is envisioned that this functionality could be expanded with add-on TAPs that would accept commands relayed from a browser via TMA1 and then send data back to a browser via TMA1.

The idea of TMA1 was inspired by commercial AV control systems that use touch screens such as AMX or Crestron, but using cheap domestic-grade touch screen devices like tablets and smart phones to control the PVR.

There is no system security. If implemented, security will be designed to discourage an opportunistic troublemaker, not repel a determined hacker.

Does anyone find this concept interesting and worth exploring further?

If you have HTML, CSS or JavaScript programming skills, and would be interested in collaborating with me on this project, please send me a private message.

Regards,
DMC.
Zuletzt geändert von DeltaMikeCharlie am Sa 10. Aug 2013, 07:04, insgesamt 1-mal geändert.
Grund: Amend title

Benutzeravatar
Mucki
Quelle des Wissens
Quelle des Wissens
Beiträge: 1347
Registriert: Mo 12. Dez 2005, 19:14
Receivertyp: SRP2100, PVR5000, Vu+ Ultimo4K mit DVB-S2 + DVB-T2
Receiverfirmware: Die Aktuelle
Wohnort: Grafschaft

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#2

Beitrag von Mucki » Sa 10. Aug 2013, 13:28

Hallo,
if i press the html-Channel Button my TMS2100 reboot. :thinker:
Gruß Mucki :)

Taps: SE, TMSArchiv, V!deotext, Callmonitor, lost+found, TMSRemote, TimeShiftSaver, NiceDisplay, FastSkip, TMSCommander, Backupsettings, FreeSatEit_TMS, TMSMount, Inf+, TMA1

Neu Ultimo4K mit SmartEPGVu+, Autotimer, AutomaticBackup, EMC, Camofs, CoolTV, AdvancedLibrary, VWeather3.
Skin: IFlatHD mit Eisman Pro Features

DeltaMikeCharlie
WebController
WebController
Beiträge: 469
Registriert: Di 7. Mai 2013, 05:11
Wohnort: Australia

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#3

Beitrag von DeltaMikeCharlie » Sa 10. Aug 2013, 23:51

Hi Mucki,

Thanks for trying. :)

I'm sorry to hear that your PVR rebooted. I hope that no damage was done.

Can you please explain some more about what you did?
  • When you accessed the PVR from your browser, did you see a list of channels?
  • Did the PVR crash when you selected a channel, or when you press the "Channels" menu item at the top?
  • Did you press the "Timers" menu item? Did it list the timers?
  • Do you have telnet access to your PVR? If so, can you please tell me at what point the PVR reboots?
  • Are you able to send me a copy of /ProgamFiles/TMA1.log from after a crash via PM?
Can you also please tell me what version(s) of which browser(s) did you try?

Regards,
DMC.

Benutzeravatar
Mucki
Quelle des Wissens
Quelle des Wissens
Beiträge: 1347
Registriert: Mo 12. Dez 2005, 19:14
Receivertyp: SRP2100, PVR5000, Vu+ Ultimo4K mit DVB-S2 + DVB-T2
Receiverfirmware: Die Aktuelle
Wohnort: Grafschaft

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#4

Beitrag von Mucki » So 11. Aug 2013, 00:14

DeltaMikeCharlie hat geschrieben:Hi Mucki,

Thanks for trying. :)

I'm sorry to hear that your PVR rebooted. I hope that no damage was done.

Can you please explain some more about what you did?
  • When you accessed the PVR from your browser, did you see a list of channels?
  • Did the PVR crash when you selected a channel, or when you press the "Channels" menu item at the top?
  • Did you press the "Timers" menu item? Did it list the timers?
  • Do you have telnet access to your PVR? If so, can you please tell me at what point the PVR reboots?
  • Are you able to send me a copy of /ProgamFiles/TMA1.log from after a crash via PM?
Can you also please tell me what version(s) of which browser(s) did you try?

Regards,
DMC.


Hello DMC,

the TMS2100 rebooted when I press the item Channel Menue at the Top.
The TMA1 Log show you all Information before my TMS crashed.

Greetings to down under !
Sorry for my English ;)

Here is the completet Log-File.

TMA1 Started: 12:53:51.

Initialising listening socket.
Setting listening socket 66 to non-blocking mode.
About to 'bind' listening socket 66.
About to 'listen' listening socket 66.
Listening socket 66 initialisation complete.
Got connection from 192.168.24.105.
Got connection from 192.168.24.105.
Got 365 bytes of data.
GET / HTTP/1.1
Host: 192.168.24.103:8000
User-Agent: Mozilla/5.0 (iPad; CPU OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Cache-Control: max-age=0
Accept-Language: de-de
Accept-Encoding: gzip, deflate
Connection: keep-alive


Method: 'GET'
Path: '/'
Processing Command '/' (1).
Trying to send home page.
Closing home file.
Home file closed.
Sent: 9276.
NetHTTPRespond() - Memory released.
Response sent.
NetServeHomePage() - Memory released.
Got connection from 192.168.24.105.
Got connection from 192.168.24.105.
Got 376 bytes of data.
GET /api?function=channels&action=get! HTTP/1.1
Host: 192.168.24.103:8000
User-Agent: Mozilla/5.0 (iPad; CPU OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3
Accept: */*
Referer: http://192.168.24.103:8000/
Cache-Control: max-age=0
Accept-Language: de-de
Accept-Encoding: gzip, deflate
Connection: keep-alive


Method: 'GET'
Path: '/api?function=channels&action=get!'
Processing Command '/api?function=channels&action=get!' (34).
Processing API-Channels-Get request '/api?function=channels&action=get!'.
Channels = (394)
Gruß Mucki :)

Taps: SE, TMSArchiv, V!deotext, Callmonitor, lost+found, TMSRemote, TimeShiftSaver, NiceDisplay, FastSkip, TMSCommander, Backupsettings, FreeSatEit_TMS, TMSMount, Inf+, TMA1

Neu Ultimo4K mit SmartEPGVu+, Autotimer, AutomaticBackup, EMC, Camofs, CoolTV, AdvancedLibrary, VWeather3.
Skin: IFlatHD mit Eisman Pro Features

DeltaMikeCharlie
WebController
WebController
Beiträge: 469
Registriert: Di 7. Mai 2013, 05:11
Wohnort: Australia

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#5

Beitrag von DeltaMikeCharlie » So 11. Aug 2013, 00:47

Thanks Mucki,

My best guess at the moment is that your PVR rebooted because you have 394 channels on your PVR. (I only have 30!)

In the proof-of-concept, I allocate a fixed amount of memory for the response to the browser and this does not take into account how many channels you may have. I think that because the response was bigger than the amount of memory that I allocated, the PVR rebooted.

I will need to address this issue in the next version by dynamically allocating the amount of memory required based on the number of channels that the PVR has. I have a terrestrial PVR with 30 channels and I did not imagine that you could have so many channels. I assume that you are a Satellite user.

Thank you very much for your help.

You don’t need to apologise for your English skills. My German skills are much worse!! :wink:

Regards,
DMC.

DeltaMikeCharlie
WebController
WebController
Beiträge: 469
Registriert: Di 7. Mai 2013, 05:11
Wohnort: Australia

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#6

Beitrag von DeltaMikeCharlie » So 11. Aug 2013, 04:41

I have changed the TAP so that it dynamically reserves memory based on the number of channels stored in the PVR. I'm hoping that this will solve the rebooting problem.

You can download the updated TAP from the same place as before.

I can not guarantee that this will work for almost 400 channels, but it worked for me with 30. I tried to simulate 400+ channels by loading my 30 channels 17 times and it took a long time, so be patient.

If this TAP is developed further, the number of channels returned will have to be filtered, perhaps using favourite groups. Also, the JavaScript could buffer the channels only needing to ask for them once. Maybe I can provide a smaller number of fields in my returned data, just enough for the display and channel selection.

For now, I will be happy if I can prove that it will not reboot a PVR with 400+ channels.

Benutzeravatar
FireBird
Suspekter verdächtiger Zauberküchenchef, TAP & Firmware-Guru
Suspekter verdächtiger Zauberküchenchef, TAP & Firmware-Guru
Beiträge: 28911
Registriert: Fr 9. Dez 2005, 09:59
Receivertyp: SRP-2401CI+ TFIR
vu+ Duo 4k
Wohnort: Wien

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#7

Beitrag von FireBird » So 11. Aug 2013, 10:03

Sorry, but it is still rebooting. OK, a little bit more than 400 channels. :) The interesting part is that the Toppy freezes for quite some time (about 20 seconds) before the reboot occurs.

Code: Alles auswählen

TMA1 Started: 09:58:01.
Initialising listening socket.
Setting listening socket 61 to non-blocking mode.
About to 'bind' listening socket 61.
About to 'listen' listening socket 61.
Listening socket 61 initialisation complete.


Got connection from 192.168.0.1.
Got connection from 192.168.0.1.
Got 285 bytes of data.
GET / HTTP/1.1
Host: 192.168.0.214:8000
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:21.0) Gecko/20100101 Firefox/21.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive


Method: 'GET'
Path: '/'
Processing Command '/' (1).
Trying to send home page.
Closing home file.
Home file closed.
NetHTTPRespond Sending header: 66.
NetHTTPRespond Sent: 66.
NetHTTPRespond Sending payload: 9276.
NetHTTPRespond Sent: 9276.
Response sent.
Got connection from 192.168.0.1.
Got connection from 192.168.0.1.
Got 355 bytes of data.
GET /api?function=channels&action=get! HTTP/1.1
Host: 192.168.0.214:8000
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:21.0) Gecko/20100101 Firefox/21.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.0.214:8000/
Connection: keep-alive


Method: 'GET'
Path: '/api?function=channels&action=get!'
Processing Command '/api?function=channels&action=get!' (34).
theCommand = [/api?function=channels&action=get!]
Function = [channels], Action = [get], Module = [default], Session = [].
Processing API-Channels-Get request '/api?function=channels&action=get!'.
Reserving 565856 bytes for channel response.
Channels = (1359)

DeltaMikeCharlie
WebController
WebController
Beiträge: 469
Registriert: Di 7. Mai 2013, 05:11
Wohnort: Australia

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#8

Beitrag von DeltaMikeCharlie » So 11. Aug 2013, 11:02

Thanks FireBird,

That's a shame, perhaps my buffer size calculations are wrong.

I have posted a new version with some more debug code. That should at least narrow down where the reboot is occurring.

Regards,
DMC.

Benutzeravatar
FireBird
Suspekter verdächtiger Zauberküchenchef, TAP & Firmware-Guru
Suspekter verdächtiger Zauberküchenchef, TAP & Firmware-Guru
Beiträge: 28911
Registriert: Fr 9. Dez 2005, 09:59
Receivertyp: SRP-2401CI+ TFIR
vu+ Duo 4k
Wohnort: Wien

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#9

Beitrag von FireBird » So 11. Aug 2013, 11:14

Did you only change the logging? Because now it is working and I get a list of all channels and timers. :bye3:

Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

DeltaMikeCharlie
WebController
WebController
Beiträge: 469
Registriert: Di 7. Mai 2013, 05:11
Wohnort: Australia

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#10

Beitrag von DeltaMikeCharlie » So 11. Aug 2013, 11:25

I added logging and also increased the buffer size. I know it's bad to change 2 things at once when debugging, sorry.

If you click on the channel name, does the PVR change channels?

Benutzeravatar
FireBird
Suspekter verdächtiger Zauberküchenchef, TAP & Firmware-Guru
Suspekter verdächtiger Zauberküchenchef, TAP & Firmware-Guru
Beiträge: 28911
Registriert: Fr 9. Dez 2005, 09:59
Receivertyp: SRP-2401CI+ TFIR
vu+ Duo 4k
Wohnort: Wien

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#11

Beitrag von FireBird » So 11. Aug 2013, 11:29

DeltaMikeCharlie hat geschrieben:I know it's bad to change 2 things at once when debugging, sorry.

No problem at all - as long as you know what's going on. :)
If you click on the channel name, does the PVR change channels?
Yes it does, it just doesn't show up as a link in Firefox, which is a bit confusing.

DeltaMikeCharlie
WebController
WebController
Beiträge: 469
Registriert: Di 7. Mai 2013, 05:11
Wohnort: Australia

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#12

Beitrag von DeltaMikeCharlie » So 11. Aug 2013, 11:43

Thanks for testing FireBird. :)

FireBird hat geschrieben:Yes it does, it just doesn't show up as a link in Firefox, which is a bit confusing.


It is not a HTML link. The JavaScript in the web page responds to a mouse click event on the channels table cells and then activates the API using an asynchronous request. The date/time under the channels list should change and also display the channel that you changed to.

Ultimately, I think that a channel logo would be displayed and perhaps a MouseOver event could be used to show a different border. For a touch screen, the issue of not being a link would go away because you would press the logo of the channel you want to display.

Benutzeravatar
jkIT
TFtool-Guru
TFtool-Guru
Beiträge: 3194
Registriert: Sa 10. Dez 2005, 18:26
Receivertyp: TF4000 & TF5000MP & SRP-2410

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#13

Beitrag von jkIT » So 11. Aug 2013, 14:20

Hello DMC,

nice work. This is an awesome idea.

I have an issue on a SRP2410 (running non UTF-8 firmware) with some characters (see image).
[img]data:image/png;base64,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[/img]

btw: I tried to put jquery into the public_html folder and linked it in the index.html, but tma1 only returns the content of index.html :u:

FireBird hat geschrieben:Yes it does, it just doesn't show up as a link in Firefox, which is a bit confusing.

You can insert the following line in function showChannels()

Code: Alles auswählen

        cell.style.textAlign="left";
       [b] cell.style.cursor="pointer";[/b]
        cell.chtype=chObject.channels[i].chtype.toString();
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Gruß jkIT

CRP-2401; SRP-2410 (aD); TF5000MP (aD); TF4000PVR (aD); TFtool, aTMSremote (Autor)

DeltaMikeCharlie
WebController
WebController
Beiträge: 469
Registriert: Di 7. Mai 2013, 05:11
Wohnort: Australia

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#14

Beitrag von DeltaMikeCharlie » So 11. Aug 2013, 22:24

Hi jkIT,

Thanks for the feedback.

This is still a proof of concept so I'm really only testing that the data gets across from the PVR to the browser and back successfully.

The font issue that you raise proves that the data is transferring, it is just not being decoded properly. At this point in the development process, I'm happy with that. As development progresses, I will have to ensure that either 1) The PVR encodes Unicode text properly or 2) The browser portion decodes the fonts properly. I will put this on the "to do" list.

As a proof of concept, I only needed to serve 1 file to ensure that it was working. If the URL request does not begin with "api?" then index.html is returned. As development progresses, the TAP will be able to serve other files as well.

Regards,
DMC.

Benutzeravatar
jkIT
TFtool-Guru
TFtool-Guru
Beiträge: 3194
Registriert: Sa 10. Dez 2005, 18:26
Receivertyp: TF4000 & TF5000MP & SRP-2410

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#15

Beitrag von jkIT » Mo 12. Aug 2013, 13:58

I think javascript json decoding needs unicode, isnt it?
Gruß jkIT

CRP-2401; SRP-2410 (aD); TF5000MP (aD); TF4000PVR (aD); TFtool, aTMSremote (Autor)

DeltaMikeCharlie
WebController
WebController
Beiträge: 469
Registriert: Di 7. Mai 2013, 05:11
Wohnort: Australia

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#16

Beitrag von DeltaMikeCharlie » Mi 14. Aug 2013, 10:39

I've been thinking about system performance and the delay in loading 1000+ channels dynamically every time TMA1 receives a request for a channel list. This has made me think about caching the channels listing into a file.

Caching would be a problem if satellite providers change their services frequently.

Can somebody please tell me:
  • How often do satellite providers change their services?
  • Does the PVR recognise these changes automatically, or does the satellite service need to be "rescanned" like a terrestrial service?
If the answers to the questions above are favourable, then perhaps I could build the channel list once, when TMA1 loads, and save the response in a file. When a request for channels is made via the API, then TMA1 simply returns the cached file.

I'm also thinking about adding available logo information to the channels data so that the JavaScript code can tell if any logos exist and what their names are. I'm thinking that there would be 2 logo sources: 1) JPEG/PNG files and 2) LIL files. These sources would be searched and added to the channel data each timeTMA1 starts.

Benutzeravatar
FireBird
Suspekter verdächtiger Zauberküchenchef, TAP & Firmware-Guru
Suspekter verdächtiger Zauberküchenchef, TAP & Firmware-Guru
Beiträge: 28911
Registriert: Fr 9. Dez 2005, 09:59
Receivertyp: SRP-2401CI+ TFIR
vu+ Duo 4k
Wohnort: Wien

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#17

Beitrag von FireBird » Mi 14. Aug 2013, 10:49

DeltaMikeCharlie hat geschrieben:*How often do satellite providers change their services?

That depends. :) The providers on the sat which is mainly used here in Europe (Astra), are quite "stable". The interval between scans might be half a year or even longer. I guess that the same is true for cable Toppies. If you receive more exotic sats, you might need to scan more often. But I think that can?t beat a cache file.
*Does the PVR recognise these changes automatically, or does the satellite service need to be "rescanned" like a terrestrial service?
You need to do a rescan as you know it.

DeltaMikeCharlie
WebController
WebController
Beiträge: 469
Registriert: Di 7. Mai 2013, 05:11
Wohnort: Australia

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#18

Beitrag von DeltaMikeCharlie » Mi 14. Aug 2013, 11:39

Thanks Firebird,

How long does the channels list take to load on your PVR via TMA1 and your browser?

Also, with jkIT's character set issue: Is there a function in FireBirdLib to convert these characters?

Benutzeravatar
FireBird
Suspekter verdächtiger Zauberküchenchef, TAP & Firmware-Guru
Suspekter verdächtiger Zauberküchenchef, TAP & Firmware-Guru
Beiträge: 28911
Registriert: Fr 9. Dez 2005, 09:59
Receivertyp: SRP-2401CI+ TFIR
vu+ Duo 4k
Wohnort: Wien

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#19

Beitrag von FireBird » Mi 14. Aug 2013, 12:26

If you like I can provide more accurate numbers but it was more than one minute. MakeValidFileName() will clean-up a string, ControlChars will remove this specific emphasis characters.

DeltaMikeCharlie
WebController
WebController
Beiträge: 469
Registriert: Di 7. Mai 2013, 05:11
Wohnort: Australia

AW: New TAP to manage the PVR using HTML/CSS/JavaScript.

#20

Beitrag von DeltaMikeCharlie » Mi 14. Aug 2013, 13:32

At more than 1 minute to load, I think that caching will be mandatory, both on the PVR and probably also on the JavaScript side too.

Thanks for the function names, I'll try them in the next prototype version.

Gesperrt

Zurück zu „SRP/CRP TAP-Bereich“