Home AMX User Forum MODPEDIA - The Public Repository of Modules for Everyone

Digital Loggers (Ethernet Power Controller)

VAV_EPCII_MODULE_Rev1.zip This module is for the Ethernet Power Controller by Digital Loggers which can be found here: http://www.digital-loggers.com/EPCR2.html

I originally posted this module elsewhere on the forum last year or the year before but now that we have this repository I'll post it here so it can be found if needed and it will now have a permanent home.

It's basically an ethernet controlled power strip, which provide 8 banks of outlets on 2 15 amp circuits. Each circuit has 4 banks of individually controlled duplex recepticles. The device itself can do auotping and a host of other cool things so even as a stand alone device it's wroth the $295.00 price tag. It also has front panels switches so even if it's not controlled via PC or TP having front rack switches to cylce power is also cool.

The device required MD5 encryption and I was able to get a module for that from AMXJeff. This module uses HTTP protocol to communicate with the device so it's a bit sloppy compared to telnet or 232 comms. They have a 232 port but last I looked it still wasn't active and for all I know it never will be.

This device has saved my butt several times when transferring new files to remote systems which I inadvertantly put into a loop. Power cycle the master and a quick new file transfer before those files causing the loop run and I'm back in business. I also use on cable boxes, TP power and what ever else benefits from periodic cold reboots. Considering it's the cost of one service call it's a good investment and will make your customers happy when they can either reboot the problem device themselves or have you do it remotely w/o a service charge or waiting until the next day for a tech to get there..

The only thing I'll say about the TP GUI is that it's very colorful. There are power off/on buttons and cycle button for 8 seperatley controll duplex recepticles. You won't see the cycle buttons until the module initializes. The module also provide a reading of the current draw for each circuit.

