def __init__(self, updatecallback, address=0x9d, name="/dev/serial", rate=9600, config=None): super(ModbusBase, self).__init__() self.Address = address self.Rate = rate self.PortName = name self.config = config self.InitComplete = False self.IsStopping = False self.UpdateRegisterList = updatecallback self.RxPacketCount = 0 self.TxPacketCount = 0 self.ComTimoutError = 0 self.TotalElapsedPacketeTime = 0 self.SlaveException = 0 self.CrcError = 0 self.ComValidationError = 0 self.UnexpectedData = 0 self.SlowCPUOptimization = False self.UseTCP = False self.AdditionalModbusTimeout = 0 self.ResponseAddress = None # Used if recieve packes have a different address than sent packets if self.config != None: self.loglocation = self.config.ReadValue('loglocation', default='/var/log/') self.SlowCPUOptimization = self.config.ReadValue( 'optimizeforslowercpu', return_type=bool, default=False) self.UseTCP = self.config.ReadValue('use_serial_tcp', return_type=bool, default=False) self.Address = int(self.config.ReadValue('address', default='9d'), 16) # modbus address self.AdditionalModbusTimeout = self.config.ReadValue( 'additional_modbus_timeout', return_type=float, default=0.0) ResponseAddressStr = self.config.ReadValue('response_address', default=None) if ResponseAddressStr != None: try: self.ResponseAddress = int(ResponseAddressStr, 16) # response modbus address except: self.ResponseAddress = None else: self.loglocation = default = './' self.CommAccessLock = threading.RLock( ) # lock to synchronize access to the serial port comms self.ModbusStartTime = datetime.datetime.now() # used for com metrics # log errors in this module to a file self.log = SetupLogger("mymodbus", self.loglocation + "mymodbus.log") self.console = SetupLogger("mymodbus_console", log_file="", stream=True)
def __init__(self, host="127.0.0.1", port=9082, log=None, callback=None, polltime=None, blacklist=None, flush_interval=float('inf'), use_numeric=False, debug=False): super(MyGenPush, self).__init__() self.Callback = callback self.UseNumeric = use_numeric self.Debug = debug if polltime == None: self.PollTime = 3 else: self.PollTime = float(polltime) if log != None: self.log = log else: # log errors in this module to a file self.log = SetupLogger("client", "/var/log/mygenpush.log") self.console = SetupLogger("mygenpush_console", log_file="", stream=True) self.AccessLock = threading.Lock() self.BlackList = blacklist self.LastValues = {} self.FlushInterval = flush_interval self.LastChange = {} try: startcount = 0 while startcount <= 10: try: self.Generator = ClientInterface(host=host, log=log) break except Exception as e1: startcount += 1 if startcount >= 10: self.console.info("genmon not loaded.") self.LogError("Unable to connect to genmon.") sys.exit(1) time.sleep(1) continue # start thread to accept incoming sockets for nagios heartbeat self.Threads["PollingThread"] = MyThread(self.MainPollingThread, Name="PollingThread") except Exception as e1: self.LogErrorLine("Error in mygenpush init: " + str(e1))
def __init__(self, log=None, host=ProgramDefaults.LocalHost, port=8899, config=None): super(SerialTCPDevice, self).__init__() self.DeviceName = "serialTCP" self.config = config self.Buffer = [] self.BufferLock = threading.Lock() self.DiscardedBytes = 0 self.Restarts = 0 self.SerialStartTime = datetime.datetime.now() # used for com metrics self.rxdatasize = 2000 self.SocketTimeout = 1 self.host = host self.port = port if self.config != None: self.loglocation = self.config.ReadValue('loglocation', default='/var/log/') self.host = self.config.ReadValue('serial_tcp_address', return_type=str, default=None) self.port = self.config.ReadValue('serial_tcp_port', return_type=int, default=None, NoLog=True) else: self.loglocation = default = './' # log errors in this module to a file self.console = SetupLogger("myserialtcp_console", log_file="", stream=True) if log == None: self.log = SetupLogger( "myserialtcp", os.path.join(self.loglocation, "myserialtcp.log")) else: self.log = log if self.host == None or self.port == None: self.LogError("Invalid setting for host or port in myserialtcp") #Starting tcp connection self.Connect() self.IsOpen = True self.StartReadThread()
def __init__(self, host=ProgramDefaults.LocalHost, port=ProgramDefaults.ServerPort, log = None, loglocation = ProgramDefaults.LogPath): super(ClientInterface, self).__init__() if log != None: self.log = log else: # log errors in this module to a file self.log = SetupLogger("client", loglocation+ "myclient.log") self.console = SetupLogger("client_console", log_file = "", stream = True) self.AccessLock = threading.RLock() self.EndOfMessage = "EndOfMessage" self.rxdatasize = 2000 self.host = host self.port = port self.Connect()
def __init__(self, host="127.0.0.1", port=9082, log=None): super(ClientInterface, self).__init__() if log != None: self.log = log else: # log errors in this module to a file self.log = SetupLogger("client", "/var/log/myclient.log") self.console = SetupLogger("client_console", log_file="", stream=True) self.AccessLock = threading.RLock() self.EndOfMessage = "EndOfMessage" self.rxdatasize = 2000 self.host = host self.port = port self.Connect()
def __init__(self, host=ProgramDefaults.LocalHost, port=ProgramDefaults.ServerPort, log=None, callback=None, polltime=None, blacklist=None, flush_interval=float('inf'), use_numeric=False, debug=False, loglocation=ProgramDefaults.LogPath, console=None): super(MyGenPush, self).__init__() self.Callback = callback self.UseNumeric = use_numeric self.debug = debug self.Exiting = False if polltime == None: self.PollTime = 3 else: self.PollTime = float(polltime) if log != None: self.log = log else: # log errors in this module to a file self.log = SetupLogger("client", os.path.join(loglocation, "mygenpush.log")) self.console = console self.AccessLock = threading.Lock() self.BlackList = blacklist self.LastValues = {} self.FlushInterval = flush_interval self.LastChange = {} try: self.Generator = ClientInterface(host=host, port=port, log=log) self.GetGeneratorStartInfo() # start thread to accept incoming sockets for nagios heartbeat self.Threads["MainPollingThread"] = MyThread( self.MainPollingThread, Name="MainPollingThread", start=False) self.Threads["MainPollingThread"].Start() except Exception as e1: self.LogErrorLine("Error in mygenpush init: " + str(e1))
def __init__(self, name = '/dev/serial0', rate=9600, log = None, Parity = None, OnePointFiveStopBits = None, sevendatabits = False, RtsCts = False, config = None, loglocation = ProgramDefaults.LogPath): super(SerialDevice, self).__init__() self.config = config self.DeviceName = name self.BaudRate = rate self.Buffer = [] self.BufferLock = threading.Lock() self.DiscardedBytes = 0 self.Restarts = 0 self.SerialStartTime = datetime.datetime.now() # used for com metrics self.loglocation = loglocation # This supports getting this info from genmon.conf if self.config != None: self.loglocation = self.config.ReadValue('loglocation', default = '/var/log/') self.DeviceName = self.config.ReadValue('port', default = '/dev/serial0') # log errors in this module to a file if log == None: self.log = SetupLogger("myserial", os.path.join(self.loglocation, "myserial.log")) else: self.log = log self.console = SetupLogger("myserial_console", log_file = "", stream = True) try: #Starting serial connection if self.VersionTuple(serial.__version__) < self.VersionTuple("3.3"): self.SerialDevice = serial.Serial() else: self.SerialDevice = serial.Serial(exclusive = True) self.SerialDevice = serial.Serial() self.SerialDevice.port = self.DeviceName self.SerialDevice.baudrate = rate #number of bits per bytes if sevendatabits == True: self.SerialDevice.bytesize = serial.SEVENBITS else: self.SerialDevice.bytesize = serial.EIGHTBITS if Parity == None: self.SerialDevice.parity = serial.PARITY_NONE #set parity check: no parity elif Parity == 1: self.SerialDevice.parity = serial.PARITY_ODD #set parity check: use odd parity else: self.SerialDevice.parity = serial.PARITY_EVEN #set parity check: use even parity if OnePointFiveStopBits == None: self.SerialDevice.stopbits = serial.STOPBITS_ONE #number of stop bits elif OnePointFiveStopBits: self.SerialDevice.stopbits = serial.STOPBITS_ONE_POINT_FIVE #number of stop bits else: self.SerialDevice.stopbits = serial.STOPBITS_ONE #number of stop bits self.SerialDevice.timeout = 0.05 # small timeout so we can check if the thread should exit self.SerialDevice.xonxoff = False #disable software flow control self.SerialDevice.rtscts = RtsCts #disable hardware (RTS/CTS) flow control self.SerialDevice.dsrdtr = False #disable hardware (DSR/DTR) flow control self.SerialDevice.writeTimeout = None #timeout for write, return when packet sent self.IsOpen = False #Check if port failed to open if (self.SerialDevice.isOpen() == False): try: self.SerialDevice.open() except Exception as e: self.FatalError( "Error on open serial port %s: " % self.DeviceName + str(e)) return None else: self.FatalError( "Serial port already open: %s" % self.DeviceName) return None self.IsOpen = True self.Flush() self.StartReadThread() except Exception as e1: self.LogErrorLine("Error in init: " + str(e1)) self.FatalError("Error on serial port init!")
def __init__(self, host="127.0.0.1", port=9082, log=None, onready=None, onexercise=None, onrun=None, onrunmanual=None, onalarm=None, onservice=None, onoff=None, onmanual=None, onutilitychange=None): super(GenNotify, self).__init__() self.AccessLock = threading.Lock() self.Threads = {} self.LastEvent = None self.LastOutageStatus = None self.Events = {} # Dict for handling events if log != None: self.log = log else: # log errors in this module to a file self.log = SetupLogger("client", "/var/log/myclient.log") self.console = SetupLogger("notify_console", log_file="", stream=True) try: # init event callbacks if onready != None: self.Events["READY"] = onready if onexercise != None: self.Events["EXERCISING"] = onexercise if onrun != None: self.Events["RUNNING"] = onrun if onrunmanual != None: self.Events["RUNNING-MANUAL"] = onrunmanual if onalarm != None: self.Events["ALARM"] = onalarm if onservice != None: self.Events["SERVICEDUE"] = onservice if onoff != None: self.Events["OFF"] = onoff if onmanual != None: self.Events["MANUAL"] = onmanual if onutilitychange != None: self.Events["OUTAGE"] = onutilitychange startcount = 0 while startcount <= 10: try: self.Generator = ClientInterface(host=host, log=log) break except Exception as e1: startcount += 1 if startcount >= 10: self.console.info("genmon not loaded.") sys.exit(1) time.sleep(1) continue # start thread to accept incoming sockets for nagios heartbeat self.Threads["PollingThread"] = MyThread(self.MainPollingThread, Name="PollingThread") except Exception as e1: self.LogErrorLine("Error in mynotify init: " + str(e1))
def __init__(self, start=False, stop=False, hardstop=False, loglocation="/var/log/", log=None, localinit=False, ConfigFilePath=None): self.Start = start self.Stop = stop self.HardStop = hardstop if ConfigFilePath == None: self.ConfigFilePath = "/etc/" else: self.ConfigFilePath = ConfigFilePath self.ConfigFileName = "genloader.conf" # log errors in this module to a file if localinit == True: self.configfile = self.ConfigFileName else: self.configfile = self.ConfigFilePath + self.ConfigFileName self.ModulePath = os.path.dirname(os.path.realpath(__file__)) + "/" self.ConfPath = os.path.dirname(os.path.realpath(__file__)) + "/conf/" # log errors in this module to a file if log == None: self.log = SetupLogger("genloader", loglocation + "genloader.log") else: self.log = log self.console = SetupLogger("genloader_console", log_file="", stream=True) try: if self.Start: if not self.CheckSystem(): self.LogInfo("Error check system readiness. Exiting") sys.exit(2) self.CachedConfig = {} # check to see if genloader.conf is present, if not copy it from genmon directory if not os.path.isfile(self.configfile): self.LogInfo("Warning: unable to find config file: " + self.configfile + " Copying file to /etc/ directory.") if os.path.isfile(self.ConfPath + self.ConfigFileName): copyfile(self.ConfPath + self.ConfigFileName, self.configfile) else: self.LogInfo("Unable to find config file.") sys.exit(2) self.config = MyConfig(filename=self.configfile, section="genmon", log=self.log) if not self.GetConfig(): self.LogInfo("Error reading config file. Exiting") sys.exit(2) if not self.ValidateConfig(): self.LogInfo("Error validating config. Exiting") sys.exit(2) self.LoadOrder = self.GetLoadOrder() if self.Stop: self.StopModules() time.sleep(2) if self.Start: self.StartModules() except Exception as e1: self.LogErrorLine("Error in init: " + str(e1))
HardStop = False for opt, arg in opts: if opt == '-h': print(HelpStr) sys.exit() elif opt in ("-s", "--start"): StartModules = True elif opt in ("-r", "--restart"): StopModules = True StartModules = True elif opt in ("-x", "--exit"): StopModules = True elif opt in ("-z", "--hardstop"): HardStop = True StopModules = True elif opt in ("-c", "--configpath"): ConfigFilePath = arg ConfigFilePath = ConfigFilePath.strip() if not StartModules and not StopModules: print("\nNo option selected.\n") print(HelpStr) sys.exit(2) tmplog = SetupLogger("genloader", "/var/log/" + "genloader.log") if (Loader.OneTimeMaint(ConfigFilePath, tmplog)): time.sleep(1.5) port, loglocation = MySupport.GetGenmonInitInfo(ConfigFilePath, log = None) LoaderObject = Loader(start = StartModules, stop = StopModules, hardstop = HardStop, ConfigFilePath = ConfigFilePath, loglocation = loglocation)
print ('Port is : %s' % address) elif opt in ("-f", "--filename"): fileName = arg print ('Output file is : %s' % fileName) except Exception as e1: print ("Error : " + str(e1)) sys.exit(2) if not len(address): print ("Address is : localhost") address = ProgramDefaults.LocalHost if not len(fileName): print (HelpStr) sys.exit(2) try: log = SetupLogger("client", "kwlog2csv.log") MyClientInterface = myclient.ClientInterface(host = address, port = port, log = log) data = MyClientInterface.ProcessMonitorCommand("generator: power_log_json") data = json.loads(data) for Time, Value in reversed(data): LogToFile(fileName, Time, Value) except Exception as e1: print ("Error (1): " + str(e1))
class ClientInterface(MyCommon): def __init__(self, host=ProgramDefaults.LocalHost, port=ProgramDefaults.ServerPort, log=None, loglocation=ProgramDefaults.LogPath): super(ClientInterface, self).__init__() if log != None: self.log = log else: # log errors in this module to a file self.log = SetupLogger("client", os.path.join(loglocation, "myclient.log")) self.console = SetupLogger("client_console", log_file="", stream=True) self.AccessLock = threading.RLock() self.EndOfMessage = "EndOfMessage" self.rxdatasize = 2000 self.host = host self.port = port self.max_reties = 10 self.Connect() #---------- ClientInterface::Connect -------------------------------------- def Connect(self): retries = 0 while True: try: #create an INET, STREAMing socket self.Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #now connect to the server on our port self.Socket.connect((self.host, self.port)) sRetData, data = self.Receive( noeom=True) # Get initial status before commands are sent self.console.info(data) return except Exception as e1: retries += 1 if retries >= self.max_reties: self.LogErrorLine("Error: Connect : " + str(e1)) self.console.error("Genmon not loaded.") sys.exit(1) else: time.sleep(1) continue #---------- ClientInterface::SendCommand ---------------------------------- def SendCommand(self, cmd): try: self.Socket.sendall(cmd.encode("utf-8")) except Exception as e1: self.LogErrorLine("Error: TX: " + str(e1)) self.Close() self.Connect() #---------- ClientInterface::Receive -------------------------------------- def Receive(self, noeom=False): with self.AccessLock: RetStatus = True try: bytedata = self.Socket.recv(self.rxdatasize) data = bytedata.decode("utf-8") if len(data): if not self.CheckForStarupMessage(data) or not noeom: while not self.EndOfMessage in data: morebytes = self.Socket.recv(self.rxdatasize) more = morebytes.decode("utf-8") if len(more): if self.CheckForStarupMessage(more): data = "" RetStatus = False break data += more if data.endswith(self.EndOfMessage): data = data[:-len(self.EndOfMessage)] RetStatus = True else: self.Connect() return False, data except Exception as e1: self.LogErrorLine("Error: RX:" + str(e1)) self.Close() self.Connect() RetStatus = False data = "Retry" return RetStatus, data #---------- ClientInterface::CheckForStarupMessage ------------------------ def CheckForStarupMessage(self, data): # check for initial status response from monitor if data.startswith("OK") or data.startswith( "CRITICAL:") or data.startswith("WARNING:"): return True else: return False #---------- ClientInterface::Close ---------------------------------------- def Close(self): self.Socket.close() #---------- ClientInterface::ProcessMonitorCommand ------------------------ def ProcessMonitorCommand(self, cmd): data = "" try: with self.AccessLock: RetStatus = False while RetStatus == False: self.SendCommand(cmd) RetStatus, data = self.Receive() except Exception as e1: self.LogErrorLine("Error in ProcessMonitorCommand:" + str(e1)) return data
def __init__(self, ConfigFilePath = ProgramDefaults.ConfPath): super(Monitor, self).__init__() self.ProgramName = "Generator Monitor" self.Version = "Unknown" self.log = None self.IsStopping = False self.ProgramComplete = False if ConfigFilePath == None or ConfigFilePath == "": self.ConfigFilePath = ProgramDefaults.ConfPath else: self.ConfigFilePath = ConfigFilePath self.ConnectionList = [] # list of incoming connections for heartbeat # defautl values self.SiteName = "Home" self.ServerSocket = None self.ServerSocketPort = ProgramDefaults.ServerPort # server socket for nagios heartbeat and command/status self.IncomingEmailFolder = "Generator" self.ProcessedEmailFolder = "Generator/Processed" self.FeedbackLogFile = self.ConfigFilePath + "feedback.json" self.LogLocation = ProgramDefaults.LogPath self.LastLogFileSize = 0 self.NumberOfLogSizeErrors = 0 # set defaults for optional parameters self.NewInstall = False # True if newly installed or newly upgraded version self.FeedbackEnabled = False # True if sending autoated feedback on missing information self.FeedbackMessages = {} self.OneTimeMessages = {} self.MailInit = False # set to true once mail is init self.CommunicationsActive = False # Flag to let the heartbeat thread know we are communicating self.Controller = None self.ControllerSelected = None self.bDisablePlatformStats = False self.ReadOnlyEmailCommands = False self.SlowCPUOptimization = False # weather parameters self.WeatherAPIKey = None self.WeatherLocation = None self.UseMetric = False self.WeatherMinimum = True self.DisableWeather = False self.MyWeather = None # Time Sync Related Data self.bSyncTime = False # Sync gen to system time self.bSyncDST = False # sync time at DST change self.bDST = False # Daylight Savings Time active if True # simulation self.Simulation = False self.SimulationFile = None self.console = SetupLogger("genmon_console", log_file = "", stream = True) if os.geteuid() != 0: self.LogConsole("You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'.") sys.exit(1) if not os.path.isfile(self.ConfigFilePath + 'genmon.conf'): self.LogConsole("Missing config file : " + self.ConfigFilePath + 'genmon.conf') sys.exit(1) if not os.path.isfile(self.ConfigFilePath + 'mymail.conf'): self.LogConsole("Missing config file : " + self.ConfigFilePath + 'mymail.conf') sys.exit(1) self.config = MyConfig(filename = self.ConfigFilePath + 'genmon.conf', section = "GenMon", log = self.console) # read config file if not self.GetConfig(): self.LogConsole("Failure in Monitor GetConfig") sys.exit(1) # log errors in this module to a file self.log = SetupLogger("genmon", self.LogLocation + "genmon.log") self.config.log = self.log if self.IsLoaded(): self.LogConsole("ERROR: genmon.py is already loaded.") self.LogError("ERROR: genmon.py is already loaded.") sys.exit(1) if self.NewInstall: self.LogError("New version detected: Old = %s, New = %s" % (self.Version, GENMON_VERSION)) self.Version = GENMON_VERSION self.ProgramStartTime = datetime.datetime.now() # used for com metrics self.LastSofwareUpdateCheck = datetime.datetime.now() atexit.register(self.Close) signal.signal(signal.SIGTERM, self.Close) signal.signal(signal.SIGINT, self.Close) # start thread to accept incoming sockets for nagios heartbeat and command / status clients self.Threads["InterfaceServerThread"] = MyThread(self.InterfaceServerThread, Name = "InterfaceServerThread") # init mail, start processing incoming email self.mail = MyMail(monitor=True, incoming_folder = self.IncomingEmailFolder, processed_folder =self.ProcessedEmailFolder,incoming_callback = self.ProcessCommand, loglocation = self.LogLocation, ConfigFilePath = ConfigFilePath) self.Threads = self.MergeDicts(self.Threads, self.mail.Threads) self.MailInit = True self.FeedbackPipe = MyPipe("Feedback", self.FeedbackReceiver, log = self.log, ConfigFilePath = self.ConfigFilePath) self.Threads = self.MergeDicts(self.Threads, self.FeedbackPipe.Threads) self.MessagePipe = MyPipe("Message", self.MessageReceiver, log = self.log, nullpipe = self.mail.DisableSNMP, ConfigFilePath = self.ConfigFilePath) self.Threads = self.MergeDicts(self.Threads, self.MessagePipe.Threads) try: #Starting device connection if self.Simulation: self.LogError("Simulation Running") if not self.ControllerSelected == None and len(self.ControllerSelected): self.LogError("Selected Controller: " + str(self.ControllerSelected)) else: self.ControllerSelected = "generac_evo_nexus" if self.ControllerSelected.lower() == "h_100" : self.Controller = HPanel(self.log, newinstall = self.NewInstall, simulation = self.Simulation, simulationfile = self.SimulationFile, message = self.MessagePipe, feedback = self.FeedbackPipe, config = self.config) else: self.Controller = Evolution(self.log, self.NewInstall, simulation = self.Simulation, simulationfile = self.SimulationFile, message = self.MessagePipe, feedback = self.FeedbackPipe, config = self.config) self.Threads = self.MergeDicts(self.Threads, self.Controller.Threads) except Exception as e1: self.LogErrorLine("Error opening controller device: " + str(e1)) sys.exit(1) self.StartThreads() self.ProcessFeedbackInfo() # send mail to tell we are starting self.MessagePipe.SendMessage("Generator Monitor Starting at " + self.SiteName, "Generator Monitor Starting at " + self.SiteName , msgtype = "info") self.LogError("GenMon Loaded for site: " + self.SiteName)
from_ = from_number, body = Message) console.info(message.sid) except Exception as e1: log.error("Error: " + str(e1)) console.error("Error: " + str(e1)) #------------------- Command-line interface for gengpio ------------------------ if __name__=='__main__': address = ProgramDefaults.LocalHost # Set the signal handler signal.signal(signal.SIGINT, signal_handler) console = SetupLogger("sms_console", log_file = "", stream = True) HelpStr = '\nsudo python gensyslog.py -a <IP Address or localhost> -c <path to genmon config file>\n' if os.geteuid() != 0: console.error("You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting.") sys.exit(2) try: ConfigFilePath = ProgramDefaults.ConfPath opts, args = getopt.getopt(sys.argv[1:],"hc:a:",["help","configpath=","address="]) except getopt.GetoptError: console.error("Invalid command line argument.") sys.exit(2) for opt, arg in opts: if opt == '-h': console.error(HelpStr)
def __init__(self, log=None, loglocation=ProgramDefaults.LogPath, ConfigFilePath=MyCommon.DefaultConfPath, host=ProgramDefaults.LocalHost, port=ProgramDefaults.ServerPort): super(GenTankData, self).__init__() self.LogFileName = loglocation + "gentankutil.log" self.AccessLock = threading.Lock() # log errors in this module to a file self.log = SetupLogger("gentankutil", self.LogFileName) self.console = SetupLogger("gentankutil_console", log_file="", stream=True) self.MonitorAddress = host self.PollTime = 2 self.TankID = "" self.debug = False configfile = ConfigFilePath + 'gentankutil.conf' try: if not os.path.isfile(configfile): self.LogConsole("Missing config file : " + configfile) self.LogError("Missing config file : " + configfile) sys.exit(1) self.config = MyConfig(filename=configfile, section='gentankutil', log=self.log) self.PollTime = self.config.ReadValue('poll_frequency', return_type=float, default=60) self.debug = self.config.ReadValue('debug', return_type=bool, default=False) self.username = self.config.ReadValue('username', default="") self.password = self.config.ReadValue('password', default="") self.tank_name = self.config.ReadValue('tank_name', default="") if self.MonitorAddress == None or not len(self.MonitorAddress): self.MonitorAddress = ProgramDefaults.LocalHost except Exception as e1: self.LogErrorLine("Error reading " + configfile + ": " + str(e1)) self.LogConsole("Error reading " + configfile + ": " + str(e1)) sys.exit(1) if self.username == "" or self.username == None or self.password == "" or self.password == None: self.LogError("Invalid user name or password, exiting") sys.exit(1) try: try: startcount = 0 while startcount <= 10: try: self.Generator = ClientInterface( host=self.MonitorAddress, port=port, log=self.log) break except Exception as e1: startcount += 1 if startcount >= 10: self.console.info("genmon not loaded.") self.LogError("Unable to connect to genmon.") sys.exit(1) time.sleep(1) continue except Exception as e1: self.LogErrorLine("Error in GenTankData init: " + str(e1)) #if not self.CheckGeneratorRequirement(): # self.LogError("Requirements not met. Exiting.") # sys.exit(1) self.tank = tankutility(self.username, self.password, self.log, debug=self.debug) # start thread monitor time for exercise self.Threads["TankCheckThread"] = MyThread(self.TankCheckThread, Name="TankCheckThread", start=False) self.Threads["TankCheckThread"].Start() atexit.register(self.Close) signal.signal(signal.SIGTERM, self.Close) signal.signal(signal.SIGINT, self.Close) except Exception as e1: self.LogErrorLine("Error in GenTankData init: " + str(e1)) self.console.error("Error in GenTankData init: " + str(e1)) sys.exit(1)
#------------------- StartTransferCallBack ------------------------------------- def StartTransferCallBack(): try: MyClientInterface.ProcessMonitorCommand( "generator: setremote=starttransfer") except Exception as e1: log.error("Error: " + str(e1)) #------------------- Command-line interface for gengpioin ---------------------- if __name__ == '__main__': # usage program.py [server_address] address = '127.0.0.1' if len(sys.argv) < 2 else sys.argv[1] try: console = SetupLogger("gengpioin_console", log_file="", stream=True) log = SetupLogger("client", "/var/log/gengpioin.log") # Set the signal handler signal.signal(signal.SIGINT, signal_handler) MyClientInterface = ClientInterface(host=address, log=log) #setup GPIO using Board numbering GPIO.setmode(GPIO.BOARD) console.info(GPIO.RPI_INFO) GPIO.setwarnings(True) GPIO.setup( INPUT_STOP, GPIO.IN,
'Request to slack returned an error %s, the response is:\n%s' % (response.status_code, response.text) ) except Exception as e1: log.error("Error in SendNotice: " + str(e1)) console.error("Error in SendNotice: " + str(e1)) #------------------- Command-line interface for gengpio ------------------------ if __name__=='__main__': address=ProgramDefaults.LocalHost # Set the signal handler signal.signal(signal.SIGINT, signal_handler) console = SetupLogger("slack_console", log_file = "", stream = True) HelpStr = '\nsudo python genslack.py -a <IP Address or localhost> -c <path to genmon config file>\n' if os.geteuid() != 0: console.error("You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting.") sys.exit(2) try: ConfigFilePath = ProgramDefaults.ConfPath opts, args = getopt.getopt(sys.argv[1:],"hc:a:",["configpath=","address="]) except getopt.GetoptError: console.error("Invalid command line argument.") sys.exit(2) for opt, arg in opts: if opt == '-h': console.error(HelpStr)
#------------ MyMQTT::on_message-------------------------------------------- # The callback for when a PUBLISH message is received from the server. def on_message(self, client, userdata, msg): if self.Debug: self.console.info("Confirmed: " + msg.topic + ": " + str(msg.payload)) # ---------- MyMQTT::Close-------------------------------------------------- def Close(self): self.Push.Close() #------------------------------------------------------------------------------- if __name__ == "__main__": address=ProgramDefaults.LocalHost console = SetupLogger("genmqtt_console_", log_file = "", stream = True) HelpStr = '\nsudo python genmqtt.py -a <IP Address or localhost> -c <path to genmon config file>\n' if os.geteuid() != 0: console.error("\nYou need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting.\n") sys.exit(2) try: ConfigFilePath = ProgramDefaults.ConfPath opts, args = getopt.getopt(sys.argv[1:],"hc:a:",["help","configpath=","address="]) except getopt.GetoptError: console.error("Invalid command line argument.") sys.exit(2) for opt, arg in opts: if opt == '-h': console.error(HelpStr)
#------------------- Command-line interface for gengpio ------------------------ if __name__ == '__main__': # usage program.py [server_address] address = '127.0.0.1' if len(sys.argv) < 2 else sys.argv[1] # Set the signal handler signal.signal(signal.SIGINT, signal_handler) if os.geteuid() != 0: print( "You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting." ) sys.exit(2) log = SetupLogger("client", "/var/log/gensyslog.log") console = SetupLogger("gensyslog_console", log_file="", stream=True) try: GenNotify = GenNotify(host=address, onready=OnReady, onexercise=OnExercise, onrun=OnRun, onrunmanual=OnRunManual, onalarm=OnAlarm, onservice=OnService, onoff=OnOff, onmanual=OnManual, onutilitychange=OnUtilityChange, log=log)
class MyMQTT(MyCommon): #------------ MyMQTT::init-------------------------------------------------- def __init__(self, log = None, loglocation = ProgramDefaults.LogPath, host = ProgramDefaults.LocalHost, port = ProgramDefaults.ServerPort, configfilepath = ProgramDefaults.ConfPath): super(MyMQTT, self).__init__() self.LogFileName = loglocation + "genmqtt.log" if log != None: self.log = log else: # log errors in this module to a file self.log = SetupLogger("client", self.LogFileName) # cleanup # test self.console = SetupLogger("mymqtt_console", log_file = "", stream = True) self.Username = None self.Password = None self.Topic = None self.MQTTAddress = None self.MonitorAddress = host self.MQTTPort = 1883 self.Topic = "generator" self.TopicRoot = None self.BlackList = None self.UseNumeric = False self.PollTime = 2 self.FlushInterval = float('inf') # default to inifite flush interval (e.g., never) self.Debug = False try: config = MyConfig(filename = configfilepath + 'genmqtt.conf', section = 'genmqtt', log = log) self.Username = config.ReadValue('username') self.Password = config.ReadValue('password') self.MQTTAddress = config.ReadValue('mqtt_address') if self.MQTTAddress == None or not len(self.MQTTAddress): log.error("Error: invalid MQTT server address") console.error("Error: invalid MQTT server address") sys.exit(1) self.MonitorAddress = config.ReadValue('monitor_address', default = self.MonitorAddress) if self.MonitorAddress == None or not len(self.MonitorAddress): self.MonitorAddress = ProgramDefaults.LocalHost self.MQTTPort = config.ReadValue('mqtt_port', return_type = int, default = 1883) self.PollTime = config.ReadValue('poll_interval', return_type = float, default = 2.0) self.UseNumeric = config.ReadValue('numeric_json', return_type = bool, default = False) self.TopicRoot = config.ReadValue('root_topic') #http://www.steves-internet-guide.com/mosquitto-tls/ self.CertificateAuthorityPath = config.ReadValue('cert_authority_path', default = "") self.TLSVersion = config.ReadValue('tls_version', return_type = str, default = "1.0") self.CertReqs = config.ReadValue('cert_reqs', return_type = str, default = "Required") BlackList = config.ReadValue('blacklist') if BlackList != None: if len(BlackList): BList = BlackList.strip().split(",") if len(BList): self.BlackList = [] for Items in BList: self.BlackList.append(Items.strip()) self.Debug = config.ReadValue('debug', return_type = bool, default = False) if config.HasOption('flush_interval'): self.FlushInterval = config.ReadValue('flush_interval', return_type = float, default = float('inf')) if self.FlushInterval == 0: self.FlushInterval = float('inf') else: self.FlushInterval = float('inf') except Exception as e1: self.LogErrorLine("Error reading " + configfilepath + "genmqtt.conf: " + str(e1)) self.console.error("Error reading " + configfilepath + "genmqtt.conf: " + str(e1)) sys.exit(1) try: self.MQTTclient = mqtt.Client(client_id = "genmon") if self.Username != None and len(self.Username) and self.Password != None: self.MQTTclient.username_pw_set(self.Username, password=self.Password) self.MQTTclient.on_connect = self.on_connect self.MQTTclient.on_message = self.on_message if len(self.CertificateAuthorityPath): if os.path.isfile(self.CertificateAuthorityPath): cert_reqs = ssl.CERT_REQUIRED if self.CertReqs.lower() == "required": cert_reqs = ssl.CERT_REQUIRED elif self.CertReqs.lower() == "optional": cert_reqs = ssl.CERT_REQUIRED elif self.CertReqs.lower() == "none": cert_reqs = ssl.CERT_NONE else: self.LogError("Error: invalid cert required specified, defaulting to required: " + self.self.CertReq) use_tls = ssl.PROTOCOL_TLSv1 if self.TLSVersion == "1.0" or self.TLSVersion == "1": use_tls = ssl.PROTOCOL_TLSv1 elif self.TLSVersion == "1.1": use_tls = ssl.PROTOCOL_TLSv1_1 elif self.TLSVersion == "1.2": use_tls = ssl.PROTOCOL_TLSv1_2 else: self.LogError("Error: invalid TLS version specified, defaulting to 1.0: " + self.TLSVersion) self.MQTTclient.tls_set(ca_certs = self.CertificateAuthorityPath,cert_reqs = cert_reqs, tls_version = use_tls ) self.MQTTPort = 8883 # port for SSL else: self.LogError("Error: Unable to find CA cert file: " + self.CertificateAuthorityPath) self.MQTTclient.connect(self.MQTTAddress, self.MQTTPort, 60) self.Push = MyGenPush(host = self.MonitorAddress, log = self.log, callback = self.PublishCallback, polltime = self.PollTime , blacklist = self.BlackList, flush_interval = self.FlushInterval, use_numeric = self.UseNumeric, debug = self.Debug, port = port, loglocation = loglocation) atexit.register(self.Close) signal.signal(signal.SIGTERM, self.Close) signal.signal(signal.SIGINT, self.Close) self.MQTTclient.loop_start() except Exception as e1: self.LogErrorLine("Error in MyMQTT init: " + str(e1)) self.console.error("Error in MyMQTT init: " + str(e1)) sys.exit(1) #------------ MyMQTT::PublishCallback--------------------------------------- # Callback to publish data via MQTT def PublishCallback(self, name, value): try: if self.TopicRoot != None and len(self.TopicRoot): FullPath = self.TopicRoot + "/" + str(name) else: FullPath = str(name) if self.Debug: self.console.info("Publish: " + FullPath + ": " + str(value) + ": " + str(type(value))) self.MQTTclient.publish(FullPath, value) except Exception as e1: self.LogErrorLine("Error in MyMQTT:PublishCallback: " + str(e1)) #------------ MyMQTT::on_connect-------------------------------------------- # The callback for when the client receives a CONNACK response from the server. def on_connect(self, client, userdata, flags, rc): if rc != 0: self.LogError("Error connecting to MQTT server: return code: " + str(rc)) self.console.info("Connected with result code "+str(rc)) # Subscribing in on_connect() means that if we lose the connection and # reconnect then subscriptions will be renewed. self.MQTTclient.subscribe(self.Topic + "/#") #------------ MyMQTT::on_message-------------------------------------------- # The callback for when a PUBLISH message is received from the server. def on_message(self, client, userdata, msg): if self.Debug: self.console.info("Confirmed: " + msg.topic + ": " + str(msg.payload)) # ---------- MyMQTT::Close-------------------------------------------------- def Close(self): self.Push.Close()
#---------------------GetErrorLine---------------------------------------------- def GetErrorLine(): exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] lineno = exc_tb.tb_lineno return fname + ":" + str(lineno) #------------------- Command-line interface for gengpioin ---------------------- if __name__ == '__main__': address = ProgramDefaults.LocalHost try: console = SetupLogger("gengpioin_console", log_file="", stream=True) if os.geteuid() != 0: console.error( "You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting." ) sys.exit(2) HelpStr = '\nsudo python gengpioin.py -a <IP Address or localhost> -c <path to genmon config file>\n' try: ConfigFilePath = ProgramDefaults.ConfPath opts, args = getopt.getopt(sys.argv[1:], "hc:a:", ["help", "configpath=", "address="]) except getopt.GetoptError: console.error("Invalid command line argument.") sys.exit(2)
def __init__(self, log = None, loglocation = ProgramDefaults.LogPath, host = ProgramDefaults.LocalHost, port = ProgramDefaults.ServerPort, configfilepath = ProgramDefaults.ConfPath): super(MyMQTT, self).__init__() self.LogFileName = loglocation + "genmqtt.log" if log != None: self.log = log else: # log errors in this module to a file self.log = SetupLogger("client", self.LogFileName) # cleanup # test self.console = SetupLogger("mymqtt_console", log_file = "", stream = True) self.Username = None self.Password = None self.Topic = None self.MQTTAddress = None self.MonitorAddress = host self.MQTTPort = 1883 self.Topic = "generator" self.TopicRoot = None self.BlackList = None self.UseNumeric = False self.PollTime = 2 self.FlushInterval = float('inf') # default to inifite flush interval (e.g., never) self.Debug = False try: config = MyConfig(filename = configfilepath + 'genmqtt.conf', section = 'genmqtt', log = log) self.Username = config.ReadValue('username') self.Password = config.ReadValue('password') self.MQTTAddress = config.ReadValue('mqtt_address') if self.MQTTAddress == None or not len(self.MQTTAddress): log.error("Error: invalid MQTT server address") console.error("Error: invalid MQTT server address") sys.exit(1) self.MonitorAddress = config.ReadValue('monitor_address', default = self.MonitorAddress) if self.MonitorAddress == None or not len(self.MonitorAddress): self.MonitorAddress = ProgramDefaults.LocalHost self.MQTTPort = config.ReadValue('mqtt_port', return_type = int, default = 1883) self.PollTime = config.ReadValue('poll_interval', return_type = float, default = 2.0) self.UseNumeric = config.ReadValue('numeric_json', return_type = bool, default = False) self.TopicRoot = config.ReadValue('root_topic') #http://www.steves-internet-guide.com/mosquitto-tls/ self.CertificateAuthorityPath = config.ReadValue('cert_authority_path', default = "") self.TLSVersion = config.ReadValue('tls_version', return_type = str, default = "1.0") self.CertReqs = config.ReadValue('cert_reqs', return_type = str, default = "Required") BlackList = config.ReadValue('blacklist') if BlackList != None: if len(BlackList): BList = BlackList.strip().split(",") if len(BList): self.BlackList = [] for Items in BList: self.BlackList.append(Items.strip()) self.Debug = config.ReadValue('debug', return_type = bool, default = False) if config.HasOption('flush_interval'): self.FlushInterval = config.ReadValue('flush_interval', return_type = float, default = float('inf')) if self.FlushInterval == 0: self.FlushInterval = float('inf') else: self.FlushInterval = float('inf') except Exception as e1: self.LogErrorLine("Error reading " + configfilepath + "genmqtt.conf: " + str(e1)) self.console.error("Error reading " + configfilepath + "genmqtt.conf: " + str(e1)) sys.exit(1) try: self.MQTTclient = mqtt.Client(client_id = "genmon") if self.Username != None and len(self.Username) and self.Password != None: self.MQTTclient.username_pw_set(self.Username, password=self.Password) self.MQTTclient.on_connect = self.on_connect self.MQTTclient.on_message = self.on_message if len(self.CertificateAuthorityPath): if os.path.isfile(self.CertificateAuthorityPath): cert_reqs = ssl.CERT_REQUIRED if self.CertReqs.lower() == "required": cert_reqs = ssl.CERT_REQUIRED elif self.CertReqs.lower() == "optional": cert_reqs = ssl.CERT_REQUIRED elif self.CertReqs.lower() == "none": cert_reqs = ssl.CERT_NONE else: self.LogError("Error: invalid cert required specified, defaulting to required: " + self.self.CertReq) use_tls = ssl.PROTOCOL_TLSv1 if self.TLSVersion == "1.0" or self.TLSVersion == "1": use_tls = ssl.PROTOCOL_TLSv1 elif self.TLSVersion == "1.1": use_tls = ssl.PROTOCOL_TLSv1_1 elif self.TLSVersion == "1.2": use_tls = ssl.PROTOCOL_TLSv1_2 else: self.LogError("Error: invalid TLS version specified, defaulting to 1.0: " + self.TLSVersion) self.MQTTclient.tls_set(ca_certs = self.CertificateAuthorityPath,cert_reqs = cert_reqs, tls_version = use_tls ) self.MQTTPort = 8883 # port for SSL else: self.LogError("Error: Unable to find CA cert file: " + self.CertificateAuthorityPath) self.MQTTclient.connect(self.MQTTAddress, self.MQTTPort, 60) self.Push = MyGenPush(host = self.MonitorAddress, log = self.log, callback = self.PublishCallback, polltime = self.PollTime , blacklist = self.BlackList, flush_interval = self.FlushInterval, use_numeric = self.UseNumeric, debug = self.Debug, port = port, loglocation = loglocation) atexit.register(self.Close) signal.signal(signal.SIGTERM, self.Close) signal.signal(signal.SIGINT, self.Close) self.MQTTclient.loop_start() except Exception as e1: self.LogErrorLine("Error in MyMQTT init: " + str(e1)) self.console.error("Error in MyMQTT init: " + str(e1)) sys.exit(1)
def __init__(self, monitor=False, incoming_folder=None, processed_folder=None, incoming_callback=None, localinit=False, loglocation=ProgramDefaults.LogPath, ConfigFilePath="/etc/", log=None, start=True): self.Monitor = monitor # true if we receive IMAP email self.IncomingFolder = incoming_folder # folder to look for incoming email self.ProcessedFolder = processed_folder # folder to move mail to once processed self.IncomingCallback = incoming_callback # called back with mail subject as a parameter if ConfigFilePath == None or ConfigFilePath == "": self.ConfigFilePath = "/etc/" else: self.ConfigFilePath = ConfigFilePath self.Mailbox = 0 self.EmailSendQueue = [] # queue for email to send self.DisableEmail = False self.DisableIMAP = False self.DisableSNMP = False self.DisableSmtpAuth = False self.SSLEnabled = False self.TLSDisable = False self.UseBCC = False self.ExtendWait = 0 self.Threads = {} # Dict of mythread objects self.debug = False self.ModulePath = os.path.dirname( os.path.dirname(os.path.realpath(__file__))) # log errors in this module to a file if localinit == True: self.logfile = "mymail.log" self.configfile = "mymail.conf" else: self.logfile = os.path.join(loglocation, "mymail.log") self.configfile = os.path.join(self.ConfigFilePath, "mymail.conf") if log == None: self.log = SetupLogger("mymail", self.logfile) else: self.log = log # if mymail.conf is present attempt to copy it from the # main source directory if not os.path.isfile(self.configfile): if os.path.join(os.path.isfile(self.ModulePath, "mymail.conf")): copyfile(os.path.join(self.ModulePath, "mymail.conf"), self.configfile) else: self.LogError("Missing config file : " + self.configfile) sys.exit(1) self.config = MyConfig(filename=self.configfile, section="MyMail", log=self.log) self.GetConfig() if self.DisableEmail: self.DisableIMAP = True self.DisableSNMP = True self.Monitor = False if not len(self.SMTPServer): self.DisableSNMP = True if not len(self.IMAPServer): self.DisableIMAP = True self.Monitor = False atexit.register(self.Close) if not self.DisableEmail: if not self.DisableSMTP and self.SMTPServer != "": self.Threads["SendMailThread"] = MyThread( self.SendMailThread, Name="SendMailThread", start=start) else: self.LogError("SMTP disabled") if not self.DisableIMAP and self.Monitor and self.IMAPServer != "": # if True then we will have an IMAP monitor thread if incoming_callback and incoming_folder and processed_folder: self.Threads["EmailCommandThread"] = MyThread( self.EmailCommandThread, Name="EmailCommandThread", start=start) else: self.FatalError( "ERROR: incoming_callback, incoming_folder and processed_folder are required if receive IMAP is used" ) else: self.LogError("IMAP disabled")
class MyGenPush(MySupport): #------------ MyGenPush::init----------------------------------------------- def __init__(self, host=ProgramDefaults.LocalHost, port=ProgramDefaults.ServerPort, log = None, callback = None, polltime = None, blacklist = None, flush_interval = float('inf'), use_numeric = False, debug = False, loglocation = ProgramDefaults.LogPath): super(MyGenPush, self).__init__() self.Callback = callback self.UseNumeric = use_numeric self.Debug = debug if polltime == None: self.PollTime = 3 else: self.PollTime = float(polltime) if log != None: self.log = log else: # log errors in this module to a file self.log = SetupLogger("client", loglocation + "mygenpush.log") self.console = SetupLogger("mygenpush_console", log_file = "", stream = True) self.AccessLock = threading.Lock() self.BlackList = blacklist self.LastValues = {} self.FlushInterval = flush_interval self.LastChange = {} try: startcount = 0 while startcount <= 10: try: self.Generator = ClientInterface(host = host, port = port, log = log) break except Exception as e1: startcount += 1 if startcount >= 10: self.console.info("genmon not loaded.") self.LogError("Unable to connect to genmon.") sys.exit(1) time.sleep(1) continue # start thread to accept incoming sockets for nagios heartbeat self.Threads["PollingThread"] = MyThread(self.MainPollingThread, Name = "PollingThread") except Exception as e1: self.LogErrorLine("Error in mygenpush init: " + str(e1)) #---------- MyGenPush::SendCommand ---------------------------------------- def SendCommand(self, Command): if len(Command) == 0: return "Invalid Command" try: with self.AccessLock: data = self.Generator.ProcessMonitorCommand(Command) except Exception as e1: self.LogErrorLine("Error calling ProcessMonitorCommand: " + str(Command)) data = "" return data # ---------- MyGenPush::MainPollingThread----------------------------------- def MainPollingThread(self): while True: try: if not self.UseNumeric: statusdata = self.SendCommand("generator: status_json") else: statusdata = self.SendCommand("generator: status_num_json") outagedata = self.SendCommand("generator: outage_json") monitordata = self.SendCommand("generator: monitor_json") maintdata = self.SendCommand("generator: maint_json") try: GenmonDict = {} TempDict = {} TempDict = json.loads(statusdata) GenmonDict["Status"] = TempDict["Status"] TempDict = json.loads(maintdata) GenmonDict["Maintenance"] = TempDict["Maintenance"] TempDict = json.loads(outagedata) GenmonDict["Outage"] = TempDict["Outage"] TempDict = json.loads(monitordata) GenmonDict["Monitor"] = TempDict["Monitor"] self.CheckDictForChanges(GenmonDict, "generator") except Exception as e1: self.LogErrorLine("Unable to get status: " + str(e1)) if self.WaitForExit("PollingThread", float(self.PollTime)): return except Exception as e1: self.LogErrorLine("Error in mynotify:MainPollingThread: " + str(e1)) if self.WaitForExit("PollingThread", float(self.PollTime)): return #------------ MySupport::CheckDictForChanges ------------------------------- # This function is recursive, it will turn a nested dict into a flat dict keys # that have a directory structure with corrposonding values and determine if # anyting changed. If it has then call our callback function def CheckDictForChanges(self, node, PathPrefix): CurrentPath = PathPrefix if not isinstance(PathPrefix, str): return "" if isinstance(node, dict): for key, item in node.items(): if isinstance(item, dict): CurrentPath = PathPrefix + "/" + str(key) self.CheckDictForChanges(item, CurrentPath) elif isinstance(item, list): CurrentPath = PathPrefix + "/" + str(key) for listitem in item: if isinstance(listitem, dict): self.CheckDictForChanges(listitem, CurrentPath) elif isinstance(listitem, str) or isinstance(listitem, unicode): CurrentPath = PathPrefix + "/" + str(key) #todo list support pass else: self.LogError("Invalid type in CheckDictForChanges: %s %s (2)" % (key, str(type(listitem)))) else: CurrentPath = PathPrefix + "/" + str(key) self.CheckForChanges(CurrentPath, item) else: self.LogError("Invalid type in CheckDictForChanges %s " % str(type(node))) # ---------- MyGenPush::CheckForChanges------------------------------------- def CheckForChanges(self, Path, Value): try: if self.BlackList != None: for BlackItem in self.BlackList: if BlackItem.lower() in Path.lower(): return LastValue = self.LastValues.get(str(Path), None) LastChange = self.LastChange.get(str(Path), 0) if LastValue == None or LastValue != Value or (time.time() - LastChange) > self.FlushInterval: self.LastValues[str(Path)] = Value self.LastChange[str(Path)] = time.time() if self.Callback != None: self.Callback(str(Path), Value) except Exception as e1: self.LogErrorLine("Error in mygenpush:CheckForChanges: " + str(e1)) # ---------- MyGenPush::Close----------------------------------------------- def Close(self): self.KillThread("PollingThread") self.Generator.Close()
class GenNotify(MyCommon): def __init__(self, host="127.0.0.1", port=9082, log=None, onready=None, onexercise=None, onrun=None, onrunmanual=None, onalarm=None, onservice=None, onoff=None, onmanual=None, onutilitychange=None): super(GenNotify, self).__init__() self.AccessLock = threading.Lock() self.Threads = {} self.LastEvent = None self.LastOutageStatus = None self.Events = {} # Dict for handling events if log != None: self.log = log else: # log errors in this module to a file self.log = SetupLogger("client", "/var/log/myclient.log") self.console = SetupLogger("notify_console", log_file="", stream=True) try: # init event callbacks if onready != None: self.Events["READY"] = onready if onexercise != None: self.Events["EXERCISING"] = onexercise if onrun != None: self.Events["RUNNING"] = onrun if onrunmanual != None: self.Events["RUNNING-MANUAL"] = onrunmanual if onalarm != None: self.Events["ALARM"] = onalarm if onservice != None: self.Events["SERVICEDUE"] = onservice if onoff != None: self.Events["OFF"] = onoff if onmanual != None: self.Events["MANUAL"] = onmanual if onutilitychange != None: self.Events["OUTAGE"] = onutilitychange startcount = 0 while startcount <= 10: try: self.Generator = ClientInterface(host=host, log=log) break except Exception as e1: startcount += 1 if startcount >= 10: self.console.info("genmon not loaded.") sys.exit(1) time.sleep(1) continue # start thread to accept incoming sockets for nagios heartbeat self.Threads["PollingThread"] = MyThread(self.MainPollingThread, Name="PollingThread") except Exception as e1: self.LogErrorLine("Error in mynotify init: " + str(e1)) # ---------- GenNotify::MainPollingThread----------------------------------- def MainPollingThread(self): while True: try: data = self.SendCommand("generator: getbase") outagedata = self.SendCommand("generator: outage_json") try: OutageDict = collections.OrderedDict() OutageDict = json.loads(outagedata) OutageState = True if OutageDict["Outage"][ "System In Outage"].lower() == "yes" else False except Exception as e1: # The system does no support outage tracking (i.e. H-100) #self.LogErrorLine("Unable to get outage state: " + str(e1)) OutageState = None if OutageState != None: self.ProcessOutageState(OutageState) if self.LastEvent == data: time.sleep(3) continue if self.LastEvent != None: self.console.info("Last : <" + self.LastEvent + ">, New : <" + data + ">") self.CallEventHandler(False) # end last event self.LastEvent = data self.CallEventHandler(True) # begin new event time.sleep(3) except Exception as e1: self.LogErrorLine("Error in mynotify:MainPollingThread: " + str(e1)) time.sleep(3) #---------- GenNotify::CallEventHandler ----------------------------------- def CallEventHandler(self, Status): try: if self.LastEvent == None: return EventCallback = self.Events.get(self.LastEvent, None) # Event has ended if EventCallback != None: if callable(EventCallback): EventCallback(Status) else: self.LogError("Invalid Callback in CallEventHandler : " + str(EventCallback)) else: self.LogError("Invalid Callback in CallEventHandler : None") except Exception as e1: self.LogErrorLine("Error in CallEventHandler: " + str(e1)) #---------- GenNotify::ProcessOutageState --------------------------------- def ProcessOutageState(self, outagestate): try: if self.LastOutageStatus == outagestate: return self.LastOutageStatus = outagestate EventCallback = self.Events.get("OUTAGE", None) if EventCallback != None: if callable(EventCallback): EventCallback(self.LastOutageStatus) else: self.LogError("Invalid Callback in ProcessOutageState : " + str(EventCallback)) else: self.LogError("Invalid Callback in ProcessOutageState : None") except Exception as e1: self.LogErrorLine("Error in ProcessOutageState: " + str(e1)) #---------- GenNotify::SendCommand ---------------------------------------- def SendCommand(self, Command): if len(Command) == 0: return "Invalid Command" try: with self.AccessLock: data = self.Generator.ProcessMonitorCommand(Command) except Exception as e1: self.LogErrorLine("Error calling ProcessMonitorCommand: " + str(Command)) data = "" return data #---------- GenNotify::Close ---------------------------------------------- def Close(self): self.Generator.Close() return False
LogFile.write(excel_date(time) + "," + Event + "\n") LogFile.flush() #------------------- Command-line interface for genlog ------------------------- if __name__ == '__main__': address = ProgramDefaults.LocalHost fileName = "" HelpStr = '\npython genlog.py -a <IP Address or localhost> -f <outputfile> -c <config file path>\n' try: ConfigFilePath = ProgramDefaults.ConfPath console = SetupLogger("genlog_console", log_file="", stream=True) port, loglocation, multi_instance = MySupport.GetGenmonInitInfo( ConfigFilePath, log=console) if not MySupport.PermissionsOK(): console.error( "You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting." ) sys.exit(2) if MySupport.IsRunning(os.path.basename(__file__), multi_instance=multi_instance): console.error("The program %s is already loaded" % os.path.basename(__file__)) sys.exit(2)
#---------- Signal Handler ---------------------------------------------------- def signal_handler(signal, frame): GPIO.cleanup() MyClientInterface.Close() sys.exit(0) #------------------- Command-line interface for gengpio ------------------------ if __name__ == '__main__': # usage program.py [server_address] address = ProgramDefaults.LocalHost try: console = SetupLogger("gengpio_console", log_file="", stream=True) HelpStr = '\nsudo python gengpio.py -a <IP Address or localhost> -c <path to genmon config file>\n' try: ConfigFilePath = ProgramDefaults.ConfPath opts, args = getopt.getopt(sys.argv[1:], "hc:a:", ["help", "configpath=", "address="]) except getopt.GetoptError: console.error("Invalid command line argument.") sys.exit(2) for opt, arg in opts: if opt == '-h': console.error(HelpStr) sys.exit() elif opt in ("-a", "--address"): address = arg
def SetupAddOnProgram(prog_name): console = SetupLogger(prog_name + "_console", log_file="", stream=True) if not MySupport.PermissionsOK(): console.error( "\nYou need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting.\n" ) sys.exit(2) HelpStr = '\nsudo python ' + prog_name + '.py -a <IP Address or localhost> -c <path to ' + prog_name + ' config file>\n' ConfigFilePath = ProgramDefaults.ConfPath address = ProgramDefaults.LocalHost try: opts, args = getopt.getopt(sys.argv[1:], "hc:a:", ["help", "configpath=", "address="]) except getopt.GetoptError: console.error("Invalid command line argument.") sys.exit(2) for opt, arg in opts: if opt == '-h': console.error(HelpStr) sys.exit() elif opt in ("-a", "--address"): address = arg elif opt in ("-c", "--configpath"): ConfigFilePath = arg.strip() try: port, loglocation, multi_instance = MySupport.GetGenmonInitInfo( ConfigFilePath, log=console) log = SetupLogger("client_" + prog_name, os.path.join(loglocation, prog_name + ".log")) if not prog_name.lower().endswith(".py"): prog_name += ".py" attempts = 0 while True: if MySupport.IsRunning(prog_name=prog_name, log=log, multi_instance=multi_instance): if attempts >= 4: raise Exception("The program %s is already loaded" % prog_name) else: attempts += 1 time.sleep(1) else: break except Exception as e1: console.error("Error : " + str(e1)) log.error("Error : " + str(e1) + ": " + MySupport.GetErrorLine()) sys.exit(1) return console, ConfigFilePath, address, port, loglocation, log
#---------- Signal Handler ---------------------------------------------------- def signal_handler(signal, frame): GPIO.cleanup() MyClientInterface.Close() sys.exit(0) #------------------- Command-line interface for gengpio ------------------------ if __name__ == '__main__': # usage program.py [server_address] address = ProgramDefaults.LocalHost try: console = SetupLogger("gengpio_console", log_file="", stream=True) if os.geteuid() != 0: console.error( "You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting." ) sys.exit(2) HelpStr = '\nsudo python gengpio.py -a <IP Address or localhost> -c <path to genmon config file>\n' try: ConfigFilePath = ProgramDefaults.ConfPath opts, args = getopt.getopt(sys.argv[1:], "hc:a:", ["help", "configpath=", "address="]) except getopt.GetoptError: console.error("Invalid command line argument.") sys.exit(2)
def __init__(self, updatecallback, address = 0x9d, name = "/dev/serial", rate = 9600, config = None, use_fc4 = False): super(ModbusBase, self).__init__() self.Address = address self.Rate = rate self.PortName = name self.config = config self.InitComplete = False self.IsStopping = False self.UpdateRegisterList = updatecallback self.RxPacketCount = 0 self.TxPacketCount = 0 self.ComTimoutError = 0 self.TotalElapsedPacketeTime = 0 self.ModbusException = 0 self.ExcepFunction = 0 self.ExcepAddress = 0 self.ExcepData = 0 self.ExcepSlave = 0 self.ExcepAck = 0 self.ExcepBusy = 0 self.ExcepNack = 0 self.ExcepMemPe = 0 self.ExcepGateway = 0 self.ExcepGateWayTg = 0 self.CrcError = 0 self.ComValidationError = 0 self.ComSyncError = 0 self.UnexpectedData = 0 self.SlowCPUOptimization = False self.UseTCP = False self.AdditionalModbusTimeout = 0 self.ModBusPacketTimoutMS = 0 self.ResponseAddress = None # Used if recieve packes have a different address than sent packets self.debug = False self.UseModbusFunction4 = use_fc4 if self.config != None: self.debug = self.config.ReadValue('debug', return_type = bool, default = False) self.loglocation = self.config.ReadValue('loglocation', default = ProgramDefaults.LogPath) self.SlowCPUOptimization = self.config.ReadValue('optimizeforslowercpu', return_type = bool, default = False) self.UseTCP = self.config.ReadValue('use_serial_tcp', return_type = bool, default = False) self.ModbusTCP = self.config.ReadValue('modbus_tcp', return_type = bool, default = False) self.UseModbusFunction4 = self.config.ReadValue('use_modbus_fc4', return_type = bool, default = False) try: self.Address = int(self.config.ReadValue('address', default = '9d'),16) # modbus address except: self.Address = 0x9d self.AdditionalModbusTimeout = self.config.ReadValue('additional_modbus_timeout', return_type = float, default = 0.0) ResponseAddressStr = self.config.ReadValue('response_address', default = None) if ResponseAddressStr != None: try: self.ResponseAddress = int(ResponseAddressStr,16) # response modbus address except: self.ResponseAddress = None else: self.loglocation = default = './' self.CommAccessLock = threading.RLock() # lock to synchronize access to the serial port comms self.ModbusStartTime = datetime.datetime.now() # used for com metrics # log errors in this module to a file self.log = SetupLogger("mymodbus", os.path.join(self.loglocation, "mymodbus.log")) self.console = SetupLogger("mymodbus_console", log_file = "", stream = True) if self.UseModbusFunction4: # use modbus function code 4 instead of 3 for reading modbus values self.MBUS_CMD_READ_REGS = self.MBUS_CMD_READ_INPUT_REGS self.LogError("Using Modbus function 4 instead of 3")