import importlib
from empyric.adapters import Phidget, Serial
from empyric.instruments import Instrument, setter, measurer
from empyric.types import recast, String, Float


class Phidget1101(Instrument):
    """
    Phidgets 4x TC reader
    Many instrument methods (setX, getY, etc.) are mapped by the adapter from
    the Phidgets device class
    """

    name = 'Phidget1101'

    supported_adapters = (
        (Phidget, {}),
    )

    # Available knobs
    knobs = ('type',)

    # Available meters
    meters = ('temperature',)

    def __init__(self, *args, **kwargs):

        self.device_class = importlib.import_module(
            'Phidget22.Devices.TemperatureSensor'
        ).TemperatureSensor

        Instrument.__init__(self, *args, **kwargs)

    @setter
    def set_type(self, type_: String):

        types = importlib.import_module('Phidget22.ThermocoupleType')

        type_dict = {
            'K': types.ThermocoupleType.THERMOCOUPLE_TYPE_K,
            'J': types.ThermocoupleType.THERMOCOUPLE_TYPE_J,
            'T': types.ThermocoupleType.THERMOCOUPLE_TYPE_T,
            'E': types.ThermocoupleType.THERMOCOUPLE_TYPE_E,
        }

        self.write('ThermocoupleType', type_dict[type_])

    @measurer
    def measure_temperature(self) -> Float:
        return self.query('Temperature')


class WilliamsonPyrometer(Instrument):
    """
    Williamson Pro Series 2-color pyrometer.
    """

    supported_adapters = (
        (Serial, {
            'read_termination': b'\n\r',
            'write_termination': b'\r\n',
            'baud_rate': 38400
        }),
    )

    meters = (
        'temperature',
        'unfiltered temperature',
        'signal strength',
    )

    @measurer
    def measure_temperature(self) -> Float:
        # temp returned in F, convert to C
        return (recast(self.query('FT')) - 32) / 1.8

    @measurer
    def measure_unfiltered_temperature(self) -> Float:
        # temp returned in F, convert to C
        return (recast(self.query('UT')) - 32) / 1.8

    @measurer
    def measure_signal_strength(self) -> Float:
        return recast(self.query('SS'))
