jbonzey Posted November 26, 2012 Share Posted November 26, 2012 The application has to do with an alarm system. When an alarm event occurs it generates a 16 digit/character number and logs it on my linux server. I am trying to translate the code into english using str_replace. The problem i have is the last character/number is a checksum and changes so my search never comes up with a match. I got around this by just seaching the first 15 digits/characters even though the string is 16 digits/characters. This works and i have a valid match. Problem is once the replace happens, the 16th digit/character is showing up to the right of the replace. Question /Example 1: I can only search on the first 15 characters/digits of the 16 generated by the alarm The alarm generates the following string: 769418113401001A I execute the following line: file_put_contents($file,str_replace('769418113401001','769418113401001 Garage Kitchen Entry ',file_get_contents($file))); The output from the above line is: 769418113401001 Garage Kitchen Entry A How do I stop the 16th character/digit in this case "A" from showing up in the output????????????? Question/Example 2: I can only search on the first 10 characters/digits of the 16 generated by the alarm The alarm generates the following string: 7694181250123456 I execute the following line: file_put_contents($file,str_replace('7694181250','7694181250 Fire Alarm ',file_get_contents($file))); 7694181250 Fire Alarm 123456 How do i stop the last 6 digits/characters from showing up in the output? thanks for your help !!!!!!! Quote Link to comment Share on other sites More sharing options...
AyKay47 Posted November 26, 2012 Share Posted November 26, 2012 Perhaps you can use preg_replace instead of str_replace() to capture the checksum character as well. Quote Link to comment Share on other sites More sharing options...
Barand Posted November 26, 2012 Share Posted November 26, 2012 substr Quote Link to comment Share on other sites More sharing options...
jbonzey Posted November 26, 2012 Author Share Posted November 26, 2012 (edited) Can you guys give me an idea as to how to do this with your suggestions as i am lost. I looked up substr but don't understand how to make it work with my application. The actual php script is below. It needs to search for a string in a specified file but the 16th character is never constant. The way i did it below works but displays the 16 digit/character as it leaves it alone during the replace. <?php $file = '/etc/asterisk/alarm/latest.txt'; // // System Alarms file_put_contents($file,str_replace('769418130101000','769418130101000 AC Power Failure ',file_get_contents($file))); file_put_contents($file,str_replace('769418330101000','769418330101000 AC Power Restore ',file_get_contents($file))); // // Zone Alarms file_put_contents($file,str_replace('769418113401001','769418113401001 Garage Kitchen Entry ',file_get_contents($file))); file_put_contents($file,str_replace('769418113101007','769418113101007 Bulkhead Basement Door ',file_get_contents($file))); file_put_contents($file,str_replace('769418113101008','769418113101008 Phone Tamper ',file_get_contents($file); ?> Edited November 26, 2012 by jbonzey Quote Link to comment Share on other sites More sharing options...
Pikachu2000 Posted November 26, 2012 Share Posted November 26, 2012 How abut posting a couple lines of the actual data you have, and what it should be after it's processed? Quote Link to comment Share on other sites More sharing options...
jbonzey Posted November 26, 2012 Author Share Posted November 26, 2012 (edited) The application has to do with an alarm system. When an alarm event occurs it generates a text file that has a 16 digit/character number at the bottom of the text file and logs it on my linux server. I am trying to translate the code into english using str_replace. The problem i have in the first example below is the last character/number is a checksum and changes so my search never comes up with a match. I got around this by just seaching the first 15 digits/characters even though the string is 16 digits/characters. This works and i have a valid match. Problem is once the replace happens, the 16th digit/character is showing up to the right of the replace. The problem i have in the second example below is only the first 10 digits are constant and the remaining 6 are never the same. Question /Example 1: I can only search on the first 15 characters/digits of the 16 generated by the alarm as the 16th is never the same. The alarm generates the following text file: [metadata] PROTOCOL=ADEMCO_CONTACT_ID CALLINGFROM=5085551212 CALLERNAME=<unknown> TIMESTAMP=Wed Nov 21, 2012 @ 13:33:58 EST [events] 769418130101000B I execute the following php script: <?php $file = '/etc/asterisk/alarm/latest.txt'; // // System Alarms file_put_contents($file,str_replace('7694181110','7694181110 Fire Alarm ',file_get_contents($file))); file_put_contents($file,str_replace('7694183110','7694183110 Fire Alarm Clear ',file_get_contents($file))); file_put_contents($file,str_replace('7694181111','7694181111 Smoke Alarm ',file_get_contents($file))); file_put_contents($file,str_replace('7694183111','7694183111 Smoke Alarm Clear ',file_get_contents($file))); file_put_contents($file,str_replace('7694181302','7694181302 Low System Battery ',file_get_contents($file))); file_put_contents($file,str_replace('769418130101000','769418130101000 AC Power Failure ',file_get_contents($file))); file_put_contents($file,str_replace('769418330101000','769418330101000 AC Power Restore ',file_get_contents($file))); ?> The output from the above line is: 769418130101000 AC Power Failure B How do I stop the 16th character/digit in this case "B" from showing up in the output????????????? Question/Example 2: For some alarms I can only search on the first 10 characters/digits of the 16 generated by the alarm as the last 6 are never the same. The alarm generates the following Text file: [metadata] PROTOCOL=ADEMCO_CONTACT_ID CALLINGFROM=5085551212 CALLERNAME=<unknown> TIMESTAMP=Wed Nov 21, 2012 @ 13:33:58 EST [events] 7694181302123456 <?php $file = '/etc/asterisk/alarm/latest.txt'; // // System Alarms file_put_contents($file,str_replace('7694181110','7694181110 Fire Alarm ',file_get_contents($file))); file_put_contents($file,str_replace('7694183110','7694183110 Fire Alarm Clear ',file_get_contents($file))); file_put_contents($file,str_replace('7694181111','7694181111 Smoke Alarm ',file_get_contents($file))); file_put_contents($file,str_replace('7694183111','7694183111 Smoke Alarm Clear ',file_get_contents($file))); file_put_contents($file,str_replace('7694181302','7694181302 Low System Battery ',file_get_contents($file))); file_put_contents($file,str_replace('769418130101000','769418130101000 AC Power Failure ',file_get_contents($file))); file_put_contents($file,str_replace('769418330101000','769418330101000 AC Power Restore ',file_get_contents($file))); ?> The script outputs: 7694181302 Low System Battery 123456 How do i stop the last 6 digits/characters from showing up in the output ? I can not just delete the digits/characters as i need to be able to read all 15 as explained in example 1. The script needs to be looking for either scenerio. I just learning php so please be as detailed as possible. Thanks very much for your help !!!!!!!! Edited November 26, 2012 by jbonzey Quote Link to comment Share on other sites More sharing options...
Psycho Posted November 26, 2012 Share Posted November 26, 2012 (edited) Although regular expressions are slower than string functions, I think that is the best solution for you in this situation. But, file_put_contents() is probably not a good choice at it will likely encounter a performance hit as well since each call is effectively opening, writing and closing the file. It would probably be better to read the file into a variable, modify the contents of the variable, then write the file one time. //Specify the file $file = '/etc/asterisk/alarm/latest.txt'; //Get contents of file $contents = file_get_contents($file); //Make replacements in file $contents = preg_replace('#7694181110\d{6}#', '7694181110 Fire Alarm', $contents); $contents = preg_replace('#7694183110\d{6}#','7694183110 Fire Alarm Clear ', $contents); $contents = preg_replace('#7694181111\d{6}#','7694181111 Smoke Alarm ', $contents); $contents = preg_replace('#7694183111\d{6}#','7694183111 Smoke Alarm Clear ', $contents); $contents = preg_replace('#7694181302\d{6}#','7694181302 Low System Battery ', $contents); $contents = preg_replace('#769418130101000\d#','769418130101000 AC Power Failure ', $contents); $contents = preg_replace('#769418330101000\d#','769418330101000 AC Power Restore ', $contents); file_put_contents($file, $contents); Note, the \d represent any digit and the {6} means to repeat the previous character 6 times. So, the first 5 replacements are looking for the specific number followed by any 6 additional digits. The last two are looking for the specific number followed by any one digit. But, if all of the codes in the source file are always 16 digits, I'd suggest creating an array of all your alarm codes and creating a function to dynamically do the replacements. Edited November 26, 2012 by Psycho Quote Link to comment Share on other sites More sharing options...
Psycho Posted November 26, 2012 Share Posted November 26, 2012 (edited) This seems to work per your requirements and only requires you to add a new alarm code and description to the array //Array of alarm codes and their descriptions $alarm_codes = array( '7694181110' => 'Fire Alarm', '7694183110' => 'Fire Alarm Clear', '7694181111' => 'Smoke Alarm', '7694183111' => 'Smoke Alarm Clear', '7694181302' => 'Low System Battery', '769418130101000' => 'AC Power Failure', '769418330101000' => 'AC Power Restore', ); //Specify the file $file = 'latest.txt'; //Get contents of file $contents = file_get_contents($file); //Make replacements in content for each alarm code foreach($alarm_codes as $code => $description) { $addlDigits = str_repeat('\d', 16 - strlen($code)); $pattern = "#{$code}{$addlDigits}#"; $replacement = "{$code} {$description}"; $contents = preg_replace($pattern, $replacement, $contents); } //Write new content to file file_put_contents($file, $contents); Edited November 26, 2012 by Psycho Quote Link to comment Share on other sites More sharing options...
jbonzey Posted November 26, 2012 Author Share Posted November 26, 2012 Psycho - THANKS FOR YOU HELP - we are real close!!! Your code works perfectly unless the 16th position is a character or *. I went though a dozen or so events and it consistantly works correctly when the alarm event ends in a number. If position 16 ends in a letter or a * it fails. Example one above fails because there is a B in the 16th position. Below are some examples: This is the event from the alarm panel: [metadata] PROTOCOL=ADEMCO_CONTACT_ID CALLINGFROM=5085551212 CALLERNAME=<unknown> TIMESTAMP=Sat Nov 24, 2012 @ 14:30:59 EST [events] 769418113101007* 7694181131010148 7694181131010148 7694181131010021 769418113101003C 769418113101005A 7694181131010157 7694181131010139 7694181131010139 This is the output from your code fix: [metadata] PROTOCOL=ADEMCO_CONTACT_ID CALLINGFROM=5087554994 CALLERNAME=<unknown> TIMESTAMP=Sat Nov 24, 2012 @ 14:30:59 EST [events] 769418113101007* 769418113101014 Cellar Windows 769418113101014 Cellar Windows 769418113101002 Foyer Windows 769418113101003C 769418113101005A 769418113101015 Kitchen French Left Door 769418113101013 Kitchen French Right Door ****************** The php file used for the above output is below: <?php //Array of alarm codes and their descriptions $alarm_codes = array( // System Alarms '7694181110' => 'Fire Alarm', '7694183110' => 'Fire Alarm Clear', '7694181111' => 'Smoke Alarm', '7694183111' => 'Smoke Alarm Clear', '7694181302' => 'Low System Battery', '7694183302' => 'Low System Battery Restore', '7694181320' => 'Bell Relay Trouble', '7694183320' => 'Bell Relay Trouble Restore', '7694181316' => 'System Tamper', '7694183316' => 'System Tamper', '7694181350' => 'Communications Alarm', '7694183350' => 'Communications Alarm', '7694181351' => 'Telco Line Fault', '7694183351' => 'Telco Line Fault Restore', '769418160201000' => 'Weekly Test', '769418130101000' => 'AC Power Failure', '769418330101000' => 'AC Power Restore', // Zone Alarms '769418113401001' => 'Garage Kitchen Entry', '769418113101001' => 'Garage Kitchen Entry', '769418113101002' => 'Foyer Windows', '769418113101003' => 'Front Door', '769418113201004' => 'Foyer Motion', '769418113101005' => 'Dining Room Windows', '769418113101006' => 'Family Room Front Windows', '769418113101007' => 'Bulkhead Basement Door', '769418113101008' => 'Phone Tamper', '769418113101009' => 'Family Side Windows', '769418113101010' => 'Family Room French Doors', '769418113201011' => 'Family Room Motion', '769418113101012' => 'Kitchen Window', '769418113101013' => 'Kitchen French Right Door', '769418113101014' => 'Cellar Windows', '769418113101015' => 'Kitchen French Left Door', '769418113101000' => 'Panic Button', '769418112001000' => 'Panic Button #2', ); //Specify the file $file = 'latest.txt'; //Get contents of file $contents = file_get_contents($file); //Make replacements in content for each alarm code foreach($alarm_codes as $code => $description) { $addlDigits = str_repeat('\d', 16 - strlen($code)); $pattern = "#{$code}{$addlDigits}#"; $replacement = "{$code} {$description}"; $contents = preg_replace($pattern, $replacement, $contents); } //Write new content to file file_put_contents($file, $contents); ?> Quote Link to comment Share on other sites More sharing options...
Psycho Posted November 26, 2012 Share Posted November 26, 2012 Sorry, I thought it was only numbers. That's easy enough to fix: just use the period character (to match against any character) for the additional characters to pad the code out to 16 characters. This also simplifies the process a bit since you can just use str_pad() since you will be padding with just a single character '.' vs. '\d' //Array of alarm codes and their descriptions $alarm_codes = array( '7694181110' => 'Fire Alarm', '7694183110' => 'Fire Alarm Clear', '7694181111' => 'Smoke Alarm', '7694183111' => 'Smoke Alarm Clear', '7694181302' => 'Low System Battery', '769418130101000' => 'AC Power Failure', '769418330101000' => 'AC Power Restore', ); //Specify the file $file = 'latest.txt'; //Get contents of file $contents = file_get_contents($file); //Make replacements in content for each alarm code foreach($alarm_codes as $code => $description) { $pattern = str_pad($code, 16, '.'); $replacement = "{$code} {$description}"; $contents = preg_replace("#{$pattern}#", $replacement, $contents); } //Write new content to file file_put_contents($file, $contents); Quote Link to comment Share on other sites More sharing options...
jbonzey Posted November 26, 2012 Author Share Posted November 26, 2012 Psycho - PERFECT !!!!!!! Thanks so much for your time !!!!!! Regards John Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.