<?php
namespace Models;

class Scales_php {
	public $f3, $sets, $config, $port, $open=false;
	
	function __construct($f3, $sets, $config) {
		$this->f3=$f3;
		$this->sets=$sets;
        $this->config=$config;
		//$this->config=parse_ini_file($sets['driver'].'/server.config'); // Настройки драйвера
        require_once $sets['driver'].'/Scales.ports.php';
        $this->config['PortType']=strtolower($this->config['PortType']);
        if($this->config['PortType']=='remote') {
            $sets['url']=mb_substr($sets['url'], mb_strrpos($sets['url'], '/')+1);
            $url=explode(':', $sets['url']);
            $host = $url[0];
            $port = $url[1];
            $this->port = new \RemoteScalesPort($host, $port);
        }
        elseif($this->config['PortType']=='socket') {
            $sets['url']=mb_substr($sets['url'], mb_strrpos($sets['url'], '/')+1);
            $url=explode(':', $sets['url']);
            $host = $url[0];
            $port = $url[1];
            $this->port = new \RemoteScalesSocket($host, $port);
        }
        elseif($this->config['PortType']=='ssh') {
            $u=mb_substr($sets['url'], mb_strrpos($sets['url'], '/'));
            $url=explode(':', $u);
            $host = $url[0];
            $port = $url[1];
            $this->port = new \SshScalesComPort($host, $port);
        }
        else {
            $this->port = new \LocalScalesComPort($sets['url']);
        }

        if(!$this->config['WaitTime']) $this->config['WaitTime']=10;
        if(!$this->config['Attempts']) $this->config['Attempts']=1;
        if($this->config['AlwaysExec']) {
            $this->always_exec($this->config['AlwaysExec']);
        }
	}

    function always_exec($exec) {
        foreach ($exec as $cmd) {
            if($cmd!='') {
                exec($cmd);
            }
        }
    }

    function port_open() {
        $this->open=$this->port->open();
        if(!$this->open) {
            echo $error_txt='Не удалось подключиться';
            $this->f3->get('logs_model')->save_log($error_txt.' (Весы)');
            exit();
        };
    }

    function send_command($str, $length=20, $h=true) {
        $data=pack('H*', $str);

        if(!$this->open) {
            $this->port_open();
        }

        $res=$this->port->write($data);
        if($res) {
            $n=0;
            $res='';
            while ($n<$this->config['Attempts']) {
                usleep($this->config['WaitTime']);
                $res.=$this->port->read(1, 400);
                if($res && mb_strlen($res)==$length) {
                    if($h) $res=unpack('H*', $res)[1];
                    break;
                }
                $n++;
            }
            if(!$res) {
                echo $error_txt='Не удалось прочитать ответ: '.$str;
                $this->f3->get('logs_model')->save_log($error_txt.' (Весы)');
                exit();
            }
            return $res;
        }
        else {
            echo $error_txt='Не удалось отправить команду: '.$str;
            $this->f3->get('logs_model')->save_log($error_txt.' (Весы)');
            exit();
        }
    }

	function scales_init() {
		//$this->f3->set('SESSION.drivers_init', 1);
	}

    function prepareArg($num, $bytes) {
        return implode('', str_split(sprintf('%0' . ($bytes * 2) . 'x', $num), 2));
    }

    // Узнать вес
    function weight() {
        $weight=false;
        
        $pars='05';
        $res=$this->send_command($pars, 1);
        if($res=='06') {
            $pars='11';
            $res=$this->send_command($pars, 15, false);
            $s=mb_substr($res, 2, 2);
            if($s=='F') {
                $error_txt='Весы перегружены';
                $this->f3->get('logs_model')->save_log($error_txt.' (Весы)');
                return array(
                    'success'=>false,
                    'txt'=>$error_txt,
                );
            }

            if($s=='U') {
                $error_txt='Не удалось получить вес. Вес нестабильный.';
                $this->f3->get('logs_model')->save_log($error_txt.' (Весы)');
                return array(
                    'success'=>false,
                    'txt'=>$error_txt,
                );
            }
            $z=mb_substr($res, 3, 1);
            $weight=(float)mb_substr($res, 4, 6);
            if($z=='-') {
                $weight=-$weight;
            }
        }
        if(is_numeric($weight)) {
            return array(
                'success'=>true,
                'weight'=>round($weight, 3)
            );
        }
        $error_txt='Не удалось получить вес';
        $this->f3->get('logs_model')->save_log($error_txt.' (Весы)');
        return array(
            'success'=>false,
            'txt'=>$error_txt,
            'res'=>$weight
        );
    }
}
