<filename>pyfnip/__init__.py
import telnetlib
import socket
import requests
import time
from xml.etree import ElementTree
from abc import ABC, abstractmethod

class FNIPOutput:

	def __init__(self, host, port, channel):
	    self._host = host
	    self._port = int(port)
	    self._timeout = 1 # seconds
	    self._channel = int(channel)
	    self._state = None
	    self._updated_time = 0

	@abstractmethod
	def is_on(self):
		status = self.get_status(find)
		return status

	@abstractmethod
	def turn_on(self, state):
		cmd = "FN,ON," + str(self._channel)
		self.send_cmd(cmd)
		self.update_state(1)

	def turn_off(self):
		cmd = "FN,OFF," + str(self._channel)
		self.send_cmd(cmd)
		self.update_state(0)

	def update_state(self, state):
		self._state = state
		self._updated_time = time.time()

	def get_status(self, find):
		if self._updated_time > time.time()-2:
			# Use cached state for 2 seconds
			status = self._state
		else:
			# 2s delay is needed to get state change values ready in status.xml
			response = requests.get("http://" + self._host + "/status.xml")
			tree = ElementTree.fromstring(response.content)
			status = tree.findtext(find, "0")
			self.update_state(status)
		return status

	def send_cmd(self, cmd):
		try:
			tn = telnetlib.Telnet(self._host, self._port, self._timeout)
			tn.write(cmd.encode('ascii') + b"\r\n")
			tn.read_some()
			tn.close()
		except socket.timeout:
			pass

class FNIP8x10aOutput(FNIPOutput):
	def is_on(self):
		find = "led" + str(int(self._channel)-1)
		status = self.get_status(find)
		return status

	def turn_on(self, state):
		cmd = "FN,ON," + str(self._channel)
		self.send_cmd(cmd)
		self.update_state(1)

class FNIP6x2adOutput(FNIPOutput):
	def is_on(self):
		find = "level" + str(self._channel)
		status = self.get_status(find)
		return status

	def turn_on(self, state):
		cmd = "FN,LEV," + str(self._channel) + "," + str(state)
		self.send_cmd(cmd)
		self.update_state(state)

<filename>pyfnip/__init__.py
import telnetlib
import socket
import requests
import time
from xml.etree import ElementTree
from abc import ABC, abstractmethod

class FNIPOutput:

	def __init__(self, host, port, channel):
	    self._host = host
	    self._port = int(port)
	    self._timeout = 1 # seconds
	    self._channel = int(channel)
	    self._state = None
	    self._updated_time = 0

	@abstractmethod
	def is_on(self):
		status = self.get_status(find)
		return status

	@abstractmethod
	def turn_on(self, state):
		cmd = "FN,ON," + str(self._channel)
		self.send_cmd(cmd)
		self.update_state(1)

	def turn_off(self):
		cmd = "FN,OFF," + str(self._channel)
		self.send_cmd(cmd)
		self.update_state(0)

	def update_state(self, state):
		self._state = state
		self._updated_time = time.time()

	def get_status(self, find):
		if self._updated_time > time.time()-2:
			# Use cached state for 2 seconds
			status = self._state
		else:
			# 2s delay is needed to get state change values ready in status.xml
			response = requests.get("http://" + self._host + "/status.xml")
			tree = ElementTree.fromstring(response.content)
			status = tree.findtext(find, "0")
			self.update_state(status)
		return status

	def send_cmd(self, cmd):
		try:
			tn = telnetlib.Telnet(self._host, self._port, self._timeout)
			tn.write(cmd.encode('ascii') + b"\r\n")
			tn.read_some()
			tn.close()
		except socket.timeout:
			pass

class FNIP8x10aOutput(FNIPOutput):
	def is_on(self):
		find = "led" + str(int(self._channel)-1)
		status = self.get_status(find)
		return status

	def turn_on(self, state):
		cmd = "FN,ON," + str(self._channel)
		self.send_cmd(cmd)
		self.update_state(1)

class FNIP6x2adOutput(FNIPOutput):
	def is_on(self):
		find = "level" + str(self._channel)
		status = self.get_status(find)
		return status

	def turn_on(self, state):
		cmd = "FN,LEV," + str(self._channel) + "," + str(state)
		self.send_cmd(cmd)
		self.update_state(state)

# seconds # Use cached state for 2 seconds # 2s delay is needed to get state change values ready in status.xml