40 return strtof( in, &e );
43 static std::unique_ptr<ShelyakDriver> usis(
new ShelyakDriver());
57 if ( _serialPort != -1 )
68 bool ShelyakDriver::readConfig( )
74 std::ifstream file( fname );
78 catch(
const std::ifstream::failure &e )
80 LOGF_ERROR(
"File not found: %s", fname.c_str() );
85 LOGF_ERROR(
"Bad json file format: %s", fname.c_str() );
94 bool ShelyakDriver::findBoard(
const char* boardName,
json* result )
101 json boards = _config[
"boards"];
107 for(
json::iterator it = boards.begin(); it != boards.end(); ++it)
110 if( !it->is_object() )
115 json sig = (*it)[
"signature"];
135 return "Shelyak Usis";
139 bool ShelyakDriver::Connect( )
146 LOGF_ERROR(
"Failed to connect to port %s. Error: %s", serialConnection->
port(), errMsg );
154 bool ShelyakDriver::Disconnect( )
156 if ( _serialPort != -1 )
168 bool ShelyakDriver::initProperties( )
193 _actions.push_back( act );
201 void ShelyakDriver::scanProperties( )
211 if ( sendCmd( &rsp,
"GET;DEVICE_NAME;VALUE" ) )
219 fprintf( stderr,
"device not found %s\n", rsp.
parts[4] );
225 fprintf( stderr,
"found device %s\n", rsp.
parts[4] );
233 for (
json::iterator it = categs.begin(); it != categs.end(); ++it)
235 fprintf( stderr,
"category %s\n", it.key().c_str() );
236 genCatProps( it.key().c_str(), it.value() );
248 void ShelyakDriver::genCatProps(
const char* catName,
json &category )
257 for (
auto it = category.begin(); it != category.end(); ++it)
266 json jname = item[
"name"];
273 json jtype = item[
"type"];
280 json jcmd = item[
"command"];
283 LOGF_ERROR(
"expected property command",
"" );
291 std::string name = jname;
292 std::string
type = jtype;
293 std::string
cmd = jcmd;
295 fprintf( stderr,
" name: %s\n", name.c_str() );
298 if (
type ==
"string" )
301 fprintf( stderr,
" type: string\n" );
303 act = createAction(
_text,
type.c_str() );
312 else if (
type ==
"enum" )
315 fprintf( stderr,
" type: enum\n" );
317 json values = item[
"values"];
324 act = createAction(
_enum,
cmd.c_str() );
337 std::string
value = jvalue;
347 IUFillSwitchVector( &enm.
_vec, sws, nsw,
getDeviceName( ), act->
uid, name.c_str(), catName,
IP_RW,
ISR_1OFMANY, 60,
352 else if (
type ==
"number" )
355 fprintf( stderr,
" type: number\n" );
357 double minVal = -9999.0;
358 double maxVal = +9999.0;
359 double precVal = 0.01;
363 if(
min.is_number() )
366 fprintf( stderr,
" min: %lf\n", minVal );
370 if(
max.is_number() )
373 fprintf( stderr,
" max: %lf\n", maxVal );
376 json prec = item[
"prec"];
380 fprintf( stderr,
" prec: %lf\n", precVal );
392 json actions = item[
"actions"];
395 fprintf( stderr,
" actions:\n" );
398 for (
json::iterator it = actions.begin(); it != actions.end(); ++it)
402 if(
value.is_string() )
404 std::string n =
value;
408 fprintf( stderr,
" stop\n" );
410 else if( n ==
"CALIB" )
413 fprintf( stderr,
" calib\n" );
430 sub_act->
cmd.
cmd =
"STOP";
439 sub_act->
cmd.
cmd =
"CALIB";
445 IUFillSwitchVector( &enm.
_vec, sws, nsw,
getDeviceName( ), act->
uid,
" ", catName,
IP_RW,
ISR_ATMOST1, 60,
IPS_IDLE );
473 for(
auto it = _actions.cbegin(); it != _actions.cend(); ++it )
477 if( !(p->
type & 0x10) )
485 if( sendCmd( &rsp,
"GET;%s;VALUE", p->
name.c_str() ) )
505 for(
auto it2 = _actions.cbegin(); it2 != _actions.cend(); ++it2 )
537 bool ShelyakDriver::sendCmd(
UsisResponse* rsp,
const char* text, ... )
540 va_start( lst, text );
542 bool rc = _send( text, lst ) && _receive( rsp );
548 bool ShelyakDriver::_send(
const char* text, va_list lst )
558 int rc, nbytes_written;
559 if ( ( rc =
tty_write( _serialPort, buf, strlen( buf ),
560 &nbytes_written ) ) !=
TTY_OK )
586 fprintf( stderr,
"< received %s\n", rsp->
buffer );
593 while ( e >= p && ( e[-1] ==
'\n' || e[-1] ==
' ' ) )
602 while ( p < e && rsp->pcount < 5 )
613 if ( strcmp( rsp->
parts[0],
"M00" ) != 0 )
626 bool ShelyakDriver::updateProperties( )
643 void ShelyakDriver::clearProperties( )
646 for(
auto it = _actions.cbegin(); it != _actions.cend(); ++it )
664 for(
auto it = _actions.cbegin(); it != _actions.cend(); ++it )
668 if( p->
type ==
_eitm && strcmp( p->
uid, names[0] ) == 0 )
671 sendCmd( &rsp,
"SET;%s;VALUE;%s", p->
name.c_str(), p->
itm.
val.c_str() );
674 else if( p->
type ==
_ecmd && strcmp( p->
uid, names[0] ) == 0 )
677 sendCmd( &rsp,
"%s;%s;", p->
cmd.
cmd.c_str(), p->
cmd.
name.c_str() );
699 for(
auto it = _actions.cbegin(); it != _actions.cend(); ++it )
702 if ( p->
type ==
_text && strcmp( p->
uid, names[0] ) == 0 )
705 sendCmd( &rsp,
"SET;%s;VALUE;%s", p->
name.c_str(), texts[0] );
723 for(
auto it = _actions.cbegin(); it != _actions.cend(); ++it )
729 sendCmd( &rsp,
"SET;%s;VALUE;%lf", p->
name.c_str(), values[0] );
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the intial connection to the device...
The Serial class manages connection with serial devices including Bluetooth. Serial communication is ...
void setDefaultPort(const char *port)
setDefaultPort Set default port. Call this function in initProperties() of your driver if you want to...
virtual const char * port()
static std::string getSharedFilePath(std::string fileName)
const char * getDeviceName() const
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
void registerConnection(Connection::Interface *newConnection)
registerConnection Add new connection plugin to the existing connection pool. The connection type sha...
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
virtual bool initProperties()
Initilize properties initial state and value. The child class must implement this function.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
const char * getDefaultName() override
static void __update(void *ptr)
bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
a class to store JSON values
constexpr bool is_object() const noexcept
return whether value is an object
constexpr bool is_string() const noexcept
return whether value is a string
constexpr bool is_array() const noexcept
return whether value is an array
constexpr bool is_number() const noexcept
return whether value is a number
general exception of the basic_json class
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
int IEAddTimer(int millisecs, IE_TCF *fp, void *p)
Register a new single-shot timer function, fp, to be called with ud as argument after ms.
double _atof(const char *in)
#define SHELYAK_USIS_VERSION_MINOR
int tty_connect(const char *device, int bit_rate, int word_size, int parity, int stop_bits, int *fd)
Establishes a tty connection to a terminal device.
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
int tty_disconnect(int fd)
Closes a tty connection and flushes the bus.
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
int tty_nread_section(int fd, char *buf, int nsize, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Implementations for common driver routines.
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)
@ value
the parser finished reading a JSON value
ISwitchVectorProperty _vec
INumberVectorProperty _vec
char buffer[MAX_FRAME_LENGTH]
#define SHELYAK_USIS_VERSION_MAJOR