from contextlib import contextmanager
from components import AStirrer
from components.actor.pololu1376 import *
import time
import serial


class StirrerPololu1376(AStirrer):
	def name(self):
		return "Pololu1376"

	def __init__(self, dt, params):
		AStirrer.__init__(self, dt)

		ser = serial.Serial(params['port'], params['speed'])
		ser.set_output_flow_control(False)
		self.drv = Pololu1376(ser)

	@contextmanager
	def remote_open(self):
		try:
			self.activate(True)
			yield None
		finally:
			self.activate(False)

	def get_speed(self):
		if self.isOn and self.is_activated():
			return self.speed
		return 0

	def activate(self, enable):
		print("activate {}".format(enable))
		if enable:
			self.drv.go()
		else:
			self.drv.stop()

	def _on_set_speed(self, speed):
		self.drv.motor_forward(speed)
		print("Set speed to {} %".format(speed))

	def _on_process(self):
		status = self.drv.get_variable(Varid.STATUS)
		limit_status = self.drv.get_variable(Varid.STATUS_LIMIT_STATUS)
		if status & 0x01 == 0x01:
			if limit_status & 0x01 == 0x01:
				print("Recover after motor error!")
				self.drv.go()
		

if __name__ == '__main__':
	s = StirrerPololu1376(dt=1.0, params={'port': "/dev/ttyACM0", 'speed': 115200})

	with s.remote_open():

		print("Set some speeds")
		s.set_speed(50)
		time.sleep(2)
		s.set_speed(20)
		time.sleep(2)
		s.set_speed(50)
		time.sleep(2)

		print("Pulsed operation, duty cycle = 50%")
		s.set_duty_cycle(0.5)
		s.set_cycle_time(10)
		for i in range(1, 30):
			s.process()
			time.sleep(1)

		print("Pulsed operation, duty cycle = 20%")
		s.set_duty_cycle(0.2)
		s.set_cycle_time(10)
		for i in range(1, 30):
			s.process()
			time.sleep(1)

		print("Continious operation")
		s.set_duty_cycle(1.0)
		s.set_speed(50)
		time.sleep(3.0)

		print("Continious operation increasing speed")
		for speed in range (25, 75, 5):
			s.set_duty_cycle(1.0)
			s.set_speed(speed)
			for d in range(0,3,1):
				s.process()
				time.sleep(1.0)

		print("Leaving context")