Comments

  • jjamesjjames Posts: 2,908
    Have you had a chance to play with EPCII Version 1.4.3?

    I'm using your module and it just won't connect. I didn't need any display on the TP, so I took all that out, and went just for commands to turn it on & off . . . so I thought I screwed something up (sure enough I did), so I loaded everything original in and tried it out . . . seems to get stuck on the md5_js thing (step 3) and then it halts.

    Any new revs lately?

    Thanks!

    Edit: Disregard, I whipped up a module to do this without the MD5 - works fine now.
  • viningvining Posts: 4,368
    I just installed a new device but I haven't got around to checking it out through code yet. I have used it several times through its web server to reboot devices but not yet through a TP. I'll check out the version I have and see if I can control it maybe later today. I think I'm suposed to have a picnic today (dad's day) so we'll see how much time I'll have to play.

    I did notice it has some new features so they probably screwed something up. I wonder if they've enable telnet or serial yet? Either of those would be nice and preferable over the HTML method that I was forced to deal with.

    [edit]
    I didn't see your edit on the first read.

    So it doesn't require MD5 encryption anymore? Base64 or open?
    [/edit]
  • jjamesjjames Posts: 2,908
    I *think* serial is enabled on this version actually. You can run "scripts" and send things out of the serial port; I haven't looked though to see if you can control it via serial (or telnet for that matter.)

    Regarding the encryption, I'd be surprised if even the one you developed on required MD5. If you look into the source code of the HTML, the MD5 portion is run through javascript right? They do have an option for those who block javascript - a big red warning box appears saying that it's an insecure (open) connection. Also, creating the MD5 string is now "challenge + username + password + challenge"; this I assume is most likely why I cannot connect with your module, but only found this out after writing mine. I haven't modified yours to see if that is the fix - but I'd venture to guess it is, so it may not require a lot of modification.

    I may stick with the Ethernet control now that I have it working; I'd hate to burn up a com port if I can just do this.
  • viningvining Posts: 4,368
    jjames wrote: »
    I *think* serial is enabled on this version actually. You can run "scripts" and send things out of the serial port; I haven't looked though to see if you can control it via serial (or telnet for that matter.)

    Regarding the encryption, I'd be surprised if even the one you developed on required MD5. If you look into the source code of the HTML, the MD5 portion is run through javascript right? They do have an option for those who block javascript - a big red warning box appears saying that it's an insecure (open) connection. Also, creating the MD5 string is now "challenge + username + password + challenge"; this I assume is most likely why I cannot connect with your module, but only found this out after writing mine. I haven't modified yours to see if that is the fix - but I'd venture to guess it is, so it may not require a lot of modification.

    I may stick with the Ethernet control now that I have it working; I'd hate to burn up a com port if I can just do this.


    The first problem with this version of the Ethernet Power Controller was the return MD5 javascript text didn't end the same as the previous version. The prior version sent an extra CRLF at the end so I remove that but it still didn't work although it should have so I removed some additional CRLF's and a brace and then it work up to that point. There must have been something else coming in I wasn't seeing but when I reduce the find string to just "return str;" it would get passed that point. I also then took this code out of define program (emptied it) and created a timeline to run this section so there's no overhead when no ones on page or controlling power since that would 99.999% of the time and I couldn't see checking these vars on every pass of the mainline.

    Another reason I hate looking at old code, it's hard to leave the stupid $hit in that didn't seem to bother me back in the day but now does.
     if(find_string(cEPCII_ParsingBuff,'</HTML>',1) || 
    		    find_string(cEPCII_ParsingBuff,'</html>',1) ||
    			 find_string(cEPCII_ParsingBuff,"'return str;'",1))
    
    After changing the above section I then had to change the related section in the parsing function and again remove the extra CRLF's and a brace or two.
    CASE EPCII_STEP_3://received after get /md5.js  //this is not really needed since we know the script!
    			 {//we do nothing w/ this            Content-Type: application/x-javascript
    			 fnEPCII_DeBug("'Parse STR: Step 3. >-line-<',ITOA(__LINE__),'>'") ;
    			 if(find_string(cEPCII_ParsingBuff,"'Content-Type: application/x-javascript',CRLF",1) && 
    				   find_string(cEPCII_ParsingBuff,"'return str;'",1))
    			      {
    			      fnEPCII_DeBug("'Parse md5.js ,', itoa(nEPCII_Next_CMD),' >-line-<',ITOA(__LINE__),'>'") ;
    			      cEPCII_Trash = remove_string(cEPCII_ParsingBuff,"'return str;'",1) ;
    			      fnEPCII_RemoveBufferCrap() ;
    			      CANCEL_WAIT 'EPCII_TIME_OUT' ;
    			      nEPCII_Next_CMD ++ ;
    			      }
    			 else
    			      {
    			      fnEPCII_EndProcess(EPCII_DoFeedBack) ;
    			      fnEPCII_DeBug("'Parsing STEP 3 No Go.  Kill Process! >-line-<',ITOA(__LINE__),'>'") ;
    			      }
    			 }
    
    The modification in the MD5 encryption was the easy part thanks to you since you noticed they added the challenge to the beginning of the pre-encryption string as well as end which for the life of me I don't get the need to do that but they did. I guess I could actually parse the MD5 str requirement and build the encryption string accordingly and maybe I will but not tonight.

    Had I tried to figure this out on my own it probably would have taken hours if not days to noticed this change so again thanks. I already had this part changed sso when I located the change in the retuned script and fix it everything work fine.

    DEFINE_FUNCTION CHAR fnEPCII_ENCRYPT_LOGIN(CHAR iChallenge[])
    
         {
         cMD5_STRING = "iChallenge,cEPCII_UserName,cEPCII_Password,iChallenge" ;
         SEND_COMMAND vdvEPCII_MD5_ENCRYPT,"'CYPHER-',cMD5_STRING" ;
         fnEPCII_DeBug("'MD5_STRING = ',cMD5_STRING,' >-line-<',ITOA(__LINE__),'>'") ;
         
         RETURN TRUE ;
         }
    
  • viningvining Posts: 4,368
    EPCII_Rev2_.zip EPCII_Rev2

    Here's a complete update to the module that works with the current version of the devices being shipped and probably the older devices too but I haven't tested. Besides the minor fixes to get it to work with the newest devices I changed the basic stucture of the code so that it now runs more efficiently and I added 8 more buttons (code only buttons) for direct control "cycling" of any single outlet at a time with out the need to log in through the TP GUI, basically a short cut to cycle an outlet's power.

    The original code was pretty horrific and I had a real hard time getting my head wrapped around it to make these changes but it seems to work pretty good now, although the original also worked fine but I've only had a chance to do a moderate amount of testing with this version. I got rid of all that goofy crap I had in the define program section and some other assinine things I wrote in the original code that looking at it now made me just shake my head and wonder what the F I was thinkin'.
  • i have this:

    DEFINE_CONSTANT

    //MD5

    LONG lr[64]={
    7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
    5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
    4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
    6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}

    LONG lk[64]={
    3614090360, 3905402710, 606105819, 3250441966, 4118548399, 1200080426, 2821735955, 4249261313,
    1770035416, 2336552879, 4294925233, 2304563134, 1804603682, 4254626195, 2792965006, 1236535329,
    4129170786, 3225465664, 643717713, 3921069994, 3593408605, 38016083, 3634488961, 3889429448,
    568446438, 3275163606, 4107603335, 1163531501, 2850285829, 4243563512, 1735328473, 2368359562,
    4294588738, 2272392833, 1839030562, 4259657740, 2763975236, 1272893353, 4139469664, 3200236656,
    681279174, 3936430074, 3572445317, 76029189, 3654602809, 3873151461, 530742520, 3299628645,
    4096336452, 1126891415, 2878612391, 4237533241, 1700485571, 2399980690, 4293915773, 2240044497,
    1873313359, 4264355552, 2734768916, 1309151649, 4149444226, 3174756917, 718787259, 3951481745}


    CHAR user[10] = 'remote'
    CHAR pwd[10] = '9999'




    DEFINE_VARIABLE


    //MD5
    cText2[256]
    CHAR A1[32]=''
    CHAR HA1[32]=''
    CHAR A2[32]=''
    CHAR HA2[32]=''
    CHAR Response[32]=''

    //////


    DEFINE_FUNCTION MD5(CHAR cInputstring[256], CHAR cResult[32])
    {
    LOCAL_VAR LONG lh0
    LOCAL_VAR LONG lh1
    LOCAL_VAR LONG lh2
    LOCAL_VAR LONG lh3

    LOCAL_VAR LONG la
    LOCAL_VAR LONG lb
    LOCAL_VAR LONG lc
    LOCAL_VAR LONG ld

    LOCAL_VAR INTEGER nMessageLength

    // LOCAL_VAR CHAR cResult[32]

    cText2=cInputstring

    lh0=$67452301
    lh1=$EFCDAB89
    lh2=$98BADCFE
    lh3=$10325476

    la=lh0
    lb=lh1
    lc=lh2
    ld=lh3

    nMessageLength=LENGTH_STRING(cText2)*8 // Nachrichtenl?nge ermitteln
    cText2="cText2,$80" // 1 Bit anf?gen (10000000)
    WHILE((LENGTH_STRING(cText2)%64)<>56) // 0 Bits auff?llen bis auf letzte 8 Bytes
    {
    cText2="cText2,$00"
    }
    cText2="cText2,nMessageLength%256,nMessageLength/256,$00,$00,$00,$00,$00,$00" // add message Length in little Endian

    WHILE(LENGTH_STRING(cText2))
    {
    LOCAL_VAR INTEGER i
    LOCAL_VAR CHAR cText3[64] // 512 Bit Blocks
    LOCAL_VAR CHAR cText4[16][4] // 16 32 Bit Blocks
    LOCAL_VAR LONG lText4[16] // 16 32 Bit Blocks

    LOCAL_VAR LONG lf
    LOCAL_VAR LONG lg
    LOCAL_VAR LONG ltemp

    cText3=GET_BUFFER_STRING(cText2,64)

    FOR(i=1;i<=16;i++)
    {
    cText4=GET_BUFFER_STRING(cText3,4)
    lText4=(cText4[1])+(cText4[2]*256)+(cText4[3]*65536)+(cText4[4]*16777216)
    }

    FOR(i=0;i<=63;i++)
    {
    SELECT
    {
    ACTIVE(i<=15):
    {
    lf=(lb BAND lc) BOR ((BNOT lb) BAND ld)
    lg=i
    }
    ACTIVE(i<=31):
    {
    lf=(ld BAND lb) BOR ((BNOT ld) BAND lc)
    lg=(5*i+1)%16
    }
    ACTIVE(i<=47):
    {
    lf=lb BXOR lc BXOR ld
    lg=(3*i+5)%16
    }
    ACTIVE(i<=63):
    {
    lf=lc BXOR (lb BOR (BNOT ld))
    lg=(7*i)%16
    }
    }
    ltemp=ld
    ld=lc
    lc=lb
    lb=lb+leftrotate((la+lf+lk[i+1]+lText4[lg+1]),lr[i+1])
    la=ltemp
    }
    lh0=lh0+la
    lh1=lh1+lb
    lh2=lh2+lc
    lh3=lh3+ld
    }
    cResult="FORMAT('%02x',lh0%256),FORMAT('%02x',(lh0/256)%256),FORMAT('%02x',(lh0/65536)%256),FORMAT('%02x',lh0/16777216),
    FORMAT('%02x',lh1%256),FORMAT('%02x',(lh1/256)%256),FORMAT('%02x',(lh1/65536)%256),FORMAT('%02x',lh1/16777216),
    FORMAT('%02x',lh2%256),FORMAT('%02x',(lh2/256)%256),FORMAT('%02x',(lh2/65536)%256),FORMAT('%02x',lh2/16777216),
    FORMAT('%02x',lh3%256),FORMAT('%02x',(lh3/256)%256),FORMAT('%02x',(lh3/65536)%256),FORMAT('%02x',lh3/16777216)"
    }


    DEFINE_FUNCTION LONG leftrotate(LONG lx, LONG ly)
    {
    LOCAL_VAR LONG lRotate
    lRotate=(lx << ly) BOR (lx >> (32-ly))
    RETURN lRotate
    }
  • mushmush Posts: 287
    Daniel79 wrote: »
    i have this:

    G'day Daniel,

    Did you ever get this to work?

    Cheers

    Mush
  • pdabrowskipdabrowski Posts: 184
    mush wrote: »

    G'day Daniel,

    Did you ever get this to work?

    Cheers

    Mush

    Hey Mush, That MD5 function seems to be similar to the one Bruno has in his AXW for Panasonic projectors here: http://www.amxforums.com/forum/technical-forum/general-discussion/8481-?p=87351#post87351

    I grabbed that file and used it to form an authentication module that worked for the later DZ models so the MD5 function itself is working.
  • viningvining Posts: 4,368
    The one in this EPC module is still working. The MD5 module was provided mpby AMX_Chris. The MD5 module is compiled so you don't have access to the code but you csn include it and pass it your parameters and it returns the encryted string.
  • Thank you, whoever wrote that MD5 implementation.

    But it's wrong.

    It fails for strings greater than 55 Chars.

    After a long night and day with the poor debugging methods of AMX and comparing to implementations for other languages, i got the error.

    Wikipedia got me the clue.


    The four initializations of the hashes have to accur on every loop run. not once before the MD5 function is being started.

    The block need to be moved here:
    ....
    WHILE(LENGTH_STRING(cText2)) {
            LOCAL_VAR INTEGER i
            LOCAL_VAR CHAR cText3[64] // 512 Bit Blocks
            LOCAL_VAR CHAR cText4[16][4] // 16 32 Bit Blocks
            LOCAL_VAR LONG lText4[16] // 16 32 Bit Blocks
    
            LOCAL_VAR LONG lf
            LOCAL_VAR LONG lg
            LOCAL_VAR LONG ltemp
    
    [COLOR=#008000][B]        la=lh0
            lb=lh1
            lc=lh2
            ld=lh3[/B][/COLOR]
    ....
    


    Not here:
    ....
    cText2=cInputstring
    
    lh0=$67452301
    lh1=$EFCDAB89
    lh2=$98BADCFE
    lh3=$10325476
    
    [COLOR=#FF0000]la=lh0
    lb=lh1
    lc=lh2
    ld=lh3[/COLOR]
    
    nMessageLength=LENGTH_STRING(cText2)*8 // Nachrichtenl?nge ermitteln
    .....
    

    I also changed some numbers to hex representation.

    I have to wait for the room get cleared now. when the big tests pass, I'll post my modificated snipped for future uses here.
Sign In or Register to comment.