Created
May 27, 2010 21:55
-
-
Save lightcap/416408 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require 'rexml/document' | |
| require "models/prog_const.rb" | |
| # TODO: MK Get rid of all vestiges of Dupin's global cache that doesn't cache anything. | |
| $prog_const = ProgConst.new if $prog_const.nil? | |
| $prog_const.check_reload | |
| #This object holds all the required information about a PVM post the system | |
| #will need to work with the xml message | |
| # | |
| class PostPackage | |
| MARSHAL_VERSION = 1 | |
| attr_accessor :serial_number, :text_serial, :message_type, :poll_count, :poll_interval, | |
| :xml, :mac_address, :ip_address, :timestamp_on | |
| #Population code, this code is made to be very quick | |
| def populate( ip_address, mac_address, xml, timestamp_on ) | |
| #Store the basic data we are just given here | |
| @ip_address = ip_address.gsub(/[^\.0-9]/, '') | |
| @mac_address = mac_address.upcase.gsub(/[^A-F0-9]/, '') | |
| @xml = xml | |
| @timestamp_on = timestamp_on | |
| #Figure out what the serial number of this thing is | |
| regex = /<inverter_serial>([^>]*)<\/inverter_serial>/.match(xml) || /<serial_number>([^>]*)<\/serial_number>/.match(xml) | |
| @serial_number = regex[1] unless regex.nil? | |
| regex = /<text_serial>([^>]*)<\/text_serial>/.match(xml) | |
| @text_serial = regex[1] unless regex.nil? | |
| @firmware_version = determine_firmware | |
| #Figure out what the message type and the poll count | |
| if (regex = /(<message[^>]*>)/.match(xml)) | |
| mesg = regex[1] | |
| #Get the poll count | |
| @poll_count = regex[1].to_i if (regex = | |
| /poll_count=['"]([0-9]+)['"]/.match(mesg)) | |
| #Get the poll interval in seconds | |
| @poll_interval = regex[1].to_i if (regex = | |
| /poll_interval=['"]([0-9]+)['"]/.match(mesg)) | |
| #Get the poll count | |
| @message_type = regex[1] if (regex = | |
| /type=['"]([a-zA-Z0-9]+)['"]/.match(mesg)) | |
| end | |
| #check if we are valid or not | |
| if @serial_number.nil? or @poll_count.nil? or @poll_interval.nil? or @message_type.nil? or @mac_address.nil? | |
| @valid = false | |
| else | |
| @valid = true | |
| end | |
| self | |
| end | |
| def data | |
| @data ||= load_from_xml(extract_message(self.xml)) | |
| end | |
| def validate(package_validator = nil) | |
| if package_validator.nil? | |
| @post_val = PostValidator.new(self) | |
| @post_val.validate | |
| end | |
| end | |
| def errors | |
| @post_val.errors unless @post_val.nil? | |
| end | |
| def safe_inv_model | |
| return @post_val.inv_model || $prog_const.inv_models.first | |
| end | |
| def inv_model | |
| @post_val.inv_model | |
| end | |
| #Return true, false/nil if we are valid | |
| def valid? | |
| validate if @post_val.nil? | |
| return @valid && @post_val.valid? | |
| end | |
| def serial_number_valid? | |
| validate if @post_val.nil? | |
| @post_val.serial_number_valid? | |
| end | |
| def text_serial_valid? | |
| validate if @post_val.nil? | |
| @post_val.text_serial_valid? | |
| end | |
| def segis? | |
| # Right now, versions aren't allowed to be released with point version numbers. So straight float comparisions will work, here. | |
| ((@firmware_version >= Gem::Version.create("2.18") && @firmware_version < Gem::Version.create("3.0") && scaling?) || | |
| @firmware_version >= Gem::Version.create("3.2") || string_combiner? || weather_station?) | |
| end | |
| def scaling? | |
| match = /<scaling>([^>]*)<\/scaling>/.match(xml) | |
| return @scaling = /<scaling>([^>]*)<\/scaling>/.match(xml)[1].to_f === 1 unless match.nil? | |
| return false | |
| end | |
| def marshal_dump | |
| [MARSHAL_VERSION, | |
| @serial_number, | |
| @text_serial, | |
| @message_type, | |
| @poll_count, | |
| @poll_interval, | |
| @xml, | |
| @mac_address, | |
| @ip_address, | |
| @timestamp_on | |
| ] | |
| end | |
| def marshal_load(array) | |
| @serial_number = array[1] | |
| @text_serial = array[2] | |
| @message_type = array[3] | |
| @poll_count = array[4] | |
| @poll_interval = array[5] | |
| @xml = array[6] | |
| @mac_address = array[7] | |
| @ip_address = array[8] | |
| @timestamp_on = array[9] | |
| end | |
| # Returns true if xml contains both <string_combiner> and </string_combiner> tags | |
| def string_combiner? | |
| ! /<string_combiner [^>]*>/.match(xml).nil? and ! /<\/string_combiner>/.match(xml).nil? | |
| end | |
| # Returns true if xml contains both <weather_station> and </weather_station> tags | |
| def weather_station? | |
| ! /<weather_station [^>]*>/.match(xml).nil? and ! /<\/weather_station>/.match(xml).nil? | |
| end | |
| def extra_stuff? | |
| string_combiner? || weather_station? | |
| end | |
| #dump this info | |
| def debug | |
| return "PackageDump, Mac Address #{@mac_address}, IP Addresss #{@ip_address}, Serial #{@serial_number}, Type #{@message_type}, Count #{@poll_count}" | |
| end | |
| private | |
| def determine_firmware | |
| ver = /<firmware_version>([^>]*)<\/firmware_version>/.match(@xml) || /<version_firmware>([^>]*)<\/version_firmware>/.match(@xml) | |
| @firmware_version = Gem::Version.create(ver[1]) | |
| end | |
| def extract_message(raw_xml) | |
| unless raw_xml | |
| @log.error{"Starlink #{@sl.mac_address} posted no data, no use going on..."} | |
| return nil | |
| else | |
| doc = REXML::Document.new(raw_xml) | |
| xml = doc.root | |
| end | |
| end | |
| def load_from_xml(xml) | |
| dx = DatacomXML.load_from_xml(xml) | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment