/* * ModbusAnalogWideValue.cpp * * Created on: 17 апр. 2023 г. * Author: titov */ #include "ModbusAnalogWideValue.hh" #include #include bool driver::modbus::ModbusAnalogWideValue::extract() { using namespace std; float value = tech_value.get(); if( isnan(value) ) memcpy( data, &nan_out_of_range, sizeof(uint32_t) ); else { float temp = value * read_coeff + read_offset; if( temp < down_limit || temp > up_limit ) { memcpy( data, &nan_out_of_range, sizeof(uint32_t) ); } else { if( format_signed ) { int32_t signed_reg = rintf(temp); memcpy( data, &signed_reg, sizeof(int32_t) ); } else { uint32_t unsigned_input = rintf(temp); memcpy( data, &unsigned_input, sizeof(uint32_t) ); } } } return true; } bool driver::modbus::ModbusAnalogWideValue::update() { if( format_signed ) { int32_t signed_input; memcpy( &signed_input, data, sizeof(int32_t) ); if( signed_input >= down_limit and signed_input <= up_limit ) { tech_value.set( signed_input * write_coeff + write_offset ); return true; } else return false; } else { uint32_t unsigned_input; memcpy( &unsigned_input, data, sizeof(uint32_t) ); if( unsigned_input >= down_limit and unsigned_input <= up_limit ) { tech_value.set( unsigned_input * write_coeff + write_offset ); return true; } else return false; } } driver::modbus::ModbusAnalogWideValue::Status driver::modbus::ModbusAnalogWideValue::PartShower::read( uint16_t & reg ) { if( self.extract() ) { reg = *data; return Done; } else return Failure; } driver::modbus::ModbusAnalogWideValue::Status driver::modbus::ModbusAnalogWideValue::PartShower::write( uint16_t reg ) { *data = reg; return Done; } driver::modbus::ModbusAnalogWideValue::PartUpdater::Status driver::modbus::ModbusAnalogWideValue::PartUpdater::read( uint16_t & reg ) { reg = *data; return Done; } driver::modbus::ModbusAnalogWideValue::PartUpdater::Status driver::modbus::ModbusAnalogWideValue::PartUpdater::write( uint16_t reg ) { return *data = reg, self.update() ? Done : Failure; } driver::modbus::ModbusAnalogWideValue::ModbusAnalogWideValue( systemic::IValueType &value, float write_coeff, float write_offset, float read_coeff, float read_offset, bool sign, float up_limit, float down_limit, uint32_t nan_register, WordSequence sequnece) : tech_value(value), format_signed(sign), nan_out_of_range(nan_register), down_limit(down_limit), up_limit(up_limit), write_coeff(write_coeff), write_offset(write_offset), read_coeff(read_coeff), read_offset(read_offset), one( *this, sequnece == LowFirstHighSecond ? &data[1] : &data[0] ), two( *this, sequnece == HighFirstLowSecond ? &data[1] : &data[0] ) {} driver::modbus::IModBusDispatch & driver::modbus::ModbusAnalogWideValue::first() { return one; } driver::modbus::IModBusDispatch & driver::modbus::ModbusAnalogWideValue::second() { return two; }