The function luup.ir.pronto_to_gc100() that is required to get the GC100 to work has not been implemented in openLuup yet and I was wondering if this is known?
Known once, yes, but forgotten aboutâŠ
None of the luup.ir module is implemented, simply because Iâve never used IR, and also because openLuup has very little to do with hardware specific devices.
Iâve no idea what it does. Let me take a look.
Oh, guess what? I canât find any documentation on this at all.
EDIT - see next post
luup.ir.pronto_to_gc100(IRCode)
Iâve only ever seen this used by the GC100, so yes itâs very specialised. However, I suspect there are a lot of GC100s in circulation (I use two).
As far as I can see, all it does is convert a given string to a string that suits the GC100.
- get all the space delimited four digit hex values and convert each one to decimal
- drop the first four numbers - the pronto preamble
- create a new comma delimited string of all the decimal values as string values with no leading zeroes
- prepend the string with â40000,1,1,â where the 40000 = the IR âfrequency Hzâ, 1 is the ârepeat rateâ and 1 is âoffsetâ
Thatâs it as far as I can see.
The repeat rate is internally set to 2, not 1 like in the example above. Repeating the IR codes creates havoc with some devices, when a toggle like on/off is used, rather than discrete on and off codes. I suppose you could add the repeat rate as a 2nd optional parameter and default it to one, not two. Or just do what I normally do - modify the plugin - but automatic updates can override this process:
http://forum.micasaverde.com/index.php/topic,29685.msg298566.html#msg298566
Itâs all just academic - itâs probably better to just write a new GC100 plugin and keep openLuup independent of hardware.
sample input string:
'0000 0067 0000 0030 0060 0018 0030 0018 0030 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 0018 0018 0018 0030 0018 0030 0018 0018 0018 0018 0336 0060 0018 0030 0018 0030 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 0018 0018 0018 0030 0018 0030 0018 0018 0018 0018 0336 0060 0018 0030 0018 0030 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 0018 0018 0018 0030 0018 0030 0018 0018 0018 0018 0336'
gets converted to:
'40000,2,1,96,24,48,24,48,24,48,24,48,24,24,24,48,24,24,24,24,24,24,24,24,24,24,24,48,24,48,24,24,24,24,822,96,24,48,24,48,24,48,24,48,24,24,24,48,24,24,24,24,24,24,24,24,24,24,24,48,24,48,24,24,24,24,822,96,24,48,24,48,24,48,24,48,24,24,24,48,24,24,24,24,24,24,24,24,24,24,24,48,24,48,24,24,24,24,822'
Hereâs a link to the GlobalCache API - refer page 11, section â5.4.6 Sending IR:â
You might want to try replacing the call to luup.ir.pronto_to_gc100() with a call to the following code in I_GC100.xml:
local function pronto_to_gc100(prontoCode)
local strTab = {}
local decNum = 0
local decStr = ''
for hexStr in string.gmatch(prontoCode, '([^%s]+)') do
decNum = tonumber(hexStr, 16)
decStr = tostring(decNum)
table.insert(strTab, decStr)
end
-- replace the pronto code preamble with the GC100 preamble
strTab[1] = '40000'
strTab[2] = '1'
strTab[3] = '1'
table.remove(strTab, 4)
return table.concat(strTab, ',')
end
Excellent!
I shall add luup.ir.pronto_to_gc100() to openLuup, with this:
local function pronto_to_gc100(prontoCode)
-- replace the pronto code preamble with the GC100 preamble
local strTab = {40000, 1, 1}
prontoCode = prontoCode: gsub ("^%s*%x+%s+%x+%s+%x+%s+%x+%s+", '')
for hexStr in prontoCode: gmatch "%x+" do
strTab[#strTab+1] = tonumber(hexStr, 16)
end
return table.concat(strTab, ',')
end
Thanks for filling an openLuup gap!
Been having a go at getting the GC100 plugin to work. Interesting :o
The code contains this line. It implies ioIntercept() returns something. It doesnât - so nil == false = false.
EDIT: further testing indicates ioIntercept() returns a boolean and may be passed a device ID but without one, defaults to the current device. If executed in the Lua Code Test panel, it returns nil.
Still looks like a bit of spare code:
if luup.io.intercept()==false or luup.io.write("getdevices")==false then
The D_GC100.xml file contains the tag . This is the only plugin I could find that uses this tag. It getâs mentioned here:
http://wiki.mios.com/index.php/Luup_Plugins_ByHand#.3CioPort.3E
It looks like openLuup does not take any note of it. Not surprised really. :-\
mios as far as I understand it, at start up opens as many sockets as it has info for (using device ip attribute and ). So the GC100 code doesnât use luup.io.open() as it assumes itâs already done. It looks like openLuup doesnât do this, as I had to insert this line to get things going or alternatively openLuup was missing the io port? Itâs easy enough to forget the tag and just append the io port to the ip address attribute.
luup.io.open(lul_device,luup.devices[lul_device].ip,4998)
Next problem: Turns out the GC100 uses the âcrâ protocol, although the D_GC100.xml file specifies the âcrlfâ protocol. It looks like the mios read stops at the first âcrâ and any subsequent âlfâ probably gets lost somewhere. However openLuup (more correctly) stops at the first âlfâ, which was never received, as the GC100 never sent it. So I had to change the D_GC100.xml file to specify the (correct) âcrâ protocol.
In openLuup, luup.io.intercept() must be executed before every read. This does not match with what mios does - it is not required before every read. That then raises the question how does mios implement luup.io.intercept(). Nobody seems to know >:( I suspect it is meant to be called before the very first write is done and then all subsequent reads are not passed on to the process. It may be a toggle, in that if it is used again, it re-enables the redirection to the process. As suggested by this post:
http://forum.micasaverde.com/index.php/topic,28853.msg206688.html#msg206688
I still need to look at this further but thatâs it for the moment.
Ok, not surprised by any of this.
What youâre seeing is just how poor the low-level IO implementation is in Vera. I get the impression that a lot of this was tacked on afterwards specifically for the GC100, which figures so highly in their âdocumentationâ. Itâs a much lower standard than the rest of the MiOS design, to say nothing of the implementation. One of the biggest omissions is the lack of a luup.io.close() function, which means that if a remote connection goes down thereâs nothing that you can do about it but reload the system.
[] It looks like openLuup does not take any note of it. Not surprised really.
Yes, quite right. I could add this without much problem, but my implementation had mostly been driven by need and, as you point out, nothing else out there seems to use it.
In openLuup, luup.io.intercept() must be executed before every read. This does not match with what mios does
I have gone around the houses several times on this one. On the one hand, it is actually quite difficult to discern what Vera actually does, and on the other hand I had a lengthy discussion with @cybrmage about it, and a lot of testing, to make things work for the EVL3Vista plugin. See these posts:
http://forum.micasaverde.com/index.php/topic,35972.msg266490.html#msg266490
http://forum.micasaverde.com/index.php/topic,35983.msg266858.html#msg266858
I donât know if the Vera implementation has been changed since December 2014, which is the date of the post you reference.
IF we can resolve this so that everything works, then that would be great. Second-best is an implementation of GC100 which does work on openLuup, which sounds like the direction of travel at the moment.
I have gone around the houses several times on this one.Yes - not surprising given the documentation. All I can say is that I have three plugins that use luup.io.intercept() and none of them work with openLuup until I put a put a luup.io.intercept() before every luup.io.read(). I have another plugin that uses and it appears to work perfectly.
(till I change my mind) Iâll stick with this re: luup.io.intercept()
is meant to be called before the very first write is done and then all subsequent reads are not passed on to the process. It may be a toggle, in that if it is used again, it re-enables the redirection to the process
A quick read of the posts you referred seem to suggest that the EVL3Vista plugin uses luup.io.intercept(), luup.io.read() & luup.io.write() and the process as well. Thatâs very scary.
The GC100 is plugin number four - looks like it was written up quickly to storm the USB-UIRT market. 8)
Note sure if you have an iTach device. However, I have attached four files that allows this particular device to function â
It will probably work with others in the family but the above is the device I tested on. It should work with UI7. If using openLuup, you must be using openLuup from the development branch (as of 1 May 2017) installed for it to function. You update openLuup using AltUI:
Moreâ>Pluginsâ> âopenLuupâ row and âupdateâ column - enter the word development into the entry box and hit the update button
Restart openLuup/refresh browser
Then copy the files attached to this post to /etc/cmh-ludl/files/
In AltUI on the devices page hit the create button and enter the following info:
GC100
D_GC100.xml
I_GC100.xml
Restart openLuup/refresh browser
When the GC100 device shows up, enter the ip address in its panel
Restart openLuup/refresh browser
You then end up with a parent and three âIR transmitterâ children.
At this point, some other plugin that sends IR codes eg a TV set plugin would have one of the IR children assigned as its IR transmitter, by referencing its device number.
How thatâs done depends on the requirements of the plugin that will use the IR transmitter child but it would call this at some point:
luup.call_action('urn:micasaverde-com:serviceId:IrTransmitter1', 'SendProntoCode', {ProntoCode = PCode}, IODevice_ID)
The altered plugin will probably work in Vera as well (untested). The code may change in the future as openLuup changes.
EDIT: updated files to a-lurker version - see attached
Ver 0.51
[ul][li]splits out the Lua code into a separate file: L_GC100.lua[/li]
[li]allows GC100 IR codes to be used, as an alternative to Pronto IR codes[/li][/ul]
Need to refine the luup.ir.pronto_to_gc100(IRCode) function a little further.
In the example below the Pronto code â0067â (second word) must be used to calculate the 40000 (first value) for the iTach G100, rather than just replacing it.
sample input string:
'0000 0067 0000 0030 0060 0018 0030 0018 0030 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 0018 0018 0018 0030 0018 0030 0018 0018 0018 0018 0336 0060 0018 0030 0018 0030 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 0018 0018 0018 0030 0018 0030 0018 0018 0018 0018 0336 0060 0018 0030 0018 0030 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 0018 0018 0018 0030 0018 0030 0018 0018 0018 0018 0336'
gets converted to:
'40000,2,1,96,24,48,24,48,24,48,24,48,24,24,24,48,24,24,24,24,24,24,24,24,24,24,24,48,24,48,24,24,24,24,822,96,24,48,24,48,24,48,24,48,24,24,24,48,24,24,24,24,24,24,24,24,24,24,24,48,24,48,24,24,24,24,822,96,24,48,24,48,24,48,24,48,24,24,24,48,24,24,24,24,24,24,24,24,24,24,24,48,24,48,24,24,24,24,822'
The calculation is as follows:
local PRONTO_PWM_HZ = 4145152 -- a constant measured in Hz and is the pulse width modulator frequency used by the Philip's Pronto remotes
local firstWordGC100 = PRONTO_PWM_HZ/pronto2ndWord
--[[
refer: http://www.remotecentral.com/features/irdisp3.htm
4,145,152/103 = 40,244 Hz ie close enough to Sony's IR carrier frequency of 40,000 Hz and where 103 dec = 0067 hex
refer: http://files.remotecentral.com/library/3-1/yamaha/receiver/index.html
4,145,152/109 = 38,029 Hz ie close enough to Yamaha's IR carrier frequency of 38,000 Hz and where 109 dec = 006D hex
]]
Where does 4,145,152 come from?
The Philipâs Pronto remotes used one of the Freescale DragonBall CPU series.
The calculations are the same as or similar to these but not proven definitively:
An inexpensive 32,768 Hz crystal is frequency multiplied by an onboard PLL with the default multiplier of 2024
32,768 * 2024 = 66,322,432 Hz
This is divided internally to make SYSCLK:
66,322,432 / 4 = 16,580,608 Hz
The smallest prescaler divider for the PWM clock is 4
16,580,608 /4 = 4,145,152 Hz
1/4,145,152 = 0.241246 usec period
The above form is also used as described on various sites eg:
Hi Ackbooer
Wondering if you can implement the above mod before doing a new release?
And for those interested Iâve update the GC100 code and split out the I_GC100.xml into a I_GC100.xml and L_GC100.lua file. It also adds the option to send GC100 codes instead of Pronto codes. See files in post further above.
This had, in fact, completely passed me by! Iâll happily add it, but I do have a question (despite the extensive commenting - thanks.)
Your original preamble was [tt]{4000, 1, 1}[/tt], and I see how the first word is modified, but where does the [tt]2[/tt] come from in the second one in your example, and is the third [tt]1[/tt] ever modified? It seems to be related to the âburst pairâ, but itâs not clear to me.
The second word is how many times to repeat the IR code and the third word is an offset into the code that bypasses the preamble of the IR code for those IR codes that use them (not all work this way). This preamble is the IR code preamble and is not to be confused with the GC100 preamble. So the GC100 would generate: IR preamble, IR command, IR command, etc. The third word is only applicable, if the repeat is set to higher than one.
I have always avoided using the GC100 repeat functionality, as you have no control of the dwell time between repeats. As the GC100 allows full control of the mark and space periods, itâs easier to just send one command to the GC100 that: describes your IR code, then describes a dwell period and then your IR code again; all concatenated together to make one big code that contains the repeated IR codes.
Some devices actually require an IR code to be repeated three times with a certain period before they are recognised. Variations on the theme are volume up commands; that use an arbitrary repeat (ie the user is say; continually depressing the volume up command button) with a relatively long delay between codes being required.
The original Luup routine forced the repeat to two. That is a fundamentally flawed approach and can cause havoc if the IR command is a toggle; like on/off.
In my experience, itâs best not to use the GC100 repeat at all. I wrote some Lua code to create any repeated commands I needed, allowing full control over how they were timed. These concatenated codes are then sent as one long code by the GC100.
Other examples are aircons: where the codes sent are very complex; consisting of multiple groups of information. Using any built in repeat command (can) completely stuffs up any attempt to control them.
So thatâs a [tt]1[/tt], then
Version 2017.06.19 in the development branch implements this.
Please tell me it works!
It works fine.
I notice that in Vera, they round their calculations to the nearest thousand Hz. Personally I think itâs best to be precise, by using the calculation without any rounding (as you have done in openLuup), as rounding may compromise the associated bit mark/space values. But for the record, here are some sample values that Vera produces:
2nd word & frequency calculated by Vera:
0070 37,000 Hz
006F 37,000 Hz
006D 38,000 Hz
006E 38,000 Hz
006D 38,000 Hz
006C 38,000 Hz
006B 39,000 Hz
006A 39,000 Hz
0069 39,000 Hz
0068 40,000 Hz
0067 40,000 Hz
0066 41,000 Hz
0065 41,000 Hz
0064 41,000 Hz
0063 42,000 Hz
0060 43,000 Hz
005F 44,000 Hz
[quote=âa-lurker, post:14, topic:191951â]The second word is how many times to repeat the IR code and the third word is an offset into the code that bypasses the preamble of the IR code for those IR codes that use them (not all work this way). This preamble is the IR code preamble and is not to be confused with the GC100 preamble. So the GC100 would generate: IR preamble, IR command, IR command, etc. The third word is only applicable, if the repeat is set to higher than one.
I have always avoided using the GC100 repeat functionality, as you have no control of the dwell time between repeats. As the GC100 allows full control of the mark and space periods, itâs easier to just send one command to the GC100 that: describes your IR code, then describes a dwell period and then your IR code again; all concatenated together to make one big code that contains the repeated IR codes.
Some devices actually require an IR code to be repeated three times with a certain period before they are recognised. Variations on the theme are volume up commands; that use an arbitrary repeat (ie the user is say; continually depressing the volume up command button) with a relatively long delay between codes being required.
The original Luup routine forced the repeat to two. That is a fundamentally flawed approach and can cause havoc if the IR command is a toggle; like on/off.
In my experience, itâs best not to use the GC100 repeat at all. I wrote some Lua code to create any repeated commands I needed, allowing full control over how they were timed. These concatenated codes are then sent as one long code by the GC100.
Other examples are aircons: where the codes sent are very complex; consisting of multiple groups of information. Using any built in repeat command (can) completely stuffs up any attempt to control them.[/quote]
I do like the fact though that with that pulse train you can, for example, do a volume jump up/down. But you are right it is a flawed design.