diff --git a/arduino/common/lib/commsControl/commsConstants.h b/arduino/common/lib/commsControl/commsConstants.h index 1d658631a47c9135e452bc5d18857ad758cec1b3..e387dcd454d560b68606dbc51b0f0cf61ba70b22 100644 --- a/arduino/common/lib/commsControl/commsConstants.h +++ b/arduino/common/lib/commsControl/commsConstants.h @@ -36,6 +36,33 @@ enum command_codes {CMD_START = 1, CMD_STOP = 2}; +// Taken from safety doc. Correct as of 1400 on 20200416 +enum alarm_codes {APNEA = 1, // HP + CHECK_VALVE_EXHALE = 2, // HP + CHECK_P_PATIENT = 3, // HP + EXPIRATION_SENSE_FAULT_OR_LEAK = 4, // MP + EXPIRATION_VALVE_Leak = 5, // MP + HIGH_FIO2 = 6, // MP + HIGH_PRESSURE = 7, // HP + HIGH_RR = 8, // MP + HIGH_VTE = 9, // MP + LOW_VTE = 10, // MP + HIGH_VTI = 11, // MP + LOW_VTI = 12, // MP + INTENTIONAL_STOP = 13, // HP + LOW_BATTERY = 14, // HP (LP) if AC power isn't (is) connected + LOW_FIO2 = 15, // HP + OCCLUSION = 16, // HP + HIGH_PEEP = 17, // HP + LOW_PEEP = 18, // HP + AC_POWER_DISCONNECTION = 19, // MP + BATTERY_FAULT_SRVC = 20, // MP + BATTERY_CHARGE = 21, // MP + AIR_FAIL = 22, // HP + O2_FAIL = 23, // HP + PRESSURE_SENSOR_FAULT = 24, // HP + ARDUINO_FAIL = 25}; // HP + // struct for all data sent struct dataFormat { uint8_t version = HEV_FORMAT_VERSION; // diff --git a/arduino/protocol/lib/commsControl/commsConstants.h b/arduino/protocol/lib/commsControl/commsConstants.h deleted file mode 100644 index fecc66bb65ad8eef33c67451b73b19d63e5463b6..0000000000000000000000000000000000000000 --- a/arduino/protocol/lib/commsControl/commsConstants.h +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef COMMSCONSTANTS_H -#define COMMSCONSTANTS_H - -#include <Arduino.h> - -#define CONST_TIMEOUT_ALARM 5 -#define CONST_TIMEOUT_DATA 10 -#define CONST_TIMEOUT_CMD 50 - - -#define CONST_MAX_SIZE_RB_RECEIVING 10 -#define CONST_MAX_SIZE_RB_SENDING 5 -#define CONST_MAX_SIZE_PACKET 64 -#define CONST_MAX_SIZE_BUFFER 128 -#define CONST_MIN_SIZE_PACKET 7 - -#define COMMS_FRAME_BOUNDARY 0x7E -#define COMMS_FRAME_ESCAPE 0x7D -#define COMMS_ESCAPE_BIT_SWAP 5 - -#define COMMS_CONTROL_INFORMATION 0x00 -#define COMMS_CONTROL_SUPERVISORY 0x01 - -#define COMMS_CONTROL_TYPES 0x0F -#define COMMS_CONTROL_ACK 0x00 | COMMS_CONTROL_SUPERVISORY -#define COMMS_CONTROL_NACK 0x04 | COMMS_CONTROL_SUPERVISORY - -#define PACKET_TYPE 0xC0 -#define PACKET_ALARM 0xC0 -#define PACKET_CMD 0x80 -#define PACKET_DATA 0x40 -#define PACKET_SET 0x20 //set vs get ? - -#define HEV_FORMAT_VERSION 0xA0 - -enum command_codes {CMD_START = 1, - CMD_STOP = 2}; - -// struct for all data sent -struct dataFormat { - uint8_t version = HEV_FORMAT_VERSION; // - uint8_t fsm_state = 0; - uint16_t pressure_air_supply = 0; - uint16_t pressure_air_regulated = 0; - uint16_t pressure_o2_supply = 0; - uint16_t pressure_o2_regulated = 0; - uint16_t pressure_buffer = 0; - uint16_t pressure_inhale = 0; - uint16_t pressure_patient = 0; - uint16_t temperature_buffer = 0; - uint16_t pressure_diff_patient = 0; - uint8_t readback_valve_air_in = 0; - uint8_t readback_valve_o2_in = 0; - uint8_t readback_valve_inhale = 0; - uint8_t readback_valve_exhale = 0; - uint8_t readback_valve_purge = 0; - uint8_t readback_mode = 0; -}; - -struct cmdFormat { - uint8_t version = HEV_FORMAT_VERSION; // - uint8_t cmdCode = 0; - uint32_t param = 0; -}; - -struct alarmFormat{ - uint8_t version = HEV_FORMAT_VERSION; // - uint8_t alarmCode = 0; - uint32_t param = 0; - // do we do the same as dataFormat and put all alarms in one message? -}; - -// enum of all transfer types -enum payloadType { - payloadData, - payloadCmd, - payloadAlarm, - payloadUnset -}; - -// payload consists of type and information -// type is set as address in the protocol -// information is set as information in the protocol -class payload { -public: - payload(payloadType type = payloadType::payloadUnset) {type_ = type; } //data_ = nullptr; cmd_ = nullptr; alarm_ = nullptr; } - payload(const payload &other) { -// unsetAll(); - type_ = other.type_; - /*if ( other. data_ != nullptr) { data_ = new dataFormat;*/ memcpy(& data_, & other.data_, sizeof( dataFormat));// } else { data_ = nullptr; } - /*if ( other. cmd_ != nullptr) { cmd_ = new cmdFormat;*/ memcpy(& cmd_, & other.cmd_, sizeof( cmdFormat));// } else { cmd_ = nullptr; } - /*if ( other.alarm_ != nullptr) { alarm_ = new alarmFormat;*/ memcpy(&alarm_, &other.alarm_, sizeof(alarmFormat));// } else {alarm_ = nullptr; } - } - payload& operator=(const payload& other) { -// unsetAll(); - type_ = other.type_; - /*if ( other. data_ != nullptr) { data_ = new dataFormat;*/ memcpy(& data_, & other.data_, sizeof( dataFormat));// } else { data_ = nullptr; } - /*if ( other. cmd_ != nullptr) { cmd_ = new cmdFormat;*/ memcpy(& cmd_, & other.cmd_, sizeof( cmdFormat));// } else { cmd_ = nullptr; } - /*if ( other.alarm_ != nullptr) { alarm_ = new alarmFormat;*/ memcpy(&alarm_, &other.alarm_, sizeof(alarmFormat));// } else {alarm_ = nullptr; } - - return *this; - } - - ~payload() {;}//unsetData(); unsetAlarm(); unsetCmd();} - - void setType(payloadType type) { type_ = type; } - payloadType getType() {return type_; } - - // requires argument as new struct - void setData (dataFormat *data) { /*unsetAll(); */ type_ = payloadType::payloadData; /* data_ = new dataFormat( *data); }*/ memcpy(& data_, data, sizeof( dataFormat)); } - void setCmd (cmdFormat *cmd) { /*unsetAll(); */ type_ = payloadType::payloadCmd; /* cmd_ = new cmdFormat( *cmd); }*/ memcpy(& cmd_, cmd, sizeof( cmdFormat)); } - void setAlarm(alarmFormat *alarm) { /*unsetAll(); */ type_ = payloadType::payloadAlarm;/* alarm_ = new alarmFormat( *alarm); }*/ memcpy(&alarm_, alarm, sizeof(alarmFormat)); } - - dataFormat *getData () {return &data_; } - cmdFormat *getCmd () {return &cmd_; } - alarmFormat *getAlarm() {return &alarm_; } - -// void unsetAll() { unsetData(); unsetAlarm(); unsetCmd(); type_ = payloadType::payloadUnset; } -// void unsetData() { if ( data_ != nullptr) { delete data_; data_ = nullptr; } } -// void unsetCmd() { if ( cmd_ != nullptr) { delete cmd_; cmd_ = nullptr; } } -// void unsetAlarm() { if (alarm_ != nullptr) { delete alarm_; alarm_ = nullptr; } } - - void setPayload(payloadType type, void* dt) { - switch (type) { - case payloadType::payloadData: - setData(reinterpret_cast<dataFormat*>(dt)); - break; - case payloadType::payloadCmd: - setCmd(reinterpret_cast<cmdFormat*>(dt)); - break; - case payloadType::payloadAlarm: - setAlarm(reinterpret_cast<alarmFormat*>(dt)); - break; - default: - break; - } - } - - // returns void pointer, in case you know what to do with data - void *getInformation() { - switch (type_) { - case payloadType::payloadData: - return reinterpret_cast<void*>(getData()); - case payloadType::payloadCmd: - return reinterpret_cast<void*>(getCmd()); - case payloadType::payloadAlarm: - return reinterpret_cast<void*>(getAlarm()); - default: - return nullptr; - } - } - - uint8_t getInformationSize() { - switch (type_) { - case payloadType::payloadData: - return static_cast<uint8_t>(sizeof( dataFormat)); - case payloadType::payloadCmd: - return static_cast<uint8_t>(sizeof( cmdFormat)); - case payloadType::payloadAlarm: - return static_cast<uint8_t>(sizeof(alarmFormat)); - default: - return 0; - } - } - -private: - payloadType type_; - - dataFormat data_; - cmdFormat cmd_; - alarmFormat alarm_; -}; - -#endif diff --git a/arduino/protocol/lib/commsControl/commsControl.cpp b/arduino/protocol/lib/commsControl/commsControl.cpp deleted file mode 100644 index 00fb149b2bd61068aae7f5512401a63f60a3173e..0000000000000000000000000000000000000000 --- a/arduino/protocol/lib/commsControl/commsControl.cpp +++ /dev/null @@ -1,341 +0,0 @@ -#include "commsControl.h" - -commsControl::commsControl(uint32_t baudrate) { - baudrate_ = baudrate; - - lastTransTime_ = millis(); - - startTransIndex_ = 0xFF; - lastTransIndex_ = 0; - commsReceivedSize_ = 0; - commsSendSize_ = 0; - foundStart_ = false; - - memset(lastTrans_ , 0, sizeof(lastTrans_ )); - memset(commsReceived_, 0, sizeof(commsReceived_)); - memset(commsSend_ , 0, sizeof(commsSend_ )); - - queueAlarm_ = new RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING>(); - queueData_ = new RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING>(); - queueCmd_ = new RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING>(); - - queueReceived_ = new RingBuf<payload, CONST_MAX_SIZE_RB_RECEIVING>(); - - commsTmp_ = commsFormat(CONST_MAX_SIZE_PACKET - CONST_MIN_SIZE_PACKET ); - - commsAck_ = commsFormat::generateACK(); - commsNck_ = commsFormat::generateNACK(); - - sequenceSend_ = 0; - sequenceReceive_ = 0; -} - -// WIP -commsControl::~commsControl() { - ; -} - -void commsControl::beginSerial() { - Serial.begin(baudrate_); -} - -// main function to always call and try and send data -// TODO: needs switch on data type with global timeouts on data pushing -void commsControl::sender() { - if (millis() > lastTransTime_ + CONST_TIMEOUT_ALARM ) { - sendQueue(queueAlarm_); - } - - if (millis() > lastTransTime_ + CONST_TIMEOUT_CMD ) { - sendQueue(queueCmd_); - } - - if (millis() > lastTransTime_ + CONST_TIMEOUT_DATA ) { - sendQueue(queueData_); - } -} - -// main function to always try to receive data -// TODO: needs switch on data type with global timeouts on data pushing -void commsControl::receiver() { - uint8_t currentTransIndex; - - // check if any data in waiting - if (Serial.available()) { - // while able to read data (unable == -1) - while (Serial.peek() >= 0) { - // read byte by byte, just in case the transmission is somehow blocked - - // WARNING: for mkrvidor4000, readbytes takes char* not uchar* - lastTransIndex_ += Serial.readBytes(lastTrans_ + lastTransIndex_, 1); - - // if managed to read at least 1 byte - if (lastTransIndex_ > 0 && lastTransIndex_ < CONST_MAX_SIZE_BUFFER) { - currentTransIndex = lastTransIndex_ - 1; - - // find the boundary of frames - if (lastTrans_[currentTransIndex] == COMMS_FRAME_BOUNDARY) { - // if not found start or if read the same byte as last time - if (!foundStart_ || startTransIndex_ == currentTransIndex) { - foundStart_ = true; - startTransIndex_ = currentTransIndex; - } else { - // if managed to decode and compare CRC - if (decoder(lastTrans_, startTransIndex_, lastTransIndex_)) { - - sequenceReceive_ = (*(commsTmp_.getControl()) >> 1 ) & 0x7F; - // to decide ACK/NACK/other; for other gain sequenceReceive - uint8_t control = *(commsTmp_.getControl() + 1); - - // to decide what kind of packets received - payloadType type = getInfoType(commsTmp_.getAddress()); - - // switch on received data to know what to do - received ACK/NACK or other - switch(control & COMMS_CONTROL_TYPES) { - case COMMS_CONTROL_NACK: - // received NACK - // TODO: modify timeout for next sent frame? - // resendPacket(&address); - break; - case COMMS_CONTROL_ACK: - // received ACK - finishPacket(&type); - break; - default: - uint8_t tmpSequenceReceive = (control >> 1 ) & 0x7F; - tmpSequenceReceive += 1; - // received DATA - if (receivePacket(&type)) { - commsAck_->setAddress(commsTmp_.getAddress()); - commsAck_->setSequenceReceive(tmpSequenceReceive); - sendPacket(commsAck_); - } else { - commsNck_->setAddress(commsTmp_.getAddress()); - commsNck_->setSequenceReceive(tmpSequenceReceive); - sendPacket(commsNck_); - } - - break; - } - } - - // reset the frame - foundStart_ = false; - lastTransIndex_ = 0; - startTransIndex_ = 0xFF; - - // break the loop, even if more data waiting in the bus - this frame is finished - break; - } - } - } else if (lastTransIndex_ >= CONST_MAX_SIZE_BUFFER) { - lastTransIndex_ = 0; - } - } - } -} - -bool commsControl::writePayload(payload &pl) { - commsFormat* tmpComms; - payloadType type = pl.getType(); - - // switch on different received payload types - // TODO simplify the static functions - switch(type) { - case payloadAlarm: - tmpComms = commsFormat::generateALARM(&pl); - break; - case payloadData: - tmpComms = commsFormat::generateDATA(&pl); - break; - case payloadCmd: - tmpComms = commsFormat::generateCMD(&pl); - break; - default: - return false; - } - - RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *tmpQueue = getQueue(&type); - // add new entry to the queue - if (tmpQueue->isFull()) { - commsFormat *tmpCommsRm; - if (tmpQueue->pop(tmpCommsRm)) { - delete tmpCommsRm; - } - } - - if (tmpQueue->push(tmpComms) ) { - return true; - } - return false; -} - -bool commsControl::readPayload( payload &pl) { - if ( !queueReceived_->isEmpty()) { - if (queueReceived_->pop(pl)) { - return true; - } - } - return false; -} - -// general encoder of any transmission -bool commsControl::encoder(uint8_t *data, uint8_t dataSize) { - if (dataSize > 0) { - commsSendSize_ = 0; - uint8_t tmpVal = 0; - - commsSend_[commsSendSize_++] = data[0]; - for (uint8_t idx = 1; idx < dataSize - 1; idx++) { - tmpVal = data[idx]; - if (tmpVal == COMMS_FRAME_ESCAPE || tmpVal == COMMS_FRAME_BOUNDARY) { - commsSend_[commsSendSize_++] = COMMS_FRAME_ESCAPE; - tmpVal ^= (1 << COMMS_ESCAPE_BIT_SWAP); - } - commsSend_[commsSendSize_++] = tmpVal; - } - commsSend_[commsSendSize_++] = data[dataSize-1]; - - return true; - } - return false; -} - - -// general decoder of any transmission -bool commsControl::decoder(uint8_t* data, uint8_t dataStart, uint8_t dataStop) { - // need to have more than 1 byte transferred - if (dataStop > (dataStart + 1)) { - commsReceivedSize_ = 0; - uint8_t tmpVal = 0; - bool escaped = false; - - for (uint8_t idx = dataStart; idx < dataStop; idx++) { - tmpVal = data[idx]; - if (tmpVal == COMMS_FRAME_ESCAPE) { - escaped = true; - } else { - if (escaped) { - tmpVal ^= (1 << COMMS_ESCAPE_BIT_SWAP); - escaped = false; - } - commsReceived_[commsReceivedSize_++] = tmpVal; - } - } - commsTmp_.copyData(commsReceived_, commsReceivedSize_); - return commsTmp_.compareCrc(); - } - return false; -} - -// sending anything of commsDATA format -void commsControl::sendQueue(RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queue) { - // if have data to send - if (!queue->isEmpty()) { - // reset sending counter - lastTransTime_ = millis(); - - queue->operator [](0)->setSequenceSend(sequenceSend_); - - sendPacket(queue->operator [](0)); - } -} - -void commsControl::sendPacket(commsFormat *packet) { - // if encoded and able to write data - if (encoder(packet->getData(), packet->getSize()) ) { - if (Serial.availableForWrite() >= commsSendSize_) { - Serial.write(commsSend_, commsSendSize_); - } - } -} - -// resending the packet, can lower the timeout since either NACK or wrong FCS already checked -//WIP -void commsControl::resendPacket(RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queue) { - ; -} - - -// receiving anything of commsFormat -bool commsControl::receivePacket(payloadType *type) { - payload tmpPl = payload(*type); - - void *tmpInformation = nullptr; - switch (*type) { - case payloadType::payloadData: - tmpInformation = reinterpret_cast<void*>(tmpPl.getData()); -// tmpInformation = reinterpret_cast<void*>(new dataFormat); - break; - case payloadType::payloadCmd: - tmpInformation = reinterpret_cast<void*>(tmpPl.getCmd()); -// tmpInformation = reinterpret_cast<void*>(new cmdFormat); - break; - case payloadType::payloadAlarm: - tmpInformation = reinterpret_cast<void*>(tmpPl.getAlarm()); -// tmpInformation = reinterpret_cast<void*>(new alarmFormat); - break; - default: - break; - } - - if (tmpInformation == nullptr) { - return false; - } - memcpy(tmpInformation, commsTmp_.getInformation(), commsTmp_.getInfoSize()); - tmpPl.setPayload(*type, tmpInformation); - - // remove first entry if RB is full - if (queueReceived_->isFull()) { - payload tmpPlRm; - if (queueReceived_->pop(tmpPlRm)) { - ; - } - } - - return queueReceived_->push(tmpPl); -} - -// if FCS is ok, remove from queue -void commsControl::finishPacket(payloadType *type) { - RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *tmpQueue = getQueue(type); - - if (tmpQueue != nullptr && !tmpQueue->isEmpty()) { - // get the sequence send from first entry in the queue, add one as that should be return - // 0x7F to deal with possible overflows (0 should follow after 127) - if (((tmpQueue->operator [](0)->getSequenceSend() + 1) & 0x7F) == sequenceReceive_) { - sequenceSend_ = (sequenceSend_ + 1) % 128; - commsFormat * tmpComms; - if (tmpQueue->pop(tmpComms)) { - delete tmpComms; - } - } - } -} - -payloadType commsControl::getInfoType(uint8_t *address) { - switch (*address & PACKET_TYPE) { - case PACKET_ALARM: - return payloadType::payloadAlarm; - case PACKET_CMD: - return payloadType::payloadCmd; - case PACKET_DATA: - return payloadType::payloadData; - default: - return payloadType::payloadUnset; - } -} - -// get link to queue according to packet format -RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *commsControl::getQueue(payloadType *type) { - switch (*type) { - case payloadType::payloadAlarm: - return queueAlarm_; - case payloadType::payloadCmd: - return queueCmd_; - case payloadType::payloadData: - return queueData_; - default: - return nullptr; - } -} diff --git a/arduino/protocol/lib/commsControl/commsControl.h b/arduino/protocol/lib/commsControl/commsControl.h deleted file mode 100644 index 789f360585a89a886a8a022e01a2faef831622f5..0000000000000000000000000000000000000000 --- a/arduino/protocol/lib/commsControl/commsControl.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef COMMS_CONTROL_H -#define COMMS_CONTROL_H - -// Communication protocol between rasp and arduino based on HDLC format -// author Peter Svihra <peter.svihra@cern.ch> - -#include <Arduino.h> -#include "RingBuf.h" - -#include "commsConstants.h" -#include "commsFormat.h" - -/////////////////////////////////////////////////////////////////////////// -// class to provide simple communication protocol based on the data format -class commsControl { -public: - commsControl(uint32_t baudrate = 115200); - ~commsControl(); - - void beginSerial(); - - bool writePayload(payload &pl); - bool readPayload (payload &pl); - - void sender(); - void receiver(); - -private: - RingBuf<commsFormat *,CONST_MAX_SIZE_RB_SENDING> *getQueue(payloadType *type); - payloadType getInfoType(uint8_t *address); - - void sendQueue (RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queue); - void resendPacket (RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queue); - bool receivePacket(payloadType *type); - void finishPacket (payloadType *type); - - bool encoder(uint8_t* payload, uint8_t dataSize); - bool decoder(uint8_t* payload, uint8_t dataStart, uint8_t dataStop); - - void sendPacket(commsFormat* packet); - -private: - uint8_t sequenceSend_; - uint8_t sequenceReceive_; - - commsFormat* commsAck_; - commsFormat* commsNck_; - - RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queueAlarm_; - RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queueData_; - RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queueCmd_; - - RingBuf<payload, CONST_MAX_SIZE_RB_RECEIVING> *queueReceived_; - - commsFormat commsTmp_; - - uint32_t baudrate_; - - uint64_t lastTransTime_; - - uint8_t commsReceived_[CONST_MAX_SIZE_BUFFER]; - uint8_t commsReceivedSize_; - uint8_t commsSend_ [CONST_MAX_SIZE_BUFFER]; - uint8_t commsSendSize_; - - uint8_t lastTrans_[CONST_MAX_SIZE_BUFFER]; - uint8_t startTransIndex_; - uint8_t lastTransIndex_; - - bool foundStart_; -}; - -#endif diff --git a/arduino/protocol/lib/commsControl/commsFormat.cpp b/arduino/protocol/lib/commsControl/commsFormat.cpp deleted file mode 100644 index b4951e597f8dc635810eb730d2d3f38bc7f38398..0000000000000000000000000000000000000000 --- a/arduino/protocol/lib/commsControl/commsFormat.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "commsFormat.h" - -// constructor to init variables -commsFormat::commsFormat(uint8_t infoSize, uint8_t address, uint16_t control) { - memset(data_, 0, sizeof(data_)); - - infoSize_ = infoSize; - packetSize_ = infoSize + CONST_MIN_SIZE_PACKET ; // minimum size (start,address,control,fcs,stop) - if (packetSize_ > CONST_MAX_SIZE_PACKET) { - return; - } - - assignBytes(getAddress(), &address, 1, false); - assignBytes(getControl(), reinterpret_cast<uint8_t*>(&control), 2, false); - - // hardcoded defaults - *getStart() = COMMS_FRAME_BOUNDARY; // fixed start flag - *getStop() = COMMS_FRAME_BOUNDARY; // fixed stop flag - - generateCrc(); -} - -void commsFormat::assignBytes(uint8_t* target, uint8_t* source, uint8_t size, bool calcCrc) { - memcpy(target, source, size); - if (calcCrc) { - generateCrc(); - } -} - -void commsFormat::setSequenceSend(uint8_t counter) { - // sequence send valid only for info frames (not supervisory ACK/NACK) - if ((*(getControl() + 1) & COMMS_CONTROL_SUPERVISORY) == 0) { - counter = (counter << 1) & 0xFE; - assignBytes(getControl() + 1, &counter, 1); - } -} - -uint8_t commsFormat::getSequenceSend() { - // sequence send valid only for info frames (not supervisory ACK/NACK) - if ((*(getControl() + 1) & COMMS_CONTROL_SUPERVISORY) == 0) { - return (*(getControl() + 1) >> 1) & 0x7F; - } else { - return 0xFF; - } -} - -void commsFormat::setSequenceReceive(uint8_t counter) { - counter = (counter << 1) & 0xFE; - assignBytes(getControl() , &counter, 1); -} - -uint8_t commsFormat::getSequenceReceive() { - return (*(getControl()) >> 1) & 0x7F; -} - -// compare calculated and received CRC value -bool commsFormat::compareCrc() { - // generate data crc - generateCrc(false); - - // get crc from fcs - uint16_t tmpFcs; - assignBytes(reinterpret_cast<uint8_t*>(&tmpFcs), getFcs(), 2, false); - - // return comparison - return tmpFcs == crc_; -} - -// calculate CRC value -void commsFormat::generateCrc(bool assign) { - // calculate crc - crc_ = uCRC16Lib::calculate(reinterpret_cast<char*>(getAddress()), static_cast<uint16_t>(infoSize_ + 3)); - - // assign crc to fcs - if (assign) { - assignBytes(getFcs(), reinterpret_cast<uint8_t*>(&crc_), 2, false); - } -} - -// assign received information to packet -void commsFormat::setInformation(payload *pl) { - assignBytes(getInformation(), reinterpret_cast<uint8_t*>(pl->getInformation()), getInfoSize()); -} - -void commsFormat::copyData(uint8_t* data, uint8_t dataSize) { - packetSize_ = dataSize; - infoSize_ = dataSize - CONST_MIN_SIZE_PACKET; - memset(getData(), 0, sizeof(data_)); - - assignBytes(getData(), data, dataSize); -} - - -// STATIC METHODS -// TODO rewrite in a slightly better way using the enum -commsFormat* commsFormat::generateALARM(payload *pl) { - commsFormat *tmpComms = new commsFormat(pl->getInformationSize(), PACKET_ALARM); - tmpComms->setInformation(pl); - return tmpComms; -} -commsFormat* commsFormat::generateCMD (payload *pl) { - commsFormat *tmpComms = new commsFormat(pl->getInformationSize(), PACKET_CMD ); - tmpComms->setInformation(pl); - return tmpComms; -} -commsFormat* commsFormat::generateDATA (payload *pl) { - commsFormat *tmpComms = new commsFormat(pl->getInformationSize(), PACKET_DATA ); - tmpComms->setInformation(pl); - return tmpComms; -} - diff --git a/arduino/protocol/lib/commsControl/commsFormat.h b/arduino/protocol/lib/commsControl/commsFormat.h deleted file mode 100644 index 81b2ca47a1b1eb7b1facb952567ccc8638254771..0000000000000000000000000000000000000000 --- a/arduino/protocol/lib/commsControl/commsFormat.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef COMMSFORMAT_H -#define COMMSFORMAT_H - -// Communication protocol based on HDLC format -// author Peter Svihra <peter.svihra@cern.ch> - -#include <Arduino.h> -#include <uCRC16Lib.h> - -#include "commsConstants.h" - -/////////////////////////////////////////////////////////////////////////// -// class to provide all needed control in data format -class commsFormat { -public: - commsFormat(uint8_t infoSize = 0, uint8_t address = 0x00, uint16_t control = 0x0000); - commsFormat(const commsFormat& other) { - crc_ = other.crc_; - packetSize_ = other.packetSize_; - infoSize_ = other.infoSize_; - memcpy(data_, other.data_, CONST_MAX_SIZE_PACKET); - } - commsFormat& operator=(const commsFormat& other) { - crc_ = other.crc_; - packetSize_ = other.packetSize_; - infoSize_ = other.infoSize_; - memcpy(data_, other.data_, CONST_MAX_SIZE_PACKET); - - return *this; - } - - uint8_t* getData() { return data_; } - uint8_t getSize() { return packetSize_; } - - void setAddress(uint8_t* address) {assignBytes(getAddress(), address, 1); } - void setControl(uint8_t* control) {assignBytes(getControl(), control, 2); } - void setInformation(payload *pl); - - void assignBytes(uint8_t* target, uint8_t* source, uint8_t size, bool calcCrc = true); - - void generateCrc(bool assign = true); - bool compareCrc(); - - // get data pointer of different parts - uint8_t* getStart() {return data_ + 0;} // starting flag of the chain - uint8_t* getAddress() {return data_ + 1;} // address where to send data, last bit is 8bit extension enable(0)/disable(1) - uint8_t* getControl() {return data_ + 2;} // frame control commands - uint8_t* getInformation() {return data_ + 4;} // user information - uint8_t* getFcs() {return data_ + 4 + infoSize_;} // checksum - uint8_t* getStop() {return data_ + 4 + infoSize_ + 2;} // ending flag of the chain - - uint8_t getInfoSize() { return infoSize_; } - - void setSequenceSend (uint8_t counter); - void setSequenceReceive(uint8_t counter); - - uint8_t getSequenceSend (); - uint8_t getSequenceReceive(); - - void copyData(uint8_t* payload, uint8_t dataSize); - - static commsFormat* generateACK() { return new commsFormat(0, 0, COMMS_CONTROL_ACK << 8); } - static commsFormat* generateNACK() { return new commsFormat(0, 0, COMMS_CONTROL_NACK << 8); } - - static commsFormat* generateALARM(payload *pl); - static commsFormat* generateCMD (payload *pl); - static commsFormat* generateDATA (payload *pl); - -private: - uint8_t data_[CONST_MAX_SIZE_PACKET]; - uint8_t packetSize_; - uint8_t infoSize_; - uint16_t crc_; -}; - -#endif // COMMSFORMAT_H diff --git a/raspberry-backend/app.py b/raspberry-backend/app.py index a578ac1079669c0a6bf07110614e5470be5064f6..cbf058454bc5d2f2f78945b7e3fa93f1fe76ef83 100755 --- a/raspberry-backend/app.py +++ b/raspberry-backend/app.py @@ -12,6 +12,7 @@ import sqlite3 from flask import json import chardet from hevclient import HEVClient +from commsConstants import dataFormat WEBAPP = Flask(__name__) @@ -20,6 +21,9 @@ WEBAPP = Flask(__name__) hevclient = HEVClient() +def getList(dict): + return [*dict] + @WEBAPP.route('/', methods=['GET', 'POST']) def hello_world(): return render_template('index.html', result=live_data()) @@ -94,15 +98,9 @@ def live_data(): Output in json format """ - list_variables = ['created_at', 'version' , - 'fsm_state' , 'pressure_air_supply' , - 'pressure_air_regulated' , 'pressure_o2_supply' , - 'pressure_o2_regulated' , 'pressure_buffer' , - 'pressure_inhale' , 'pressure_patient' , - 'temperature_buffer' , 'pressure_diff_patient' , - 'readback_valve_air_in' , 'readback_valve_o2_in' , - 'readback_valve_inhale' , 'readback_valve_exhale' , - 'readback_valve_purge' , 'readback_mode' ] + list_variables = [] + list_variables.append("created_at") + list_variables.extend(getList(dataFormat().getDict())) data = {key: None for key in list_variables} diff --git a/raspberry-backend/arduino_recorder.py b/raspberry-backend/arduino_recorder.py index 5561c9c9cae0a0aeb19a50feff84de846be4ae33..581c3230714d631cb9dd964dbb3641cb44e89a9b 100755 --- a/raspberry-backend/arduino_recorder.py +++ b/raspberry-backend/arduino_recorder.py @@ -9,20 +9,19 @@ import sys import time import argparse import sqlite3 -from random import random from datetime import datetime import threading from hevclient import HEVClient - +from commsConstants import dataFormat SQLITE_FILE = 'database/HEC_monitoringDB.sqlite' # name of the sqlite database file TABLE_NAME = 'hec_monitor' # name of the table to be created -def get_temperature(): - """ - Returns a random number to simulate data obtained from a sensor - """ - return random() * 20 +def getList(dict): + return [*dict] + +# List of data variables in the data packet from the Arduino +data_format = getList(dataFormat().getDict()) def database_setup(): @@ -36,28 +35,19 @@ def database_setup(): try: # Connecting to the database file conn = sqlite3.connect(SQLITE_FILE) - conn.execute('''CREATE TABLE IF NOT EXISTS ''' + TABLE_NAME + ''' ( - created_at INTEGER NOT NULL, - alarms STRING NOT NULL, - version FLOAT NOT NULL, - fsm_state FLOAT NOT NULL, - pressure_air_supply FLOAT NOT NULL, - pressure_air_regulated FLOAT NOT NULL, - pressure_o2_supply FLOAT NOT NULL, - pressure_o2_regulated FLOAT NOT NULL, - pressure_buffer FLOAT NOT NULL, - pressure_inhale FLOAT NOT NULL, - pressure_patient FLOAT NOT NULL, - temperature_buffer FLOAT NOT NULL, - pressure_diff_patient FLOAT NOT NULL, - readback_valve_air_in FLOAT NOT NULL, - readback_valve_o2_in FLOAT NOT NULL, - readback_valve_inhale FLOAT NOT NULL, - readback_valve_exhale FLOAT NOT NULL, - readback_valve_purge FLOAT NOT NULL, - readback_mode FLOAT NOT NULL - );''' - ) + + exec_string = "created_at INTEGER NOT NULL, " + for var in data_format: + exec_string += var + " FLOAT NOT NULL, " + exec_string += "alarms STRING NOT NULL " + + # Setting the maximum size of the DB to 100 MB + conn.execute("PRAGMA max_page_count = 204800") + conn.execute("PRAGMA page_size = 512") + + conn.execute('''CREATE TABLE IF NOT EXISTS {tn} ({ex_str});''' + .format(tn=TABLE_NAME, ex_str=exec_string)) + conn.commit() conn.close() except sqlite3.Error as err: @@ -72,7 +62,6 @@ def monitoring(source_address): # Instantiating the client hevclient = HEVClient() - print(hevclient.send_cmd("CMD_START")) epoch = datetime(1970, 1, 1) @@ -94,46 +83,26 @@ def monitoring(source_address): data_alarms = ','.join(data_alarms) else: data_alarms = "none" - - - data_packet = { - 'time' : timestamp, - 'alarms' : data_alarms, - 'version': data_receiver["version"], - 'fsm_state': data_receiver["fsm_state"], - 'pressure_air_supply': data_receiver["pressure_air_supply"], - 'pressure_air_regulated': data_receiver["pressure_air_regulated"], - 'pressure_o2_supply': data_receiver["pressure_o2_supply"], - 'pressure_o2_regulated': data_receiver["pressure_o2_regulated"], - 'pressure_buffer': data_receiver["pressure_buffer"], - 'pressure_inhale': data_receiver["pressure_inhale"], - 'pressure_patient': data_receiver["pressure_patient"], - 'temperature_buffer': data_receiver["temperature_buffer"], - 'pressure_diff_patient': data_receiver["pressure_diff_patient"], - 'readback_valve_air_in': data_receiver["readback_valve_air_in"], - 'readback_valve_o2_in': data_receiver["readback_valve_o2_in"], - 'readback_valve_inhale': data_receiver["readback_valve_inhale"], - 'readback_valve_exhale': data_receiver["readback_valve_exhale"], - 'readback_valve_purge': data_receiver["readback_valve_purge"], - 'readback_mode': data_receiver["readback_mode"] - } + + data_packet = { el : data_receiver[el] for el in data_format} + data_packet.update({"time" : timestamp}) + data_packet.update({"alarms" : data_alarms}) print("Writing to database ...") try: + exec_string = "( :time, " + for el in data_format: + exec_string += ":" + el + ", " + exec_string += ":alarms) " + cursor.execute( - 'INSERT INTO {tn} VALUES ' - '(:time, :alarms, :version, ' - ':fsm_state, :pressure_air_supply, ' - ':pressure_air_regulated, :pressure_o2_supply,' - ':pressure_o2_regulated, :pressure_buffer,' - ':pressure_inhale, :pressure_patient,' - ':temperature_buffer, :pressure_diff_patient,' - ':readback_valve_air_in, :readback_valve_o2_in,' - ':readback_valve_inhale, :readback_valve_exhale,' - ':readback_valve_purge, :readback_mode)' - .format(tn=TABLE_NAME), data_packet + 'INSERT INTO {tn} VALUES {ex_str} ' + .format(tn=TABLE_NAME, ex_str=exec_string), data_packet ) + conn.commit() + + except sqlite3.Error as err: raise Exception("sqlite3 error. Insert into database failed: {}".format(str(err))) finally: diff --git a/raspberry-backend/commsConstants.py b/raspberry-backend/commsConstants.py new file mode 120000 index 0000000000000000000000000000000000000000..0f24c112273123ee7e69dacdeb5f76fcebda0c2a --- /dev/null +++ b/raspberry-backend/commsConstants.py @@ -0,0 +1 @@ +../raspberry-dataserver/commsConstants.py \ No newline at end of file diff --git a/raspberry-backend/database/HEC_monitoringDB.sqlite b/raspberry-backend/database/HEC_monitoringDB.sqlite index 342d1ba5101f60ab192ea946d5f2590179fa8e2a..471743d7857451fdc86b9211851205d5c9177aa2 100644 Binary files a/raspberry-backend/database/HEC_monitoringDB.sqlite and b/raspberry-backend/database/HEC_monitoringDB.sqlite differ diff --git a/raspberry-backend/database/HEC_monitoringDB_backup.sqlite b/raspberry-backend/database/HEC_monitoringDB_backup.sqlite index 881b4b95be98e12b766f771bae3350abdc8d1f64..76867c5ad0eab29c4905a870c3ac969fd457d369 100644 Binary files a/raspberry-backend/database/HEC_monitoringDB_backup.sqlite and b/raspberry-backend/database/HEC_monitoringDB_backup.sqlite differ diff --git a/raspberry-backend/static/css/style_v3.css b/raspberry-backend/static/css/style_v3.css index f30f7dcaa3fcdf8caf88d5f96fd993c451c14e74..ff616b8895802b9448a765d11001dadd6cdb7e4e 100644 --- a/raspberry-backend/static/css/style_v3.css +++ b/raspberry-backend/static/css/style_v3.css @@ -2011,8 +2011,8 @@ pre code { transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } .form-button{ - height: calc(1.3em + 0.75rem + 2px); - padding: 0.375rem 0.75rem; + //height: calc(1.1em + 0.75rem + 2px); + background-color: #1f4793 ; color: white } @media (prefers-reduced-motion: reduce) { .form-control { @@ -4395,7 +4395,6 @@ input[type=button].btn-block { } .card-header { - padding: 0.75rem 1.25rem; margin-bottom: 0; background-color: rgba(0, 0, 0, 0.03); border-bottom: 1px solid rgba(0, 0, 0, 0.125); @@ -10283,6 +10282,8 @@ body { .alarm-ok{border: 1px solid var(--cern); width:20rem;} .alarm-red{border-color:#ff0000;color:#ff0000} .text-align-right{text-align:right;} +.text-align-center{text-align:center;} + #alarms{color:red;vertical-align:middle;text-align:center;line-height:calc(var(--top-height) - 0.5rem);} .border-invisible{ border: 1px solid rgb(255,255,255); @@ -10297,6 +10298,16 @@ div.active{ border: 1px solid var(--cern); width:200px; height:100px; + //box-shadow: + // inset 0 0 2px 0 rgba(255,255,255,.4), + // inset 0 0 3px 0 rgba(0,0,0,.4), + // inset 0 0 3px 5px rgba(0,0,0,.05), + // 2px 2px 4px 0 rgba(0,0,0,.25); + border-radius: 4px; + +} +.sb-control-button-pressed{ + } .sb-nav-button{ border: 1px solid var(--cern); width:95px; fill:none; @@ -10312,21 +10323,24 @@ div.active{ border-radius: 4px; } -.sb-nav-button:before { - //top: 0; - //border-bottom-left-radius: 4px; - //border-bottom-right-radius: 4px; - //background: rgba(255,255,255,.6); +.sb-control-button:before { + top: 0; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + background: rgba(255,255,255,.6); //box-shadow: 0 1px 2px 0 rgba(255,255,255,.6); } -.sb-nav-button:after { - //bottom: 0; - //border-top-left-radius: 4px; - //border-top-right-radius: 4px; - //background: rgba(0,0,0,.15); +.sb-control-button:after { + bottom: 0; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + background: rgba(0,0,0,.15); //box-shadow: 0 -1px 2px 0 rgba(0,0,0,.15); } .controls { position: absolute;bottom:0;} .col-center{ margin: 0 auto; } -.lh-1{line-height:1;} \ No newline at end of file +.lh-1{line-height:1;} +.min-height-1b{min-height:1.75rem;} +.min-height-2{min-height:2rem;} +.min-height-6{min-height:6rem;} \ No newline at end of file diff --git a/raspberry-backend/static/js/Chart-display.js b/raspberry-backend/static/js/Chart-display.js new file mode 100644 index 0000000000000000000000000000000000000000..d2886195c001ad61dafd947fb8c6dc94797efbe7 --- /dev/null +++ b/raspberry-backend/static/js/Chart-display.js @@ -0,0 +1,188 @@ +var chart_pressure; +var chart_flow; +var chart_volume; +var time_value = 0 ; + +/** + * Request data from the server, add it to the graph and set a timeout + * to request again + */ +function requestChartVar() { + $.ajax({ + url: '/live-data', + success: function(point) { + + if(chart_pressure.data.datasets[0].data.length > 30){ + chart_pressure.data.labels.shift(); + chart_pressure.data.datasets[0].data.shift(); + } + if(chart_flow.data.datasets[0].data.length > 30){ + chart_flow.data.labels.shift(); + chart_flow.data.datasets[0].data.shift(); + } + if(chart_volume.data.datasets[0].data.length > 30){ + chart_volume.data.labels.shift(); + chart_volume.data.datasets[0].data.shift(); + } + + + // Convert epoch timestamp into seconds + var date = new Date(point.created_at); + var seconds = date.getSeconds(); + + // Show the time that has passed + chart_pressure.data.labels.push(-(60-seconds)); + chart_pressure.data.datasets[0].data.push(point["pressure_buffer"]); + + // add the point + chart_flow.data.labels.push(point.created_at); + chart_flow.data.datasets[0].data.push(point["pressure_inhale"]); + + // add the point + chart_volume.data.labels.push(point.created_at); + chart_volume.data.datasets[0].data.push(point["temperature_buffer"]); + + chart_pressure.update(); + chart_flow.update(); + chart_volume.update(); + }, + cache: false + }); + // call it again after one second + setTimeout(requestChartVar, 1000); +} + + + +$(document).ready(function() { + var ctx_pressure = document.getElementById('pressure_chart'); + chart_pressure = new Chart(ctx_pressure, { + type: 'line', + data: { + labels: [], + datasets: [{ + data: [], + label: "Var1", + borderColor: "#3e95cd", + fill: false + } + ] + }, + options: { + responsive: true, + title: { + display: false, + text: 'Pressure [mbar]' + }, + scales: { + xAxes: [{ + ticks: { + beginAtZero: true + }, + //type: 'time', + time: { + unit: 'second', + displayFormat: 'second' + } + }], + yAxes: [{ + ticks: { + beginAtZero: true, + suggestedMax: 25 + }, + scaleLabel: { + display: true, + labelString: 'Pressure [mbar]' + } + }] + }, + legend : { + display: false} + }, + plugins: { + streaming: { + duration: 20000, + refresh: 1000, + delay: 2000, + onRefresh: requestChartVar() + } + } + }); +}); + + + + +$(document).ready(function() { + var ctx_flow = document.getElementById('flow_chart'); + chart_flow = new Chart(ctx_flow, { + type: 'line', + data: { + labels: [], + datasets: [{ + data: [], + label: "Var1", + borderColor: "#3e95cd", + fill: false + } + ] + }, + options: { + title: { + display: false, + text: 'Variable 1' + }, + scales: { + xAxes: [{ + type: 'time', + time: { + unit: 'second', + displayFormat: 'second' + } + }] + }, + legend : { + display: false} + } + }); + //requestChartVar("pressure_inhale"); +}); + + + +$(document).ready(function() { + var ctx_volume = document.getElementById('volume_chart'); + chart_volume = new Chart(ctx_volume, { + type: 'line', + data: { + labels: [], + datasets: [{ + data: [], + label: "Var1", + borderColor: "#3e95cd", + fill: false + } + ] + }, + options: { + title: { + display: false, + text: 'Variable 1' + }, + scales: { + xAxes: [{ + type: 'time', + time: { + unit: 'second', + displayFormat: 'second' + } + }] + }, + legend : { + display: false} + } + }); + //requestChartVar("temperature_buffer"); +}); + + diff --git a/raspberry-backend/static/js/Chart-display_BACKUP.js b/raspberry-backend/static/js/Chart-display_BACKUP.js new file mode 100644 index 0000000000000000000000000000000000000000..d9c7d0ee5d289a59e0a323be1ca746ff3ad08586 --- /dev/null +++ b/raspberry-backend/static/js/Chart-display_BACKUP.js @@ -0,0 +1,200 @@ +var chart_pressure; +var chart_flow; +var chart_volume; +var time_value = 0 ; + +/** + * Request data from the server, add it to the graph and set a timeout + * to request again + */ +function requestChartVar1() { + $.ajax({ + url: '/live-data', + success: function(point) { + + if(chart_pressure.data.datasets[0].data.length > 10){ + chart_pressure.data.labels.shift(); + chart_pressure.data.datasets[0].data.shift(); + } + + + // add the point + chart_pressure.data.labels.push(point.created_at); + time_value = point.created_at; + console.log(time_value) + chart_pressure.data.datasets[0].data.push(point[var1]); + + // add the point + chart_flow.data.labels.push(point.created_at); + chart_flow.data.datasets[0].data.push(point[var1]); + + + chart_pressure.update(); + }, + cache: false + }); + // call it again after one second + setTimeout(requestChartVar1, 1000); +} + + + +$(document).ready(function() { + var ctx_pressure = document.getElementById('pressure_chart'); + chart_pressure = new Chart(ctx_pressure, { + type: 'line', + data: { + labels: [], + datasets: [{ + data: [], + label: "Var1", + borderColor: "#3e95cd", + fill: false + } + ] + }, + options: { + title: { + display: false, + text: 'Variable 1' + }, + scales: { + xAxes: [{ + time: { + unit: 'second', + displayFormat: 'second' + } + }] + }, + legend : { + display: false} + } + }); + requestChartVar1("pressure_buffer"); +}); + + +function requestChartVar2(var1) { + $.ajax({ + url: '/live-data', + success: function(point) { + + if(chart_flow.data.datasets[0].data.length > 10){ + chart_flow.data.labels.shift(); + chart_flow.data.datasets[0].data.shift(); + } + + + // add the point + chart_flow.data.labels.push(point.created_at); + chart_flow.data.datasets[0].data.push(point[var1]); + + + chart_flow.update(); + }, + cache: false + }); + // call it again after one second + setTimeout(requestChartVar2, 1000, var1); +} + + + +$(document).ready(function() { + var ctx_flow = document.getElementById('flow_chart'); + chart_flow = new Chart(ctx_flow, { + type: 'line', + data: { + labels: [], + datasets: [{ + data: [], + label: "Var1", + borderColor: "#3e95cd", + fill: false + } + ] + }, + options: { + title: { + display: false, + text: 'Variable 1' + }, + scales: { + xAxes: [{ + type: 'time', + time: { + unit: 'second', + displayFormat: 'second' + } + }] + }, + legend : { + display: false} + } + }); + requestChartVar2("pressure_inhale"); +}); + + +function requestChartVar3(var1) { + $.ajax({ + url: '/live-data', + success: function(point) { + + if(chart_volume.data.datasets[0].data.length > 10){ + chart_volume.data.labels.shift(); + chart_volume.data.datasets[0].data.shift(); + } + + + // add the point + chart_volume.data.labels.push(point.created_at); + chart_volume.data.datasets[0].data.push(point[var1]); + + + chart_volume.update(); + }, + cache: false + }); + // call it again after one second + setTimeout(requestChartVar3, 1000, var1); +} + + + +$(document).ready(function() { + var ctx_volume = document.getElementById('volume_chart'); + chart_volume = new Chart(ctx_volume, { + type: 'line', + data: { + labels: [], + datasets: [{ + data: [], + label: "Var1", + borderColor: "#3e95cd", + fill: false + } + ] + }, + options: { + title: { + display: false, + text: 'Variable 1' + }, + scales: { + xAxes: [{ + type: 'time', + time: { + unit: 'second', + displayFormat: 'second' + } + }] + }, + legend : { + display: false} + } + }); + requestChartVar3("temperature_buffer"); +}); + + diff --git a/raspberry-backend/static/js/Chart-plot.js b/raspberry-backend/static/js/Chart-plot.js index ffaaaca7d2dadc615219edb69626ca7b6b961dd7..0bb68001e9409768677c85384668445097d2b060 100644 --- a/raspberry-backend/static/js/Chart-plot.js +++ b/raspberry-backend/static/js/Chart-plot.js @@ -101,7 +101,8 @@ $(document).ready(function() { type: 'time', time: { unit: 'second', - displayFormat: 'second' + displayFormat: 'second', + type: 'realtime' }, ticks: { maxTicksLimit: 5, @@ -112,16 +113,29 @@ $(document).ready(function() { id: 'A', type: 'linear', position: 'left', + ticks: { + fontColor: "#0000FF", // this here + }, }, { - id: 'B', - type: 'linear', - position: 'right', - }] - }, - legend : { - display: true} - } - }); + id: 'B', + type: 'linear', + position: 'right', + ticks: { + fontColor: "#000000", // this here + }, + ticks: { + min: 0, + max: 200, + stepSize: 20 + } + } + ] + }, + legend : { + display: true + } + } + }); requestDataVar1("pressure_buffer", "pressure_inhale"); }); @@ -201,11 +215,20 @@ function updateChartType() { yAxes: [{ id: 'A', type: 'linear', - position: 'left', + position: 'left', + color: "#0000FF", + ticks: { + fontColor: "#0000FF", // this here + }, + }, { id: 'B', type: 'linear', - position: 'right', + position: 'right', + color: "#000000", + ticks: { + fontColor: "#000000", // this here + }, }] }, legend : { diff --git a/raspberry-backend/templates/base.html b/raspberry-backend/templates/base.html index 98781e077a5cb83c8054a06451139b29e874532c..1c5c5fe38818349ff7ec8c0497c8aa722a9f592b 100644 --- a/raspberry-backend/templates/base.html +++ b/raspberry-backend/templates/base.html @@ -30,7 +30,7 @@ <!-- User--> <ul class="navbar-nav ml-auto mr-0 mr-md-3 my-2 my-md-0"> <li class="nav-item dropdown"> - <i class="fas fa-user fa-fw"></i> + <!--<i class="fas fa-user fa-fw"></i>--> </li> <span class="patient">{{patient}}</span> </ul> @@ -73,6 +73,7 @@ <script src="{{ url_for('static', filename='js/moment.js') }}"></script> <script src="{{ url_for('static', filename='js/Chart.js') }}"></script> <script src="{{ url_for('static', filename='js/Chart-plot.js') }}"></script> + <script src="{{ url_for('static', filename='js/Chart-display.js') }}"></script> <script src="{{ url_for('static', filename='js/jquery.dataTables.min.js') }}"></script> <script src="{{ url_for('static', filename='js/dataTables.bootstrap4.min.js') }}"></script> diff --git a/raspberry-backend/templates/charts.html b/raspberry-backend/templates/charts.html index ef7a80ece90765e156e2adc32a96fe229baaed37..c284ddcb6a1067cc70e6674affbaf3141f4120ec 100644 --- a/raspberry-backend/templates/charts.html +++ b/raspberry-backend/templates/charts.html @@ -11,94 +11,34 @@ <div class = "row"> - <div class = "col-md-7 py-0"> + <div class = "col-md-10 py-0"> <div class="row"> <div class="col-md-12"> <div class="card mb-6"> - <div class="card-chart-header small ">Variable number 1</div> - <div class="card-body px-0 py-0"><canvas id="pressure_air_supply" width="200%" height="40"></canvas></div> + <div class="card-chart-header small ">Pressure [mbar]</div> + <div class="card-body px-0 py-0"><canvas id="pressure_chart" width="200%" height="30"></canvas></div> </div> </div> </div> <div class = "row"> <div class="col-md-12"> <div class="card mb-6 px-0 py-0"> - <div class="card-chart-header small">Variable number 2</div> - <div class="card-body px-0 py-0"><canvas id="variable2" width="200%" height="40"></canvas></div> + <div class="card-chart-header small">Flow [mL/min]</div> + <div class="card-body px-0 py-0"><canvas id="flow_chart" width="200%" height="30"></canvas></div> </div> </div> </div> <div class = "row"> <div class="col-md-12"> <div class="card mb-6 px-0 py-0"> - <div class="card-chart-header small ">Variable number 3</div> - <div class="card-body px-0 py-0"><canvas id="chart_variable3" width="200%" height="40"></canvas></div> + <div class="card-chart-header small ">Volume [mL]</div> + <div class="card-body px-0 py-0"><canvas id="volume_chart" width="200%" height="30"></canvas></div> </div> </div> </div> </div> - <div class = "col-md-5 py-0 px-0 mr-0"> - - <div class="row"> - - <div class="col-xl-5b px-1 py-0 mr-0"> - <div class="card bg-primary text-dark mb-2"> - <div class="card-header d-flex align-items-center justify-content-between"> - <a class="small text-dark stretched-link" href="#">Temperature</a> - </div> - <div class="card-body"><span class = "reading" id="temperature">000.00</span> ℃</div> - </div> - </div> - - <div class="col-xl-5b px-1 py-0 mr-0"> - <div class="card bg-primary text-dark mb-2"> - <div class="card-header d-flex align-items-center justify-content-between"> - <a class="small text-dark stretched-link" href="#">Pressure</a> - </div> - <div class="card-body"><span class = "reading" id = "pressure">000.00</span> Pa</div> - </div> - </div> - </div> - - <div class="row"> - <div class="col-xl-5b col-md-8 px-1 py-0"> - <div class="card bg-primary text-dark mb-2"> - <div class="card-header d-flex align-items-center justify-content-between"> - <a class="small text-dark stretched-link" href="#">variable3</a> - </div> - <div class="card-body"><span class = "reading" id = "variable3">000.00</span> ℃</div> - </div> - </div> - <div class="col-xl-5b px-1 py-0 col-md-8"> - <div class="card bg-primary text-dark mb-2"> - <div class="card-header d-flex align-items-center justify-content-between"> - <a class="small text-dark stretched-link" href="#">variable4</a> - </div> - <div class="card-body"><span class = "reading" id = "variable4">000.00</span> Pa</div> - </div> - </div> - </div> - - <div class="row"> - <div class="col-xl-5b col-md-8 px-1 py-0"> - <div class="card bg-primary text-dark mb-2"> - <div class="card-header d-flex align-items-center justify-content-between"> - <a class="small text-dark stretched-link" href="#">variable5</a> - </div> - <div class="card-body"><span class = "reading" id = "variable5">000.00</span> ℃</div> - </div> - </div> - <div class="col-xl-5b px-1 py-0 col-md-8"> - <div class="card bg-primary text-dark mb-2"> - <div class="card-header d-flex align-items-center justify-content-between"> - <a class="small text-dark stretched-link" href="#">variable6</a> - </div> - <div class="card-body"><span class = "reading" id = "variable6">000.00</span> Pa</div> - </div> - </div> - </div> - + </div> </div> </div> diff --git a/raspberry-backend/templates/index.html b/raspberry-backend/templates/index.html index 94422576786e4349c310f123f2841344e47020e4..40cdba3a6598133422a7bafa0fb0346cf528de58 100644 --- a/raspberry-backend/templates/index.html +++ b/raspberry-backend/templates/index.html @@ -11,31 +11,33 @@ <!--<h1 class="mt-4">Info</h1> !--> <div class = "row"> <div class = "col-md-7 py-0"> - <select id='chart_variables' multiple="multiple"> + <div class="row col-center pb-1"> + <select id='chart_variables' multiple="multiple" class="form-select"> <option value='pressure_buffer' selected>pressure_buffer</option> <option value='pressure_inhale' selected>pressure_inhale</option> <option value='temperature_buffer' selected>temperature_buffer</option> <option value='pressure_o2_regulated' selected>pressure_o2_regulated</option> - <input class="form-button py-0" type="button" value="Submit" onclick="updateChartType()" style="background-color: #1f4793 ; color: white"> </select> + <input class="form-button" type="button" value="Submit" onclick="updateChartType()"> + </div> <div class="row"> <div class="col-md-12"> <div class="card mb-6"> - <div class="card-chart-header small ">Plots</div> - <div class="card-body px-0 py-0"><canvas id="pressure_air_supply" width="100%" height="65px"></canvas></div> + <!--<div class="card-chart-header small ">Variable number 1</div>--> + <div class="card-body px-0 py-0"><canvas id="pressure_air_supply" width="100%" height="80px"></canvas></div> </div> </div> </div> </div> - <div class = "col-md-5 py-0 px-0 mr-0"> + <div class = "col-md-5 py-0 px-0 mr-0 pl-1"> <div class="row"> <div class="col-xl-4 px-1 py-0 mr-0"> <div class="card bg-primary text-dark mb-2"> - <div class="card-header d-flex align-items-center justify-content-between py-1"> - <a class="small text-dark stretched-link" href="#">Version</a> + <div class="card-header d-flex align-items-center justify-content-between py-1 min-height-1b"> + <a class="small text-dark stretched-link col-center" href="#">Version</a> </div> <div class="card-body px-1 py-3"><span class = "reading-main" id="version">000.00</span></div> </div> @@ -43,8 +45,8 @@ <div class="col-xl-4 px-1 py-0 mr-0"> <div class="card bg-primary text-dark mb-2"> - <div class="card-header d-flex align-items-center justify-content-between py-1"> - <a class="small text-dark stretched-link" href="#">fsm_state</a> + <div class="card-header d-flex align-items-center justify-content-between py-1 min-height-1b"> + <a class="small text-dark stretched-link col-center" href="#">fsm_state</a> </div> <div class="card-body px-1 py-3"><span class = "reading-main" id = "fsm_state">000.00</span> </div> </div> @@ -52,8 +54,8 @@ <div class="col-xl-4 col-md-8 px-1 py-0"> <div class="card bg-primary text-dark mb-2"> - <div class="card-header d-flex align-items-center justify-content-between py-1"> - <a class="small text-dark stretched-link" href="#">pressure_buffer</a> + <div class="card-header d-flex align-items-center justify-content-between py-1 min-height-1b"> + <a class="small text-dark stretched-link col-center" href="#">pressure_buffer</a> </div> <div class="card-body px-1 py-3"><span class = "reading-main" id = "pressure_buffer">000.00</span> Pa</div> </div> @@ -63,24 +65,24 @@ <div class="row"> <div class="col-xl-4 px-1 py-0 col-md-5"> <div class="card bg-primary text-dark mb-2"> - <div class="card-header d-flex align-items-center justify-content-between py-1"> - <a class="small text-dark stretched-link" href="#">pressure_inhale</a> + <div class="card-header d-flex align-items-center justify-content-between py-1 min-height-1b"> + <a class="small text-dark stretched-link col-center" href="#">pressure_inhale</a> </div> <div class="card-body px-1 py-3"><span class = "reading-main" id = "pressure_inhale">000.00</span> Pa</div> </div> </div> <div class="col-xl-4 col-md-8 px-1 py-0"> <div class="card bg-primary text-dark mb-2"> - <div class="card-header d-flex align-items-center justify-content-between py-1"> - <a class="small text-dark stretched-link" href="#">temperature_buffer</a> + <div class="card-header d-flex align-items-center justify-content-between py-1 min-height-1b"> + <a class="small text-dark stretched-link col-center" href="#">temperature_buffer</a> </div> <div class="card-body px-1 py-3"><span class = "reading-main" id = "temperature_buffer">000.00</span> ℃</div> </div> </div> <div class="col-xl-4 px-1 py-0 col-md-8"> <div class="card bg-primary text-dark mb-2"> - <div class="card-header d-flex align-items-center justify-content-between py-1"> - <a class="small text-dark stretched-link" href="#">pressure_o2_regulated</a> + <div class="card-header d-flex align-items-center justify-content-between py-1 small min-height-1b"> + <a class="small text-dark stretched-link col-center" href="#">pressure_o2_regulated</a> </div> <div class="card-body px-1 py-3"><span class = "reading-main" id = "pressure_o2_regulated">000.00</span> Pa</div> </div> @@ -90,9 +92,9 @@ <div class="row no-gutters w-100"> <form action="{{ url_for('data_handler') }}" method="post" class="w-95"> <div class="card rounded-lg small px-0"> - <div class="card-header align-items-center justify-content-between px-1 py-1"> - INPUTS - <div class = "float-right"><a class="unlock thresholds" id="toggle_thresholds" onclick="toggle_lock_settings()"> + <div class="card-header align-items-center justify-content-between pl-3 pr-1 py-1"> + Settings + <div class = "float-right mr-1"><a class="unlock thresholds" id="toggle_thresholds" onclick="toggle_lock_settings()"> <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="lock" class="svg-inline--fa fa-lock fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"> <path class="path-icon" id = "path-locked" d="M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"></path> <path class="path-icon transparent" id="path-unlocked" d="M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"></path> @@ -102,22 +104,22 @@ </div> <div class="card-body px-1 py-1"> <table class="text-align-right py-0 my-0 small"> - <tr class="py-0"> + <tr class=""> <td><span class=""><label class="small" for="inputInhale">Inhale Time (ms): </label><input class="form-control" id="inputThres1" type="number" value=1 max=100 min=0 name="" readOnly onclick="show_easy_numpad_wrapper(this);"/></span></td> <td><span class="form-group"><label class="small" for="inputFill">Fill Time (ms): </label><input class="form-control" id="inputFill" type="number" value=1 name="variable1" readOnly min=0 max = 100 onclick="show_easy_numpad_wrapper(this);"/></span></td> <td><span class="form-group"><label class="small" for="inputPause">Pause (ms): </label><input class="form-control" id="inputPause" type="number" value=1 name="variable1" readOnly min=0 max=100 onclick="show_easy_numpad_wrapper(this);"/></span></td> <td></td> </tr> - <tr class="py-0"> - <td><span class="form-group"> <br> <label class="small" for="inputExhale">Exhale/Inhale: </label><input class="form-control lh-1" id="inputExInhale" type="number" value=1 max=100 min=0 name="" readOnly onclick="show_easy_numpad_wrapper(this);"/></span></td> - <td><span class="form-group"> <br> <label class="small" for="inputVar1">PEEP (cmH2O): </label><input class="form-control" id="inputPEEP" type="number" value=1 name="inputPEEP" readOnly min=0 max = 100 /></span></td> - <td><span class="form-group"> <br> <label class="small" for="inputVar1">Exhale Time (ms): </label><input class="form-control" id="inputExhaleTime" type="number" value=1 name="variable1" readOnly min=0 max=100 /></span></td> - <td><span class="form-group"> <br> <label class="small" for="inputVar1">RPM: </label><input class="form-control" id="inputRPM" type="number" value=1 name="variable1" readOnly min=0 max=100 onclick="show_easy_numpad_wrapper(this);" /></span></td> + <tr class=""> + <td><span class="form-group"> <label class="small" for="inputExhale">Exhale/Inhale: </label><input class="form-control lh-1" id="inputExInhale" type="number" value=1 max=100 min=0 name="" readOnly onclick="show_easy_numpad_wrapper(this);"/></span></td> + <td><span class="form-group"> <label class="small" for="inputVar1">PEEP (cmH2O): </label><input class="form-control" id="inputPEEP" type="number" value=1 name="inputPEEP" readOnly min=0 max = 100 /></span></td> + <td><span class="form-group"> <label class="small" for="inputVar1">Exhale Time (ms): </label><input class="form-control" id="inputExhaleTime" type="number" value=1 name="variable1" readOnly min=0 max=100 /></span></td> + <td><span class="form-group"> <label class="small" for="inputVar1">RPM: </label><input class="form-control" id="inputRPM" type="number" value=1 name="variable1" readOnly min=0 max=100 onclick="show_easy_numpad_wrapper(this);" /></span></td> </tr> </table> </div> - <div class="card-footer px-0 py-0 align-items-center"> - <span class="form-group ml-auto mr-auto"><input class="form-button py-0" id="form_submit" type="submit" value="Update Setting" style="background-color: #1f4793 ; color: white" disabled /></span> + <div class="card-footer px-0 py-0"> + <div class="col-center"><input class="form-button float-right" id="form_submit" type="submit" value="Update" disabled /></div> </div> </div> </form> @@ -125,7 +127,7 @@ <div class = "row no-gutters ml-auto mr-auto py-2"> <a> <button class="sb-control-button py-3 rounded-lg mr-1">INHALE</button></a> - <a> <button class="sb-control-button py-1 rounded-lg ml-1">EXHALE</button></a> + <a> <button class="sb-control-button sb-control-button-pressed py-1 rounded-lg ml-1">EXHALE</button></a> </div> </div> </div> @@ -142,8 +144,13 @@ var i; if ( x.length > 0 && x[0].readOnly == true ){ for (i = 0; i < x.length; i++) { - if (x[i].id != "form_submit"){x[i].readOnly = false;} - else{ x[i].disabled=false; } + if (x[i].id != "form_submit"){ + x[i].readOnly = false; + } + else{ + x[i].disabled=false; + + } var submit = document.getElementById("form_submit"); submit.disabled=false; } @@ -155,8 +162,10 @@ } else{ for (i = 0; i < x.length; i++ ) { - if (x[i].id != "form_submit"){x[i].readOnly = true;} - else {x[i].disabled=true;} + if (x[i].id != "form_submit"){ + x[i].readOnly = true; + } + else {x[i].disabled=true; } var submit = document.getElementById("form_submit"); diff --git a/raspberry-backend/templates/settings.html b/raspberry-backend/templates/settings.html index bc6762d2cd228669981ada6a4be1aee0d860f6b6..c6bd2373389171a7209705473da331375231ddf7 100644 --- a/raspberry-backend/templates/settings.html +++ b/raspberry-backend/templates/settings.html @@ -7,9 +7,11 @@ <div class="row justify-content-center"> <div class="card rounded-lg px-0 py-0 my-1"> <div class="card-header px-1 py-1">Personal Details - <div class="float-right"><a class="unlock personal" id="toggle_personal" onclick="toggle_lock_personal()"> + <div class="float-right mr-1"><a class="unlock personal" id="toggle_personal" onclick="toggle_lock_personal()"> <svg aria-hidden="true" id="personal_lock" focusable="false" data-prefix="fas" data-icon="lock" class="svg-inline--fa fa-lock fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"> - <path class="path-icon" d="M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"></path> + <path class="path-icon" id = "path-locked-details" d="M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"></path> + <path class="path-icon transparent" id="path-unlocked-details" d="M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"></path> + </svg> </a></div> </div> @@ -26,9 +28,10 @@ <div class="card rounded-lg px-0 py-0"> <div class="card-header px-1 py-1"> Thresholds - <div class = "float-right"><a class="unlock thresholds" id="toggle_thresholds" onclick="toggle_lock_thresholds()"> - <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="lock" class="svg-inline--fa fa-lock fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"> - <path class="path-icon" d="M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"></path> + <div class = "float-right mr-1"><a class="unlock thresholds" id="toggle_thresholds" onclick="toggle_lock_thresholds()"> + <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="lock" class="svg-inline--fa fa-lock fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"> + <path class="path-icon" id = "path-locked-thresholds" d="M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"></path> + <path class="path-icon transparent" id="path-unlocked-thresholds" d="M400 256H152V152.9c0-39.6 31.7-72.5 71.3-72.9 40-.4 72.7 32.1 72.7 72v16c0 13.3 10.7 24 24 24h32c13.3 0 24-10.7 24-24v-16C376 68 307.5-.3 223.5 0 139.5.3 72 69.5 72 153.5V256H48c-26.5 0-48 21.5-48 48v160c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"></path> </svg> </a> </div> @@ -57,7 +60,7 @@ </div> </div> <div class="row justify-content-center"> - <span class="form-group" ><input class="form-control py-0" style="background-color: #1f4793 ; color: white" id="inputPassword" type="submit" value="Submit Changes" /></span> + <span class="form-group" ><input class="form-button py-0" id="inputPassword" type="submit" value="Submit Changes" /></span> </div> </form> </div> @@ -66,20 +69,34 @@ {% block scripts %} <script type=text/javascript> function toggle_lock_personal() { + setTimeout(function(){ if ( document.getElementById("inputName").readOnly == true){ document.getElementById("inputName").readOnly = false; document.getElementById("inputAge").readOnly = false; document.getElementById("inputWeight").readOnly = false; document.getElementById("inputHeight").readOnly = false; + var el = document.getElementById("path-unlocked-details"); + el.classList.remove("transparent"); + var el2 = document.getElementById("path-locked-details"); + el2.classList.add("transparent"); + } else { document.getElementById("inputName").readOnly = true; document.getElementById("inputAge").readOnly = true; document.getElementById("inputWeight").readOnly = true; document.getElementById("inputHeight").readOnly = true; + var el = document.getElementById("path-unlocked-details"); + el.classList.add("transparent"); + var el2 = document.getElementById("path-locked-details"); + el2.classList.remove("transparent"); + } - } + },500)} + + function toggle_lock_thresholds() { + setTimeout(function(){ if ( document.getElementById("pressure_air_supply").readOnly == true){ document.getElementById("pressure_air_supply").readOnly = false; document.getElementById("pressure_air_regulated").readOnly = false; @@ -94,7 +111,11 @@ document.getElementById("readback_valve_scavenge").readOnly = false; document.getElementById("readback_valve_purge").readOnly = false; document.getElementById("readback_mode").readOnly = false; - + var el = document.getElementById("path-unlocked-thresholds"); + el.classList.remove("transparent"); + var el2 = document.getElementById("path-locked-thresholds"); + el2.classList.add("transparent"); + } else { document.getElementById("pressure_air_supply").readOnly = true; @@ -110,8 +131,13 @@ document.getElementById("readback_valve_scavenge").readOnly = true; document.getElementById("readback_valve_purge").readOnly = true; document.getElementById("readback_mode").readOnly = true; + var el = document.getElementById("path-unlocked-thresholds"); + el.classList.add("transparent"); + var el2 = document.getElementById("path-locked-thresholds"); + el2.classList.remove("transparent"); + } - } + },500)} </script> diff --git a/raspberry-dataserver/README.md b/raspberry-dataserver/README.md index fe20b30612c7fe90093ce29a14940258ad48c9e2..3647b57739f0aec9329bbe87c1377e8dc37500f7 100644 --- a/raspberry-dataserver/README.md +++ b/raspberry-dataserver/README.md @@ -73,7 +73,7 @@ Example broadcast packet: "readback_mode": 0 }, "alarms": [ - "ALARM_START" + "APNEA" ] } ``` @@ -82,7 +82,7 @@ Example alarm packet: ```json { “typeâ€: “alarmâ€, - “alarmsâ€: [‘apnea’] + “alarmsâ€: [‘APNEA’] } ``` @@ -153,4 +153,4 @@ for i in range(10): print(f"Values: {json.dumps(hevclient.get_values(), indent=4)}") print(f"Alarms: {hevclient.get_alarms()}") time.sleep(1) -``` \ No newline at end of file +``` diff --git a/raspberry-dataserver/commsConstants.py b/raspberry-dataserver/commsConstants.py index cb4ca0078dd7127179022d894ad7038936f62cd3..b99267f7334dd5d1b41e79173ac2ca966e5754fd 100644 --- a/raspberry-dataserver/commsConstants.py +++ b/raspberry-dataserver/commsConstants.py @@ -289,5 +289,29 @@ class alarmFormat(BaseFormat): @unique class alarm_codes(Enum): - ALARM_START = 1 - ALARM_STOP = 2 \ No newline at end of file + # Taken from safety doc. Correct as of 1400 on 20200416 + APNEA = 1 # HP + CHECK_VALVE_EXHALE = 2 # HP + CHECK_P_PATIENT = 3 # HP + EXPIRATION_SENSE_FAULT_OR_LEAK = 4 # MP + EXPIRATION_VALVE_LEAK = 5 # MP + HIGH_FIO2 = 6 # MP + HIGH_PRESSURE = 7 # HP + HIGH_RR = 8 # MP + HIGH_VTE = 9 # MP + LOW_VTE = 10 # MP + HIGH_VTI = 11 # MP + LOW_VTI = 12 # MP + INTENTIONAL_STOP = 13 # HP + LOW_BATTERY = 14 # HP (LP) if AC power isn't (is) connected + LOW_FIO2 = 15 # HP + OCCLUSION = 16 # HP + HIGH_PEEP = 17 # HP + LOW_PEEP = 18 # HP + AC_POWER_DISCONNECTION = 19 # MP + BATTERY_FAULT_SRVC = 20 # MP + BATTERY_CHARGE = 21 # MP + AIR_FAIL = 22 # HP + O2_FAIL = 23 # HP + PRESSURE_SENSOR_FAULT = 24 # HP + ARDUINO_FAIL = 25 # HP diff --git a/raspberry-dataserver/hevclient.py b/raspberry-dataserver/hevclient.py index cec4717403e1eafbaf73565a23b92e67733f11b3..a3f9dfa5f083e768d2645a04c1ab82bc8ce7d09b 100755 --- a/raspberry-dataserver/hevclient.py +++ b/raspberry-dataserver/hevclient.py @@ -37,8 +37,11 @@ class HEVClient(object): # grab data from the socket as soon as it is available and dump it in the db while self._polling: - data = await reader.read(500) - payload = json.loads(data.decode("utf-8")) + data = await reader.read(600) + try: + payload = json.loads(data.decode("utf-8")) + except json.decoder.JSONDecodeError: + logging.warning(f"Could not decode packet: {data}") with self._lock: self._values = payload["sensors"] self._alarms = payload["alarms"] @@ -50,15 +53,21 @@ class HEVClient(object): def start_client(self) -> None: asyncio.run(self.polling()) - async def send_request(self, cmd: str, param: str=None) -> bool: + async def send_request(self, reqtype, cmd: str=None, param: str=None, alarm: str=None) -> bool: # open connection and send packet reader, writer = await asyncio.open_connection("127.0.0.1", 54321) - payload = { - "type": "cmd", - "cmd": cmd, - "param": param - } + if reqtype == "cmd": + payload = { + "type": "cmd", + "cmd": cmd, + "param": param + } + elif reqtype == "alarm": + payload = { + "type": "alarm", + "ack": alarm + } packet = json.dumps(payload).encode() @@ -67,7 +76,10 @@ class HEVClient(object): # wait for acknowledge data = await reader.read(300) - data = json.loads(data.decode("utf-8")) + try: + data = json.loads(data.decode("utf-8")) + except json.decoder.JSONDecodeError: + logging.warning(f"Could not decode packet: {data}") # close connection to free up socket writer.close() @@ -75,15 +87,19 @@ class HEVClient(object): # check that acknowledge is meaningful if data["type"] == "ack": - logging.info(f"Command {cmd} sent successfully") + logging.info(f"Request type {reqtype} sent successfully") return True else: - logging.warning(f"Sending command {cmd} failed") + logging.warning(f"Request type {reqtype} failed") return False def send_cmd(self, cmd: str, param: str=None) -> bool: # send a cmd and wait to see if it's valid - return asyncio.run(self.send_request(cmd)) + return asyncio.run(self.send_request("cmd", cmd=cmd, param=param)) + + def ack_alarm(self, alarm: str) -> bool: + # acknowledge alarm to remove it from the hevserver list + return asyncio.run(self.send_request("alarm", alarm=alarm)) def get_values(self) -> Dict: # get sensor values from db @@ -101,7 +117,7 @@ if __name__ == "__main__": # Play with sensor values and alarms - for i in range(30): + for i in range(20): values = hevclient.get_values() # returns a dict or None alarms = hevclient.get_alarms() # returns a list of alarms currently ongoing if values is None: @@ -110,6 +126,15 @@ if __name__ == "__main__": print(f"Values: {json.dumps(values, indent=4)}") print(f"Alarms: {alarms}") time.sleep(1) + + # acknowledge the oldest alarm + try: + hevclient.ack_alarm(alarms[0]) # blindly assume we have one after 40s + except: + logging.info("No alarms received") + + time.sleep(1) + print(f"Alarms: {hevclient.get_alarms()}") # send commands: print(hevclient.send_cmd("CMD_START")) @@ -119,7 +144,6 @@ if __name__ == "__main__": # print some more values for i in range(10): - print(f"Alarms: {hevclient.get_alarms()}") print(f"Values: {json.dumps(hevclient.get_values(), indent=4)}") print(f"Alarms: {hevclient.get_alarms()}") time.sleep(1) diff --git a/raspberry-dataserver/hevfromtxt.py b/raspberry-dataserver/hevfromtxt.py new file mode 100755 index 0000000000000000000000000000000000000000..8d5769b6cc37570827ac1b63400d602c28940977 --- /dev/null +++ b/raspberry-dataserver/hevfromtxt.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +# simple txt filereader frontend for HEVserver +# currently dedicated to very specific file format matching victor's sample.txt +# author Dónal Murray <donal.murray@cern.ch> + +import threading +import commsConstants +import time +import numpy as np +from typing import List +from collections import deque +import logging +logging.basicConfig(level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s') + + +class hevfromtxt(): + def __init__(self, inputFile): + # use input file for testing + h = np.loadtxt(inputFile,skiprows = 1, delimiter = ',') + self._pressure = h[:,1].tolist() + self._flow = h[:,2].tolist() + self._volume = h[:,3].tolist() + self._length = len(self._pressure) + self._pos = 0 # position within sample + + # received queue and observers to be notified on update + self._payloadrecv = deque(maxlen = 16) + self._observers = [] + sendingWorker = threading.Thread(target=self.generate, daemon=True) + sendingWorker.start() + + def generate(self) -> None: + while True: + # grab next array from filedump + self._pos = self._pos + 1 if self._pos + 1 < self._length else 0 + payload = commsConstants.dataFormat() + + # directly setting private member variables in this edge case + payload._version = payload._RPI_VERSION + payload._pressure_buffer = self._pressure[self._pos] + payload._pressure_inhale = self._volume[self._pos] + payload._temperature_buffer = self._flow[self._pos] + + self.payloadrecv = payload + time.sleep(1) + + # callback to dependants to read the received payload + @property + def payloadrecv(self): + return self._payloadrecv + + @payloadrecv.setter + def payloadrecv(self, payload): + self._payloadrecv.append(payload) + logging.debug(f"Pushed {payload} to FIFO") + for callback in self._observers: + # peek at the leftmost item, don't pop until receipt confirmed + callback(self._payloadrecv[0]) + + def writePayload(self, payload): + logging.info(payload) + + def bind_to(self, callback): + self._observers.append(callback) + + def pop_payloadrecv(self): + # from callback. confirmed receipt, pop value + poppedval = self._payloadrecv.popleft() + logging.debug(f"Popped {poppedval} from FIFO") + if len(self._payloadrecv) > 0: + # purge full queue if Dependant goes down when it comes back up + for callback in self._observers: + callback(self._payloadrecv[0]) \ No newline at end of file diff --git a/raspberry-dataserver/hevserver.py b/raspberry-dataserver/hevserver.py index 332834bb8bf0eeeca21d4f4de005daed83180405..61fdd92d59256fa31fefcf45f860d183a027a3ff 100755 --- a/raspberry-dataserver/hevserver.py +++ b/raspberry-dataserver/hevserver.py @@ -9,13 +9,14 @@ import time import threading import argparse import svpi +import hevfromtxt import commsControl from commsConstants import payloadType, command_codes, alarm_codes, commandFormat from collections import deque from serial.tools import list_ports from typing import List import logging -logging.basicConfig(level=logging.INFO, +logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') class HEVPacketError(Exception): @@ -46,34 +47,38 @@ class HEVServer(object): logging.debug(f"Payload received: {payload!r}") # check if it is data or alarm payload_type = payload.getType() - if payload_type == payloadType.payloadData: + if payload_type == payloadType.payloadAlarm: + # Alarm is latched until acknowledged in GUI + alarm_packet = payload.getDict() + alarmCode = alarm_packet["alarmCode"] + with self._dblock: + try: + alarm = alarm_codes(alarmCode).name + except ValueError as e: + # alarmCode does not exist in the enum, this is serious! + logging.error(e) + self._alarms.append("ARDUINO_FAIL") # assume Arduino is broken + if alarm not in self._alarms: + self._alarms.append(alarm) + # let broadcast thread know there is data to send + with self._dvlock: + self._datavalid.set() + elif payload_type == payloadType.payloadData: # pass data to db with self._dblock: self._values = payload.getDict() - elif payload_type == payloadType.payloadAlarm: - alarm_map = { - 0: "manual", - 1: "gas supply", - 2: "apnea", - 3: "expired minute volume", - 4: "upper pressure limit", - 5: "power failure", - } - new_alarm = payload.getDict() - param = new_alarm["param"] - if new_alarm["alarmCode"] == 2: - # alarm stop, delete from list - with self._dblock: - self._alarms.remove(alarm_map[param]) - - elif new_alarm["alarmCode"] == 1: - # alarm start, add to list - with self._dblock: - self._alarms.append(alarm_map[param]) - - # let broadcast thread know there is data to send - with self._dvlock: - self._datavalid.set() + # let broadcast thread know there is data to send + with self._dvlock: + self._datavalid.set() + elif payload_type == payloadType.payloadCmd: + # ignore for the minute + pass + elif payload_type == payloadType.payloadUnset: + # ignore for the minute + pass + else: + # invalid packet, don't throw exception just log and pop + logging.error("Received invalid packet, ignoring") # pop from lli queue self._lli.pop_payloadrecv() @@ -100,20 +105,36 @@ class HEVServer(object): self._lli.writePayload(command) # processed and sent to controller, send ack to GUI since it's in enum - # TODO should we wait for ack from controller or is that going to block the port for too long? payload = {"type": "ack"} else: - raise HEVPacketError("Invalid command packet") + raise HEVPacketError(f"Invalid command packet. Command {reqcmd} does not exist.") - packet = json.dumps(payload).encode() + elif reqtype == "broadcast": + # ignore for the minute + pass + elif reqtype == "alarm": + # acknowledgement of alarm from gui + try: + # delete alarm if it exists + with self._dblock: + self._alarms.remove(request["ack"]) + payload = {"type": "ack"} + except NameError as e: + raise HEVPacketError(f"Alarm could not be removed. May have been removed already. {e}") + else: + raise HEVPacketError(f"Invalid request type") + + packet = json.dumps(payload).encode() + + # send reply and close connection + writer.write(packet) + await writer.drain() + writer.close() + - # send reply and close connection - writer.write(packet) - await writer.drain() - writer.close() except (NameError, HEVPacketError) as e: # invalid request: reject immediately - logging.warning(f"Invalid command packet. Type {reqtype} does not exist") + logging.warning(e) payload = {"type": "nack"} packet = json.dumps(payload).encode() writer.write(packet) @@ -201,8 +222,14 @@ if __name__ == "__main__": # check if input file was specified if args.inputFile != '': - # initialise frond end generator from file - lli = svpi.svpi(args.inputFile) + if args.inputFile[-1-3:] == '.txt': + # assume sample.txt format + lli = hevfromtxt.hevfromtxt(args.inputFile) + else: + # assume hex dump + lli = svpi.svpi(args.inputFile) + + logging.info(f"Serving data from {args.inputFile}") else: # get arduino serial port for port in list_ports.comports(): @@ -218,8 +245,9 @@ if __name__ == "__main__": # initialise low level interface try: lli = commsControl.commsControl(port=port_device) + logging.info(f"Serving data from device {port_device}") except NameError: - print("Arduino not connected") + logging.error("Arduino not connected") exit(1) hevsrv = HEVServer(lli) diff --git a/raspberry-dataserver/share/sample.txt b/raspberry-dataserver/share/sample.txt new file mode 100644 index 0000000000000000000000000000000000000000..3cd0eb8183c9bc49555de9f405323d7241cd2277 --- /dev/null +++ b/raspberry-dataserver/share/sample.txt @@ -0,0 +1,2000 @@ +time [s],pressure [mbar],flow [mL/min],volume [mL]20.000000,20.228397,723.944000,168.848192 +20.020000,19.979979,593.139000,180.397558 +20.040000,20.160113,597.387000,190.336158 +20.060000,20.360799,628.680000,200.293933 +20.080000,20.661909,678.448000,211.006967 +20.100000,20.756000,606.170000,220.793742 +20.120000,20.920458,390.991000,228.273442 +20.140000,21.112902,511.218000,236.728333 +20.160000,21.079143,429.125000,244.073800 +20.180000,21.331640,404.394000,250.214333 +20.200000,21.584712,386.755000,256.317942 +20.220000,21.228645,386.755000,262.548508 +20.240000,20.973719,343.957000,267.706483 +20.260000,20.850532,233.471000,271.857167 +20.280000,20.821091,134.594000,274.374142 +20.300000,20.856566,171.289000,276.628975 +20.320000,20.710081,84.240000,278.158400 +20.340000,20.351695,142.480000,280.183642 +20.360000,20.190519,13.977000,280.738342 +20.380000,20.317494,-13.977000,280.621867 +20.400000,20.402341,0.000000,280.896008 +20.420000,20.299220,18.750000,280.778117 +20.440000,20.290970,-32.897000,280.027500 +20.460000,19.968840,-14.160000,279.909500 +20.480000,19.900750,-13.989000,279.590600 +20.500000,20.058468,0.000000,279.472708 +20.520000,19.950198,32.885000,278.878225 +20.540000,19.857209,-0.000000,278.878225 +20.560000,19.711200,-0.000000,278.878225 +20.580000,19.607930,-0.000000,278.878225 +20.600000,19.813832,-32.885000,278.604183 +20.620000,19.838228,-15.026000,278.478967 +20.640000,19.673731,-88.989000,278.011333 +20.660000,19.651667,-15.222000,278.158425 +20.680000,19.686832,32.861000,278.158425 +20.700000,19.698553,18.872000,278.041850 +20.720000,19.706918,-140.368000,276.754225 +20.740000,19.731188,-47.900000,276.355058 +20.760000,19.702408,-87.048000,275.903600 +20.780000,19.531938,-47.888000,275.778375 +20.800000,19.465998,-32.861000,275.778375 +20.820000,19.406926,-32.849000,275.201600 +20.840000,19.197777,-69.213000,274.499500 +20.860000,19.275906,-69.213000,273.797400 +20.880000,19.234650,-35.302000,273.377892 +20.900000,19.096565,0.000000,273.377892 +20.920000,18.864842,0.000000,273.377892 +20.940000,18.790842,0.000000,273.377892 +20.960000,18.873369,0.000000,273.252567 +20.980000,18.712105,-116.015000,271.717850 +21.000000,18.715961,-67.077000,271.298233 +21.020000,18.856057,0.000000,271.163958 +21.040000,18.965929,-0.000000,270.197167 +21.060000,18.810841,-0.000000,269.638092 +21.080000,18.890125,-32.824000,269.504017 +21.100000,18.817377,16.528000,269.227225 +21.120000,18.728163,-0.000000,268.819617 +21.140000,18.677874,-17.358000,268.399800 +21.160000,18.571619,-65.856000,267.851000 +21.180000,18.421567,-32.812000,267.433125 +21.200000,18.443848,-32.812000,267.433125 +21.220000,18.213442,-17.333000,267.022267 +21.240000,18.243235,0.000000,266.748833 +21.260000,18.151569,-17.333000,266.337875 +21.280000,18.357209,15.441000,265.653358 +21.300000,15.636869,-30.932000,264.437958 +21.320000,11.415353,-225.671000,261.872967 +21.340000,10.940012,-620.373000,252.651375 +21.360000,10.903003,-790.795000,239.949158 +21.380000,10.975626,-687.133000,228.885633 +21.400000,10.895289,-587.646000,218.749433 +21.420000,10.750558,-396.392000,211.007083 +21.440000,9.699567,-421.258000,204.579025 +21.460000,8.955133,-345.678000,198.853025 +21.480000,8.734896,-544.415000,190.788050 +21.500000,8.695677,-595.251000,182.512808 +21.520000,8.927868,-455.816000,174.466350 +21.540000,8.658927,-304.785000,168.396917 +21.560000,8.417623,-420.208000,162.104508 +21.580000,7.993768,-367.016000,156.236092 +21.600000,7.869097,-342.492000,150.220375 +21.620000,7.945444,-332.763000,144.053292 +21.640000,7.515314,-366.748000,137.895100 +21.660000,7.475062,-309.259000,132.179467 +21.680000,7.409641,-288.934000,126.804517 +21.700000,7.070832,-295.471000,121.830258 +21.720000,7.043467,-311.157000,116.499758 +21.740000,6.898745,-279.834000,111.715167 +21.760000,6.629780,-215.563000,107.533658 +21.780000,6.285800,-111.901000,105.071617 +21.800000,5.862454,-224.798000,101.515408 +21.820000,5.689838,-194.799000,98.532125 +21.840000,5.431273,-230.096000,95.510692 +21.860000,5.392768,-231.365000,92.600042 +21.880000,5.237240,-101.861000,89.837092 +21.900000,5.074434,-51.086000,87.612517 +21.920000,4.826814,-154.357000,85.047217 +21.940000,4.639076,-155.578000,82.520267 +21.960000,4.633274,-158.776000,80.484758 +21.980000,4.615462,-159.832000,78.450725 +22.000000,4.406277,-118.035000,76.736975 +22.020000,4.151825,-42.864000,75.651175 +22.040000,3.958585,-182.794000,73.397767 +22.060000,3.782760,-56.872000,72.193758 +22.080000,3.882597,-77.697000,70.807250 +22.100000,3.864984,-89.562000,69.058500 +22.120000,3.565133,-57.965000,67.926558 +22.140000,3.571569,-79.833000,66.603483 +22.160000,3.535429,0.000000,65.945633 +22.180000,3.208012,-9.735000,65.188958 +22.200000,3.380643,-82.122000,63.839383 +22.220000,3.357284,-71.331000,63.172583 +22.240000,3.287322,-82.116000,62.144100 +22.260000,3.200826,-113.513000,61.461167 +22.280000,3.132928,-50.567000,61.039775 +22.300000,3.172961,-51.635000,60.346525 +22.320000,3.110110,-8.673000,60.274250 +22.340000,3.288410,-8.673000,59.589850 +22.360000,3.159224,-31.542000,59.327000 +22.380000,2.705475,-31.542000,59.327000 +22.400000,2.649752,-31.536000,58.697183 +22.420000,2.636296,-7.611000,58.633758 +22.440000,2.644524,-44.036000,58.266792 +22.460000,2.600843,-52.722000,57.564692 +22.480000,2.669675,-83.197000,56.808017 +22.500000,2.827807,-7.611000,55.843208 +22.520000,2.754957,25.146000,55.403808 +22.540000,2.895870,31.512000,54.754800 +22.560000,3.017855,-31.512000,54.492200 +22.580000,2.751070,31.512000,54.701650 +22.600000,2.552865,31.512000,54.052742 +22.620000,2.710701,-110.449000,53.079183 +22.640000,2.508606,-111.505000,52.368275 +22.660000,2.629563,0.000000,52.630775 +22.680000,2.746066,-0.000000,51.910975 +22.700000,2.635611,-143.005000,51.244267 +22.720000,2.807802,0.000000,51.723492 +22.740000,2.700070,-62.994000,51.198542 +22.760000,2.803283,-148.309000,49.813458 +22.780000,3.115083,0.000000,49.551117 +22.800000,9.068745,-0.000000,49.551117 +22.820000,16.566412,306.567000,53.079192 +22.840000,18.301080,956.378000,66.603608 +22.860000,19.601962,1189.776000,85.923367 +22.880000,18.569086,1079.132000,104.644625 +22.900000,18.068824,853.503000,120.179083 +22.920000,17.655458,586.553000,130.849800 +22.940000,18.459882,420.178000,138.979675 +22.960000,19.464120,500.183000,147.217225 +22.980000,20.284224,827.441000,159.027008 +23.000000,20.181561,758.416000,171.658475 +23.020000,20.179198,679.650000,182.956425 +23.040000,20.371325,565.026000,192.912217 +23.060000,20.431404,573.822000,202.959567 +23.080000,20.751765,600.567000,214.491442 +23.100000,20.719102,542.456000,223.646867 +23.120000,20.920561,447.302000,231.434950 +23.140000,21.423813,473.144000,239.392708 +23.160000,21.397025,460.974000,247.375900 +23.180000,21.028528,452.221000,254.819633 +23.200000,21.080265,278.051000,259.848008 +23.220000,21.462409,260.656000,265.114008 +23.240000,21.141733,198.974000,269.912075 +23.260000,21.045216,300.231000,274.493867 +23.280000,21.190455,102.783000,276.754708 +23.300000,21.061955,100.549000,279.544825 +23.320000,20.650709,85.314000,281.561317 +23.340000,20.420947,138.195000,282.875700 +23.360000,20.391786,0.000000,282.875700 +23.380000,20.377285,-0.000000,282.327300 +23.400000,20.450093,-72.387000,281.724075 +23.420000,20.177233,-12.927000,281.616350 +23.440000,20.203211,-0.000000,281.616350 +23.460000,20.132921,-72.399000,281.013025 +23.480000,19.921695,0.000000,280.896550 +23.500000,19.944963,-0.000000,280.896550 +23.520000,19.981460,-32.897000,280.622408 +23.540000,19.911687,0.000000,280.896550 +23.560000,20.140581,-32.897000,280.622408 +23.580000,20.020563,0.000000,280.896550 +23.600000,20.000292,-32.897000,280.028033 +23.620000,20.022962,0.000000,280.302175 +23.640000,19.828950,-32.897000,279.910033 +23.660000,19.855669,-32.885000,279.317083 +23.680000,19.719556,-14.147000,279.473233 +23.700000,19.834143,-71.337000,278.878758 +23.720000,19.813775,-80.798000,278.753433 +23.740000,19.712316,-65.759000,278.753433 +23.760000,19.633417,-80.969000,278.158950 +23.780000,19.835239,-70.275000,278.004742 +23.800000,19.762503,-87.023000,276.606233 +23.820000,19.670629,0.000000,276.606233 +23.840000,19.470617,-0.000000,276.480908 +23.860000,19.204619,-47.900000,276.355583 +23.880000,19.202970,-15.026000,275.778917 +23.900000,19.139603,-69.030000,275.898242 +23.920000,19.188037,-69.201000,274.773883 +23.940000,19.132964,-80.749000,274.648458 +23.960000,19.034658,0.000000,274.619167 +23.980000,18.973941,0.000000,274.493950 +24.000000,19.031078,0.000000,273.925917 +24.020000,18.984713,-2.441000,273.232767 +24.040000,19.088775,-0.000000,272.551008 +24.060000,19.111672,-16.284000,271.992033 +24.080000,18.821703,-16.113000,271.857758 +24.100000,18.863503,-0.000000,271.298783 +24.120000,18.822328,-50.793000,270.741233 +24.140000,18.607242,-16.113000,270.471258 +24.160000,18.596520,-16.088000,269.778117 +24.180000,18.724390,65.673000,270.325392 +24.200000,18.469231,-114.587000,268.820167 +24.220000,18.387691,-33.020000,268.545000 +24.240000,18.544050,-65.844000,267.578217 +24.260000,18.385936,-32.812000,267.433667 +24.280000,18.447239,32.812000,267.707100 +24.300000,15.536570,-32.812000,266.893817 +24.320000,11.237869,-181.604000,264.696150 +24.340000,11.236937,-709.729000,255.370183 +24.360000,11.262945,-789.477000,242.156892 +24.380000,11.333929,-653.466000,230.443642 +24.400000,11.062988,-613.635000,220.523200 +24.420000,10.697779,-425.506000,213.141975 +24.440000,9.765705,-384.674000,207.117558 +24.460000,9.021466,-381.280000,201.402133 +24.480000,8.663459,-510.974000,193.605608 +24.500000,8.870595,-512.066000,184.638792 +24.520000,9.224770,-543.273000,175.870900 +24.540000,9.024849,-422.503000,169.801625 +24.560000,8.553596,-416.992000,163.258767 +24.580000,8.243297,-335.955000,157.890892 +24.600000,8.112408,-337.194000,151.633883 +24.620000,7.973630,-372.003000,145.431500 +24.640000,7.732272,-411.523000,139.246767 +24.660000,7.576113,-375.555000,133.335267 +24.680000,7.376828,-266.900000,128.509225 +24.700000,7.009833,-248.516000,124.157375 +24.720000,6.685538,-311.193000,119.891183 +24.740000,6.691916,-262.524000,115.110100 +24.760000,6.436586,-288.549000,110.671325 +24.780000,6.203660,-246.386000,106.944017 +24.800000,6.086307,-243.127000,102.046108 +24.820000,6.059754,-208.380000,98.266508 +24.840000,5.696686,-99.475000,96.744242 +24.860000,5.285006,-229.046000,93.314842 +24.880000,5.220673,-117.285000,90.559567 +24.900000,5.121028,-84.252000,88.606608 +24.920000,4.808281,-168.505000,85.923617 +24.940000,4.754711,-135.748000,83.123992 +24.960000,4.780146,-53.631000,81.691758 +24.980000,4.441066,-71.331000,79.890825 +25.000000,4.265347,-132.202000,77.961658 +25.020000,4.342834,-161.950000,75.651642 +25.040000,4.392866,-87.438000,74.192867 +25.060000,4.032174,-75.762000,72.931692 +25.080000,3.672325,-76.641000,71.555567 +25.100000,3.850272,-88.677000,70.068767 +25.120000,3.907142,-77.886000,68.673367 +25.140000,3.695039,-78.936000,67.269267 +25.160000,3.576141,-81.066000,65.270583 +25.180000,3.513691,-79.827000,64.524233 +25.200000,3.418171,-112.640000,63.504442 +25.220000,3.384475,-103.955000,62.225708 +25.240000,3.150986,-50.390000,61.724667 +25.260000,3.021326,-105.017000,60.777308 +25.280000,3.265338,-8.673000,60.274742 +25.300000,3.060169,-8.673000,59.590342 +25.320000,2.947469,-0.000000,58.960467 +25.340000,3.020448,0.000000,58.897042 +25.360000,2.726772,-0.000000,58.004508 +25.380000,2.768026,-31.530000,58.004508 +25.400000,2.631589,31.542000,58.203833 +25.420000,2.513040,-7.604000,57.501792 +25.440000,2.726671,-7.617000,56.808492 +25.460000,2.653824,-7.611000,56.106392 +25.480000,2.674370,0.000000,56.106392 +25.500000,2.665070,-6.372000,55.404292 +25.520000,2.549051,31.518000,55.404292 +25.540000,2.378920,-77.880000,54.755292 +25.560000,2.307984,-6.378000,54.702142 +25.580000,2.584938,25.134000,54.000083 +25.600000,2.431617,-80.004000,52.631283 +25.620000,2.561093,-5.487000,52.585558 +25.640000,2.572539,-54.876000,51.911483 +25.660000,2.306227,0.000000,51.911483 +25.680000,2.399120,31.494000,51.911483 +25.700000,2.571379,-85.491000,50.936608 +25.720000,2.561838,0.000000,51.199058 +25.740000,2.541098,-5.480000,50.479317 +25.760000,2.766996,-5.480000,50.479317 +25.780000,2.737478,31.488000,50.479317 +25.800000,9.068136,-0.000000,49.813983 +25.820000,16.703862,252.758000,52.631308 +25.840000,18.412664,965.466000,65.610783 +25.860000,20.021820,1245.678000,85.659650 +25.880000,18.680085,1130.407000,105.072433 +25.900000,18.108578,881.640000,120.719450 +25.920000,17.569698,618.530000,131.818892 +25.940000,18.347533,420.196000,139.966875 +25.960000,19.601290,477.551000,147.485025 +25.980000,20.402922,755.084000,159.295425 +26.000000,20.376700,809.411000,172.352208 +26.020000,20.055037,679.510000,184.639192 +26.040000,20.131216,567.126000,194.334567 +26.060000,20.446295,600.549000,204.309633 +26.080000,20.668122,611.541000,215.257550 +26.100000,20.794086,495.953000,224.278692 +26.120000,20.864424,457.897000,231.758333 +26.140000,21.248147,519.738000,240.086467 +26.160000,21.428702,508.093000,247.496842 +26.180000,21.238436,407.275000,254.445683 +26.200000,21.210274,343.579000,260.522742 +26.220000,21.158067,258.898000,265.380925 +26.240000,20.962706,264.599000,270.332292 +26.260000,20.870372,182.495000,274.072217 +26.280000,20.997051,153.479000,277.303208 +26.300000,20.854464,166.125000,279.427325 +26.320000,20.681782,156.677000,281.445450 +26.340000,20.673332,12.927000,282.273083 +26.360000,20.424443,73.461000,282.939983 +26.380000,20.295483,-19.995000,282.773358 +26.400000,20.383082,-0.000000,282.773358 +26.420000,20.211338,12.915000,283.047608 +26.440000,20.020754,12.915000,282.773358 +26.460000,20.046197,32.910000,282.939983 +26.480000,19.920680,-32.910000,282.665733 +26.500000,19.876143,-32.897000,282.549258 +26.520000,20.176460,-0.000000,282.053558 +26.540000,20.093034,0.000000,282.053558 +26.560000,19.919224,85.815000,282.768683 +26.580000,20.114605,-45.825000,281.945933 +26.600000,19.849081,-59.460000,281.450433 +26.620000,19.657264,-12.927000,281.342708 +26.640000,19.862639,-32.897000,281.342708 +26.660000,19.737166,-72.399000,281.013525 +26.680000,19.674176,0.000000,280.897050 +26.700000,19.556378,-25.512000,280.410308 +26.720000,19.614196,-47.058000,279.910533 +26.740000,19.678916,0.000000,280.184675 +26.760000,19.487260,-0.000000,279.591625 +26.780000,19.630530,-0.000000,279.317483 +26.800000,19.476619,-18.750000,279.317483 +26.820000,19.207262,-38.452000,278.879258 +26.840000,19.204319,-140.539000,277.582775 +26.860000,19.600862,-0.000000,276.880567 +26.880000,19.697159,0.000000,276.755350 +26.900000,19.326500,-0.000000,276.481408 +26.920000,18.988172,0.000000,276.755350 +26.940000,19.078574,-15.039000,276.630025 +26.960000,19.026820,-47.900000,275.779300 +26.980000,19.165345,-117.114000,274.375092 +27.000000,19.295153,-15.051000,273.946833 +27.020000,19.212259,-47.875000,272.979950 +27.040000,19.055244,32.836000,273.253583 +27.060000,18.971177,-16.284000,273.117883 +27.080000,19.041599,-16.101000,272.277842 +27.100000,18.942087,32.836000,272.551475 +27.120000,18.817550,-32.836000,271.718867 +27.140000,18.747203,32.836000,271.858225 +27.160000,18.802756,0.000000,271.858225 +27.180000,18.378548,-16.113000,271.164975 +27.200000,18.497240,-67.077000,270.606000 +27.220000,18.621244,-99.914000,269.639108 +27.240000,18.702258,-66.040000,269.228233 +27.260000,18.606018,-50.378000,268.400808 +27.280000,18.886621,-17.175000,267.578675 +27.300000,16.003336,-32.800000,267.578675 +27.320000,11.598521,-261.828000,265.525658 +27.340000,11.100166,-606.079000,257.498933 +27.360000,11.068518,-782.165000,244.372925 +27.380000,11.115441,-613.415000,232.740958 +27.400000,11.062182,-637.500000,221.746700 +27.420000,10.758815,-421.246000,214.221275 +27.440000,9.709072,-349.011000,208.242883 +27.460000,8.844726,-306.677000,202.185858 +27.480000,8.638378,-548.834000,194.064933 +27.500000,8.659903,-512.072000,186.069950 +27.520000,8.903683,-424.444000,178.265750 +27.540000,8.833018,-423.559000,171.206283 +27.560000,8.504573,-371.313000,164.627975 +27.580000,8.286190,-337.194000,159.295500 +27.600000,7.846739,-443.640000,152.807825 +27.620000,7.644997,-407.287000,146.827250 +27.640000,7.775545,-308.142000,141.219242 +27.660000,7.721868,-330.456000,135.142233 +27.680000,7.549307,-289.984000,129.604975 +27.700000,7.366067,-265.667000,124.450667 +27.720000,6.980384,-311.175000,119.504083 +27.740000,6.738150,-277.209000,114.844358 +27.760000,6.415298,-256.652000,110.928408 +27.780000,6.101478,-203.198000,107.637650 +27.800000,5.900306,-169.244000,104.072542 +27.820000,5.868544,-180.358000,100.688917 +27.840000,5.902582,-165.313000,97.308850 +27.860000,5.511195,-280.902000,93.315325 +27.880000,5.609804,-149.682000,89.866750 +27.900000,5.319094,-84.259000,88.039158 +27.920000,4.773776,-153.271000,85.659817 +27.940000,4.824622,-186.029000,83.553650 +27.960000,4.627012,-157.879000,81.808817 +27.980000,4.454142,-53.631000,80.378008 +28.000000,4.251112,-68.878000,78.225917 +28.020000,4.451513,-193.591000,75.388400 +28.040000,4.289829,-75.579000,74.292067 +28.060000,3.855154,-75.579000,73.563417 +28.080000,3.872928,-76.635000,72.194667 +28.100000,3.788746,-123.968000,70.159150 +28.120000,3.675388,-88.677000,68.673767 +28.140000,3.559462,-58.142000,67.269608 +28.160000,3.820401,-90.802000,65.270967 +28.180000,3.674326,-79.827000,64.524567 +28.200000,3.528788,-0.000000,63.840217 +28.220000,3.375384,23.370000,63.699633 +28.240000,3.164496,-82.122000,62.407992 +28.260000,3.393689,-72.674000,61.725067 +28.280000,3.295490,-20.092000,60.873233 +28.300000,3.276500,-82.128000,59.663017 +28.320000,3.014092,-71.765000,59.590742 +28.340000,2.766990,31.536000,59.590742 +28.360000,2.825133,-75.585000,58.960867 +28.380000,2.758229,-39.147000,58.634642 +28.400000,2.854660,-75.567000,58.267717 +28.420000,2.932831,-76.635000,57.565567 +28.440000,2.820774,-31.530000,57.239392 +28.460000,2.909277,-0.000000,56.609617 +28.480000,2.757992,31.524000,56.808892 +28.500000,2.592133,-76.641000,56.170217 +28.520000,2.485119,-0.000000,56.106792 +28.540000,2.504390,-77.880000,55.457792 +28.560000,2.664250,-46.368000,54.755642 +28.580000,2.587266,-6.372000,54.702542 +28.600000,2.441298,-77.868000,54.053642 +28.620000,2.496237,-37.884000,53.737942 +28.640000,2.474726,-31.500000,53.080142 +28.660000,2.427273,-80.004000,52.631692 +28.680000,2.385703,-36.987000,52.323467 +28.700000,2.600684,31.494000,51.911892 +28.720000,2.745898,31.494000,51.911892 +28.740000,2.523716,-31.494000,51.649442 +28.760000,2.624075,-31.494000,51.649442 +28.780000,1.976693,-85.491000,51.199467 +28.800000,5.227060,0.000000,51.199467 +28.820000,13.197522,85.491000,51.911892 +28.840000,17.680481,557.336000,58.698125 +28.860000,19.380628,1085.730000,75.652267 +28.880000,18.992205,1118.121000,94.539842 +28.900000,18.818705,1037.054000,112.032000 +28.920000,17.877147,826.422000,126.931133 +28.940000,18.158206,560.705000,136.810933 +28.960000,19.076790,415.936000,143.787450 +28.980000,20.020214,627.343000,153.760125 +29.000000,20.349846,840.582000,167.002817 +29.020000,20.215685,792.797000,178.976933 +29.040000,20.278132,596.319000,189.608892 +29.060000,20.677096,581.280000,199.448717 +29.080000,20.677931,674.255000,210.028642 +29.100000,20.944416,522.924000,219.391475 +29.120000,21.186074,499.169000,228.251225 +29.140000,21.334050,397.961000,235.889967 +29.160000,21.238870,479.650000,243.947508 +29.180000,21.292324,459.436000,251.736400 +29.200000,21.153634,404.980000,258.173367 +29.220000,21.271086,369.396000,263.754817 +29.240000,21.283831,230.749000,267.722092 +29.260000,21.167501,266.113000,271.992817 +29.280000,21.059769,168.493000,275.351367 +29.300000,21.145354,51.391000,276.607050 +29.320000,21.257006,67.663000,278.723642 +29.340000,20.772622,52.587000,280.623250 +29.360000,20.740901,59.802000,281.724925 +29.380000,20.801930,12.939000,281.450875 +29.400000,20.910081,-0.000000,281.450875 +29.420000,20.711680,0.000000,281.450875 +29.440000,20.342551,45.825000,281.724925 +29.460000,20.327373,-0.000000,281.343050 +29.480000,20.136956,-0.000000,281.343050 +29.500000,19.994348,-32.897000,281.343050 +29.520000,20.185491,-32.897000,281.343050 +29.540000,20.133014,32.897000,281.617192 +29.560000,20.179621,65.795000,282.165483 +29.580000,20.283260,-0.000000,281.617192 +29.600000,19.985796,-65.795000,281.617192 +29.620000,19.953035,-138.195000,281.013858 +29.640000,19.881472,0.000000,281.562150 +29.660000,19.976144,-32.897000,280.739717 +29.680000,19.751487,-0.000000,280.739717 +29.700000,19.692804,-32.897000,280.739717 +29.720000,19.698760,32.897000,281.013858 +29.740000,19.776100,32.897000,280.897375 +29.760000,19.789656,32.897000,280.897375 +29.780000,19.603459,-0.000000,280.623233 +29.800000,19.469734,-0.000000,280.303008 +29.820000,19.471442,-32.897000,279.910867 +29.840000,19.501951,-14.147000,279.474067 +29.860000,19.416175,-47.912000,278.480325 +29.880000,19.364928,-48.083000,277.885950 +29.900000,19.354607,-172.338000,276.607067 +29.920000,19.675645,-54.187000,276.178800 +29.940000,19.759497,-15.026000,276.053583 +29.960000,19.325324,-69.226000,275.476700 +29.980000,19.094394,32.849000,275.351375 +30.000000,19.011187,-15.209000,275.224633 +30.020000,19.126023,17.810000,274.649275 +30.040000,19.078334,-15.026000,273.947283 +30.060000,18.954188,-52.941000,273.506108 +30.080000,19.010447,-0.000000,273.379258 +30.100000,18.858095,0.000000,273.379258 +30.120000,18.713589,-15.026000,273.254042 +30.140000,18.708972,16.748000,272.551833 +30.160000,18.624473,-16.113000,271.858583 +30.180000,18.851801,-34.240000,271.299617 +30.200000,18.676794,0.000000,271.165342 +30.220000,18.539376,-16.113000,270.472092 +30.240000,18.768478,0.000000,270.472092 +30.260000,18.667309,-16.088000,269.778950 +30.280000,18.916186,-48.925000,268.821017 +30.300000,16.180151,-17.333000,268.401308 +30.320000,11.873721,-229.040000,265.525950 +30.340000,11.447489,-606.066000,257.499333 +30.360000,11.243286,-780.017000,244.640758 +30.380000,11.264728,-547.143000,233.995725 +30.400000,11.236693,-522.729000,224.190333 +30.420000,10.627570,-496.899000,215.799633 +30.440000,9.773702,-349.096000,210.099567 +30.460000,9.106805,-488.293000,203.167250 +30.480000,8.804054,-613.513000,195.326167 +30.500000,9.038136,-510.992000,186.772500 +30.520000,9.109857,-424.450000,178.977050 +30.540000,8.699366,-421.270000,171.927958 +30.560000,8.568598,-421.258000,165.607575 +30.580000,8.142096,-364.929000,159.730050 +30.600000,7.785224,-381.506000,153.760258 +30.620000,7.953503,-347.808000,147.404425 +30.640000,7.878692,-328.332000,141.318517 +30.660000,7.672060,-332.586000,135.745917 +30.680000,7.522719,-325.152000,130.298692 +30.700000,7.249060,-265.673000,125.410500 +30.720000,6.880211,-312.225000,120.180100 +30.740000,6.648523,-262.493000,115.939442 +30.760000,6.672721,-255.419000,111.766583 +30.780000,6.320836,-255.572000,108.219383 +30.800000,5.862090,-205.328000,105.586333 +30.820000,5.928745,-244.085000,102.038925 +30.840000,5.657728,-226.733000,98.267367 +30.860000,5.480623,-182.482000,95.224417 +30.880000,5.575266,-165.313000,91.938092 +30.900000,5.367825,-166.381000,89.173925 +30.920000,5.012969,-222.491000,85.924475 +30.940000,4.822683,-115.954000,83.679358 +30.960000,4.573266,-117.004000,82.257550 +30.980000,4.534485,-99.475000,80.114458 +31.000000,4.489797,-145.843000,78.188200 +31.020000,4.317886,-99.298000,76.894467 +31.040000,4.217910,-68.890000,74.814700 +31.060000,4.133981,-55.981000,72.833758 +31.080000,3.984896,-120.306000,71.192533 +31.100000,3.792379,20.819000,70.718600 +31.120000,3.465740,-78.759000,69.149800 +31.140000,3.694565,-158.764000,67.351208 +31.160000,3.681759,-78.936000,65.947000 +31.180000,3.659513,-112.469000,64.334150 +31.200000,3.601864,-82.122000,63.840683 +31.220000,3.450534,21.838000,63.092800 +31.240000,3.213151,-9.729000,62.408450 +31.260000,3.088574,-9.564000,61.462408 +31.280000,3.263706,-51.629000,60.347817 +31.300000,3.317126,-73.449000,59.400508 +31.320000,3.195078,-44.036000,58.961325 +31.340000,3.007915,-75.585000,58.961325 +31.360000,3.043378,23.937000,58.897892 +31.380000,2.888791,-0.000000,58.897892 +31.400000,2.660071,-75.579000,58.268067 +31.420000,2.637460,-7.617000,58.204592 +31.440000,2.836538,23.931000,57.502583 +31.460000,2.872808,-7.604000,56.809342 +31.480000,2.776010,-84.259000,56.107183 +31.500000,2.838163,-77.880000,55.458183 +31.520000,2.722947,-77.880000,54.756083 +31.540000,2.747336,25.152000,54.702983 +31.560000,2.648038,-31.524000,54.440283 +31.580000,2.573079,31.524000,54.054033 +31.600000,2.574906,-78.942000,53.343083 +31.620000,2.613915,-53.796000,52.632133 +31.640000,2.770538,-86.376000,51.912333 +31.660000,2.588801,0.000000,51.912333 +31.680000,2.546768,0.000000,51.912333 +31.700000,2.673465,-36.987000,50.937358 +31.720000,2.727816,31.500000,51.199858 +31.740000,2.579619,-0.000000,50.525783 +31.760000,2.932075,0.000000,50.480117 +31.780000,2.073930,31.494000,50.480117 +31.800000,5.593948,31.494000,50.480117 +31.820000,13.992008,117.864000,51.199867 +31.840000,18.074602,532.208000,58.961400 +31.860000,20.009638,1218.255000,77.422342 +31.880000,19.451357,1191.870000,97.663017 +31.900000,18.872185,996.093000,115.264733 +31.920000,18.103476,667.492000,128.326908 +31.940000,18.633988,427.795000,137.017800 +31.960000,19.523427,480.914000,144.695150 +31.980000,20.429119,751.904000,155.821192 +32.000000,20.705074,791.516000,168.434050 +32.020000,20.420088,763.720000,180.832367 +32.040000,20.207492,597.631000,192.993917 +32.060000,20.281152,599.755000,202.997008 +32.080000,20.564073,533.715000,212.377592 +32.100000,20.813583,515.289000,222.182833 +32.120000,21.092450,499.353000,230.538342 +32.140000,21.307345,455.981000,237.566433 +32.160000,21.350148,461.267000,244.760033 +32.180000,21.382510,469.946000,252.250158 +32.200000,21.205743,424.609000,259.011625 +32.220000,21.189368,352.233000,264.287800 +32.240000,21.213135,231.787000,268.955558 +32.260000,20.860279,319.055000,273.820767 +32.280000,20.747863,99.291000,276.179258 +32.300000,20.831594,99.304000,278.160250 +32.320000,20.744558,123.754000,279.911333 +32.340000,20.527608,72.399000,281.617658 +32.360000,20.359272,0.000000,282.220983 +32.380000,20.570120,-59.460000,281.451342 +32.400000,20.459651,-59.460000,281.451342 +32.420000,20.098940,-12.939000,281.343517 +32.440000,20.026409,0.000000,281.343517 +32.460000,20.050719,-0.000000,281.014342 +32.480000,20.079010,-0.000000,281.014342 +32.500000,19.940550,-13.977000,280.897867 +32.520000,19.943078,0.000000,280.897867 +32.540000,19.801819,65.795000,281.446158 +32.560000,19.845741,-0.000000,280.897867 +32.580000,20.107710,-65.795000,280.897867 +32.600000,19.735518,-65.795000,280.897867 +32.620000,19.668370,-71.325000,280.303492 +32.640000,19.934656,0.000000,280.851683 +32.660000,19.666617,-32.897000,280.029350 +32.680000,19.512999,0.000000,279.911350 +32.700000,19.585750,-13.989000,279.592450 +32.720000,19.550075,32.885000,279.592450 +32.740000,19.503452,-14.147000,279.474558 +32.760000,19.564123,-57.165000,278.998183 +32.780000,19.533805,0.000000,278.880083 +32.800000,19.256117,0.000000,278.880083 +32.820000,19.155851,17.846000,278.754758 +32.840000,19.182647,-13.989000,278.043708 +32.860000,19.222420,-69.213000,276.881508 +32.880000,19.369624,-69.213000,276.179308 +32.900000,19.477995,-69.213000,275.203467 +32.920000,19.395283,-36.352000,274.775208 +32.940000,19.352194,0.000000,274.775208 +32.960000,19.357705,-15.026000,273.947783 +32.980000,19.232589,15.222000,273.506600 +33.000000,19.219939,-101.013000,273.106000 +33.020000,18.974731,-15.039000,273.254417 +33.040000,18.674169,0.000000,273.379742 +33.060000,18.602358,-32.849000,272.980675 +33.080000,18.769718,-83.178000,271.993342 +33.100000,18.883022,-16.113000,271.859067 +33.120000,18.871145,-65.222000,270.892175 +33.140000,18.641362,-99.914000,270.333192 +33.160000,18.613050,65.673000,271.019825 +33.180000,18.616634,-81.762000,269.779400 +33.200000,18.511979,-16.101000,269.642175 +33.220000,18.544792,-17.346000,268.401742 +33.240000,18.535504,-0.219000,268.399917 +33.260000,18.522113,-0.000000,267.708392 +33.280000,18.828097,32.812000,267.708392 +33.300000,16.860404,0.000000,267.708392 +33.320000,12.770269,-82.116000,266.210800 +33.340000,11.067881,-485.363000,260.926083 +33.360000,10.842777,-794.030000,248.856292 +33.380000,10.924117,-735.583000,235.756225 +33.400000,11.013877,-636.145000,225.016992 +33.420000,10.563780,-506.549000,215.654250 +33.440000,9.821135,-349.035000,209.288442 +33.460000,8.971323,-306.695000,203.167742 +33.480000,8.544016,-364.111000,196.594875 +33.500000,8.450091,-513.372000,188.013900 +33.520000,8.635556,-574.560000,178.977500 +33.540000,8.764817,-504.498000,171.772508 +33.560000,8.357856,-339.135000,165.572567 +33.580000,8.156075,-298.468000,159.350950 +33.600000,7.970758,-443.646000,152.808600 +33.620000,7.857641,-407.287000,146.828083 +33.640000,7.764646,-340.197000,141.220133 +33.660000,7.580137,-344.616000,135.025075 +33.680000,7.478724,-266.918000,130.064608 +33.700000,7.096982,-302.490000,124.978758 +33.720000,6.918659,-328.509000,120.044833 +33.740000,6.977454,-263.562000,115.255458 +33.760000,6.721419,-223.724000,111.357050 +33.780000,6.142492,-244.262000,107.638492 +33.800000,5.852247,-201.068000,104.073433 +33.820000,5.625551,-193.933000,100.576633 +33.840000,5.741153,-210.638000,97.574475 +33.860000,5.624198,-231.597000,94.275742 +33.880000,5.377075,-198.132000,90.980667 +33.900000,5.284129,-167.449000,88.607883 +33.920000,4.787371,-168.682000,86.500150 +33.940000,4.586292,-52.551000,84.520683 +33.960000,4.582280,-4.388000,82.932300 +33.980000,4.459424,-170.629000,79.667850 +34.000000,4.670644,-128.173000,77.002508 +34.020000,4.555057,-87.609000,75.280058 +34.040000,4.427808,-87.438000,74.194150 +34.060000,3.843821,-75.750000,72.669450 +34.080000,3.600874,-88.482000,71.833225 +34.100000,3.663749,-123.962000,70.160008 +34.120000,3.679127,-57.073000,68.674625 +34.140000,3.711375,-111.413000,66.423150 +34.160000,3.446183,31.585000,66.605233 +34.180000,3.255700,-40.258000,65.611900 +34.200000,3.238807,-9.741000,65.717033 +34.220000,3.302162,-82.141000,64.367300 +34.240000,3.153729,-9.729000,63.093250 +34.260000,3.093912,-72.393000,61.805575 +34.280000,3.132112,-82.141000,61.567433 +34.300000,2.877592,-63.110000,61.041517 +34.320000,2.994412,-0.000000,60.348267 +34.340000,2.937509,-50.579000,59.663867 +34.360000,2.787815,-31.549000,59.400958 +34.380000,2.887514,0.000000,59.400958 +34.400000,2.542560,0.000000,59.328742 +34.420000,2.605383,-0.000000,58.961725 +34.440000,2.654214,7.611000,58.961725 +34.460000,2.669960,-44.036000,58.268533 +34.480000,2.425172,0.000000,58.205108 +34.500000,2.445360,-7.604000,57.503067 +34.520000,2.330513,-44.042000,56.873250 +34.540000,2.361856,-108.166000,55.908392 +34.560000,2.795026,-46.356000,55.458667 +34.580000,2.814464,25.146000,55.405567 +34.600000,2.559576,-77.880000,54.756567 +34.620000,2.516690,-37.890000,54.440817 +34.640000,2.374971,0.000000,54.440817 +34.660000,2.289083,31.512000,54.054517 +34.680000,2.186577,-84.246000,53.036767 +34.700000,2.578249,-80.004000,52.632567 +34.720000,2.733292,31.494000,51.912758 +34.740000,2.519223,0.000000,51.912758 +34.760000,2.700825,31.494000,51.912758 +34.780000,1.880908,-31.494000,51.650308 +34.800000,4.902406,-31.494000,51.650308 +34.820000,12.752264,31.494000,51.912758 +34.840000,17.122235,472.912000,57.942308 +34.860000,18.828920,1114.123000,74.293158 +34.880000,18.187287,1092.913000,93.051792 +34.900000,17.877323,954.925000,110.672883 +34.920000,17.089405,741.064000,123.892783 +34.940000,17.593123,523.498000,133.125508 +34.960000,18.615479,453.283000,140.589133 +34.980000,19.673628,588.855000,148.695358 +35.000000,20.182186,794.445000,161.127650 +35.020000,20.273598,674.163000,173.073133 +35.040000,20.233376,679.473000,184.371183 +35.060000,20.333815,566.253000,195.057158 +35.080000,20.332136,598.400000,205.012900 +35.100000,20.775225,568.243000,215.744550 +35.120000,21.040483,506.549000,224.746108 +35.140000,21.272725,433.105000,231.884875 +35.160000,21.669619,471.008000,240.087692 +35.180000,21.556344,476.269000,247.377617 +35.200000,21.495328,407.250000,254.174175 +35.220000,21.366929,457.385000,261.199517 +35.240000,21.089675,411.303000,267.571167 +35.260000,20.795108,315.234000,272.406667 +35.280000,20.947535,249.267000,276.025333 +35.300000,21.162379,168.505000,278.160633 +35.320000,21.171607,170.837000,280.852075 +35.340000,20.750400,124.816000,282.054867 +35.360000,20.508696,73.461000,283.660992 +35.380000,20.580132,32.897000,283.660992 +35.400000,20.365614,-32.897000,283.386850 +35.420000,20.181425,-0.000000,283.386850 +35.440000,20.204770,65.820000,284.209492 +35.460000,20.040887,-73.461000,283.489592 +35.480000,20.096964,-13.989000,283.373017 +35.500000,20.212600,-72.399000,282.274092 +35.520000,20.237740,0.000000,282.274092 +35.540000,20.086447,-0.000000,281.725800 +35.560000,20.184734,-0.000000,281.725800 +35.580000,20.100036,-0.000000,281.725800 +35.600000,19.939334,-12.927000,281.618075 +35.620000,19.991470,0.000000,281.725800 +35.640000,19.902911,-0.000000,281.618075 +35.660000,19.736023,0.000000,281.618075 +35.680000,19.669660,0.000000,281.618075 +35.700000,19.721281,-0.000000,281.014750 +35.720000,19.832945,0.000000,280.898275 +35.740000,19.765117,-0.000000,280.303900 +35.760000,19.552421,-14.160000,280.185900 +35.780000,19.659081,-13.989000,279.592850 +35.800000,19.494184,-0.000000,279.592850 +35.820000,19.334044,-14.147000,279.474958 +35.840000,19.559093,-104.223000,278.606433 +35.860000,19.415978,-104.016000,277.739633 +35.880000,19.353762,-69.226000,277.309942 +35.900000,19.502979,-69.213000,276.607950 +35.920000,19.513290,-47.900000,276.083458 +35.940000,19.280046,32.861000,276.179692 +35.960000,19.151051,-0.000000,276.054475 +35.980000,19.106575,-15.246000,275.927425 +36.000000,18.912879,-15.039000,275.352275 +36.020000,19.038349,-51.416000,274.073392 +36.040000,19.148678,-0.000000,273.674325 +36.060000,18.814815,-32.849000,273.674325 +36.080000,18.850748,-0.000000,273.106400 +36.100000,18.875379,-32.849000,273.106400 +36.120000,18.480469,-35.314000,272.686900 +36.140000,18.592095,-16.101000,272.552725 +36.160000,18.479419,-34.240000,271.993758 +36.180000,18.222644,32.824000,271.859483 +36.200000,18.502315,-32.824000,271.026975 +36.220000,18.599173,-99.902000,270.333717 +36.240000,18.669156,-83.178000,269.779825 +36.260000,18.645856,16.711000,269.095317 +36.280000,19.019598,-48.913000,268.273183 +36.300000,17.449781,-50.158000,268.128733 +36.320000,13.363284,-33.056000,267.853267 +36.340000,11.521590,-373.840000,263.224775 +36.360000,10.980644,-726.477000,252.120350 +36.380000,10.932938,-731.457000,239.506225 +36.400000,11.389127,-588.757000,229.090175 +36.420000,10.862860,-575.854000,219.293533 +36.440000,10.142180,-472.265000,211.774775 +36.460000,9.401925,-525.158000,205.724017 +36.480000,8.676562,-345.690000,199.576417 +36.500000,8.654878,-483.074000,191.031658 +36.520000,9.005599,-510.998000,182.515025 +36.540000,8.829615,-423.565000,174.737275 +36.560000,8.434391,-336.132000,168.434542 +36.580000,8.190377,-334.893000,162.817692 +36.600000,7.935260,-302.734000,157.208208 +36.620000,7.781624,-446.984000,150.036233 +36.640000,7.728512,-411.676000,143.788425 +36.660000,7.694474,-366.748000,137.897317 +36.680000,7.643757,-328.497000,132.139367 +36.700000,7.123043,-338.879000,127.359050 +36.720000,6.921045,-315.399000,122.516833 +36.740000,6.905210,-231.817000,117.983250 +36.760000,6.724360,-244.262000,113.373783 +36.780000,6.221914,-276.989000,109.409100 +36.800000,5.976343,-246.197000,105.484242 +36.820000,5.902333,-206.207000,102.355433 +36.840000,5.702938,-195.861000,99.209892 +36.860000,5.361587,-164.251000,96.206158 +36.880000,5.303422,-180.371000,93.180850 +36.900000,5.071154,-149.029000,90.561283 +36.920000,4.877914,-84.246000,88.608375 +36.940000,4.839810,-200.207000,85.661150 +36.960000,4.795897,-84.246000,83.819017 +36.980000,4.726950,-117.163000,81.546075 +37.000000,4.499399,-85.302000,80.379300 +37.020000,4.325528,-119.274000,78.071067 +37.040000,4.586170,-175.054000,74.923192 +37.060000,4.611163,-43.951000,73.564708 +37.080000,4.159432,19.586000,73.464408 +37.100000,3.705359,-76.635000,72.195958 +37.120000,3.786559,-12.042000,71.456933 +37.140000,3.753654,-77.880000,70.160458 +37.160000,3.760482,-46.276000,68.765108 +37.180000,3.865637,-79.992000,67.088842 +37.200000,3.948149,-41.320000,66.342492 +37.220000,3.617950,0.000000,66.605700 +37.240000,3.175380,-110.522000,65.684683 +37.260000,3.335097,-113.708000,64.928000 +37.280000,3.199406,0.000000,64.525883 +37.300000,3.135341,-58.178000,63.093650 +37.320000,3.481074,21.826000,62.409300 +37.340000,3.406121,-9.558000,61.463417 +37.360000,3.132466,-82.122000,60.779067 +37.380000,3.095443,-74.511000,60.085817 +37.400000,3.028359,31.549000,60.348725 +37.420000,2.852193,31.549000,59.664325 +37.440000,2.784455,-22.875000,59.401425 +37.460000,2.794202,-75.585000,58.699383 +37.480000,2.638859,-7.611000,58.898758 +37.500000,2.598317,-107.110000,58.006175 +37.520000,2.588960,-45.104000,57.566883 +37.540000,2.457128,-51.660000,56.810208 +37.560000,3.018684,-77.880000,55.459108 +37.580000,3.085916,31.506000,54.756950 +37.600000,2.841673,-46.362000,54.054950 +37.620000,2.811626,-31.506000,53.792400 +37.640000,2.739593,-31.506000,53.792400 +37.660000,2.443425,-78.936000,53.081450 +37.680000,2.227991,-80.004000,52.370500 +37.700000,2.898697,26.013000,52.587275 +37.720000,2.947184,-63.000000,51.913200 +37.740000,2.641709,0.000000,52.438200 +37.760000,2.800262,-0.000000,51.913200 +37.780000,2.081273,-0.000000,51.913200 +37.800000,5.205562,-31.494000,51.650750 +37.820000,12.965541,86.370000,52.370500 +37.840000,17.138145,618.096000,59.592117 +37.860000,18.669734,1072.631000,75.544408 +37.880000,18.247131,1163.989000,94.541133 +37.900000,17.907701,987.793000,111.357742 +37.920000,17.335767,740.039000,124.979517 +37.940000,17.762020,495.758000,134.164742 +37.960000,18.601871,486.199000,141.682483 +37.980000,19.839713,618.829000,150.970758 +38.000000,19.847645,758.453000,163.528992 +38.020000,19.554047,757.208000,176.150700 +38.040000,19.835975,563.983000,186.504342 +38.060000,20.306170,547.778000,196.020583 +38.080000,20.459829,677.349000,205.724350 +38.100000,20.655938,599.493000,216.689967 +38.120000,20.902010,505.682000,225.756833 +38.140000,21.059334,485.205000,234.582717 +38.160000,21.190010,418.640000,242.159008 +38.180000,21.053830,456.591000,249.555642 +38.200000,21.124013,325.329000,254.799875 +38.220000,21.311252,363.024000,260.926875 +38.240000,20.922222,345.666000,266.895900 +38.260000,20.533098,282.409000,271.994158 +38.280000,20.566263,270.581000,276.054825 +38.300000,20.740522,153.479000,278.161242 +38.320000,20.904402,19.714000,279.593325 +38.340000,20.666731,157.702000,281.618567 +38.360000,20.215211,72.399000,282.878117 +38.380000,20.330744,0.000000,283.490292 +38.400000,20.420606,-65.832000,282.941692 +38.420000,20.405241,-98.742000,282.667442 +38.440000,20.177418,-40.551000,282.329517 +38.460000,20.152012,-72.399000,281.618567 +38.480000,20.078107,-32.897000,281.344425 +38.500000,19.919962,-0.000000,281.344425 +38.520000,19.947998,-46.875000,281.227942 +38.540000,20.137749,32.897000,281.015233 +38.560000,20.009289,-32.897000,280.741092 +38.580000,20.096754,-32.897000,280.741092 +38.600000,20.025943,-32.897000,280.741092 +38.620000,20.093041,0.000000,281.015233 +38.640000,19.837891,-0.000000,280.898758 +38.660000,19.609598,-32.897000,280.624617 +38.680000,19.812322,-0.000000,280.030242 +38.700000,19.650007,0.000000,280.186383 +38.720000,19.650614,-13.989000,279.593333 +38.740000,19.451128,-0.000000,279.319192 +38.760000,19.599865,32.885000,279.475442 +38.780000,19.713365,-14.172000,278.606917 +38.800000,19.281963,-0.000000,278.606917 +38.820000,19.216604,-15.039000,278.755633 +38.840000,19.292751,-0.000000,278.161258 +38.860000,19.371752,-15.039000,278.007150 +38.880000,19.436863,-15.039000,277.304942 +38.900000,19.565160,-15.039000,276.602733 +38.920000,19.626618,-3.466000,276.025958 +38.940000,19.362352,-0.000000,275.204225 +38.960000,18.983420,17.822000,275.352742 +38.980000,19.006668,-0.000000,275.078900 +39.000000,19.091293,-47.900000,274.376800 +39.020000,19.015011,-68.151000,273.380617 +39.040000,19.195689,-84.252000,272.553192 +39.060000,19.058496,-67.077000,271.994217 +39.080000,19.104409,-67.077000,271.300967 +39.100000,19.050084,32.836000,271.166683 +39.120000,18.813048,0.000000,271.300958 +39.140000,18.672792,-67.077000,270.607708 +39.160000,18.689492,0.000000,270.607708 +39.180000,18.684296,-48.950000,270.199792 +39.200000,18.457091,-16.088000,269.780292 +39.220000,18.486175,-49.743000,269.365767 +39.240000,18.398094,0.000000,269.230067 +39.260000,18.168463,-0.000000,268.822258 +39.280000,18.543514,-98.657000,268.273650 +39.300000,17.081976,-17.346000,268.129100 +39.320000,13.062390,-67.333000,267.435858 +39.340000,11.445872,-391.003000,262.397817 +39.360000,11.028967,-773.486000,250.379492 +39.380000,11.020327,-764.013000,237.854375 +39.400000,11.264117,-662.353000,227.106500 +39.420000,10.753820,-514.361000,218.004283 +39.440000,10.194633,-347.808000,211.009817 +39.460000,9.320090,-337.011000,205.283767 +39.480000,8.590830,-426.733000,197.910117 +39.500000,8.615888,-516.308000,189.610358 +39.520000,8.794890,-543.292000,180.833308 +39.540000,8.778967,-423.388000,174.035683 +39.560000,8.423381,-422.308000,166.735883 +39.580000,8.228026,-334.893000,161.396233 +39.600000,7.880501,-332.739000,155.554408 +39.620000,7.624078,-373.535000,149.288850 +39.640000,7.626376,-320.721000,143.141242 +39.660000,7.577290,-409.448000,137.711867 +39.680000,7.524061,-341.302000,132.120900 +39.700000,7.218501,-320.941000,126.763142 +39.720000,6.872685,-298.278000,122.080992 +39.740000,6.737663,-311.206000,117.300008 +39.760000,6.689848,-136.065000,113.600325 +39.780000,6.352865,-244.116000,109.692558 +39.800000,5.993284,-246.240000,106.118242 +39.820000,6.099365,-224.792000,101.518083 +39.840000,5.820813,-144.921000,98.798575 +39.860000,5.594518,-277.819000,94.961000 +39.880000,5.460842,-165.307000,91.809050 +39.900000,5.254452,-132.745000,89.739708 +39.920000,5.091533,-67.742000,88.481992 +39.940000,4.856792,-153.277000,85.925800 +39.960000,4.963838,-113.458000,83.701483 +39.980000,4.858397,-85.491000,81.810525 +40.000000,4.607798,-207.104000,79.785333 +40.020000,4.627280,-150.964000,78.335350 +40.040000,4.407074,-87.432000,76.274817 +40.060000,4.185309,-150.921000,74.923708 +40.080000,3.920795,-55.798000,73.565175 +40.100000,3.836572,-197.998000,70.546433 +40.120000,4.022166,-109.484000,68.502175 +40.140000,3.786821,-78.765000,67.755825 +40.160000,3.557477,-89.562000,66.606142 +40.180000,3.487192,-8.673000,65.876017 +40.200000,3.314848,31.585000,65.272733 +40.220000,3.329723,-48.242000,64.526383 +40.240000,3.203938,-48.437000,63.175275 +40.260000,3.302805,-41.296000,62.146742 +40.280000,3.259005,0.000000,62.252942 +40.300000,3.343238,-0.000000,61.568483 +40.320000,3.309529,-74.700000,60.945983 +40.340000,3.238627,0.000000,60.875133 +40.360000,3.322457,0.000000,60.802858 +40.380000,3.083893,31.549000,59.664708 +40.400000,2.949474,-0.000000,59.401800 +40.420000,3.112456,-0.000000,59.401800 +40.440000,3.141120,-31.549000,59.401800 +40.460000,3.139360,-31.549000,59.401800 +40.480000,3.062453,31.549000,59.664708 +40.500000,2.967665,-0.000000,59.664708 +40.520000,2.935022,0.000000,59.664708 +40.540000,2.923164,31.549000,59.664708 +40.560000,2.886965,-31.549000,59.401800 +40.580000,2.796308,0.000000,59.664708 +40.600000,2.779837,31.549000,59.664708 +40.620000,2.718492,-31.549000,59.401800 +40.640000,2.801153,31.549000,59.664708 +40.660000,2.852137,31.549000,59.592542 +40.680000,2.843307,-75.585000,58.962667 +40.700000,2.897784,0.000000,58.962667 +40.720000,2.980520,-7.617000,58.899192 +40.740000,2.890601,-0.000000,58.899192 +40.760000,2.961891,-75.567000,58.269467 +40.780000,2.278635,0.000000,58.269467 +40.800000,5.396692,31.542000,58.269467 +40.820000,13.104592,-0.000000,58.269467 +40.840000,17.486425,387.573000,63.578958 +40.860000,19.497021,1077.056000,79.785458 +40.880000,19.265569,1152.179000,98.912550 +40.900000,18.801402,950.769000,116.769142 +40.920000,17.918501,749.603000,129.723542 +40.940000,18.283262,579.034000,140.503058 +40.960000,19.126738,422.540000,148.021925 +40.980000,20.201082,527.838000,156.570250 +41.000000,20.674005,756.158000,169.119733 +41.020000,20.511780,761.651000,181.804867 +41.040000,20.487425,652.624000,192.914783 +41.060000,20.637629,571.514000,202.898750 +41.080000,20.800286,719.574000,213.818492 +41.100000,21.086253,512.054000,222.748483 +41.120000,21.450801,372.570000,230.319375 +41.140000,21.911417,475.390000,237.854667 +41.160000,21.905053,510.986000,246.966392 +41.180000,21.679535,467.810000,255.201558 +41.200000,21.537717,386.730000,262.124867 +41.220000,21.435833,361.315000,267.854125 +41.240000,21.482355,317.712000,273.255625 +41.260000,21.341072,204.846000,277.060142 +41.280000,21.284905,203.698000,280.304758 +41.300000,21.156568,158.752000,282.775450 +41.320000,21.096808,107.446000,285.013092 +41.340000,21.113053,120.361000,286.362575 +41.360000,20.880792,74.707000,286.985133 +41.380000,20.763874,32.934000,286.985133 +41.400000,20.792221,32.934000,286.985133 +41.420000,20.566468,32.934000,286.985133 +41.440000,20.288500,32.934000,286.985133 +41.460000,20.451188,-95.617000,286.188325 +41.480000,20.533054,32.934000,286.362583 +41.500000,20.682660,32.934000,286.362583 +41.520000,20.515716,0.000000,286.362583 +41.540000,20.359253,12.915000,286.362583 +41.560000,20.650168,32.934000,286.254958 +41.580000,20.615679,-61.608000,285.741558 +41.600000,20.303977,-12.915000,285.359583 +41.620000,20.437696,0.000000,285.633933 +41.640000,20.273621,-0.000000,285.633933 +41.660000,20.109716,-32.922000,285.359583 +41.680000,20.207484,-0.000000,285.359583 +41.700000,20.238887,-61.584000,284.846383 +41.720000,20.374191,-12.927000,284.905383 +41.740000,20.249724,4.235000,284.940675 +41.760000,20.104995,-12.927000,284.284250 +41.780000,20.150054,-13.073000,283.662008 +41.800000,19.999440,-12.927000,284.102883 +41.820000,19.947353,-78.747000,282.942108 +41.840000,19.918080,65.832000,283.490708 +41.860000,19.947707,-72.387000,282.222308 +41.880000,19.739583,-13.977000,281.502508 +41.900000,19.718049,-65.808000,281.015650 +41.920000,19.617618,51.831000,281.447575 +41.940000,19.403359,-71.325000,280.304800 +41.960000,19.562010,65.795000,280.853092 +41.980000,19.465701,-5.383000,280.141933 +42.000000,19.530269,-71.337000,278.881367 +42.020000,19.443597,-169.787000,278.014467 +42.040000,19.468609,-0.000000,277.887725 +42.060000,19.437574,-102.087000,277.310842 +42.080000,19.145292,32.873000,277.459567 +42.100000,19.274077,-15.063000,277.334042 +42.120000,19.231567,-0.000000,276.483525 +42.140000,19.179715,-117.114000,275.079417 +42.160000,19.417638,-0.000000,274.502642 +42.180000,19.042108,17.810000,274.651058 +42.200000,18.848999,-0.000000,274.377317 +42.220000,18.768861,32.849000,274.651058 +42.240000,18.824449,-102.062000,273.800542 +42.260000,18.560376,-68.151000,273.107292 +42.280000,18.951098,-16.101000,272.279967 +42.300000,17.926436,-16.113000,271.860358 +42.320000,13.947375,-67.065000,271.027850 +42.340000,11.857411,-263.781000,267.716600 +42.360000,11.083625,-768.200000,256.150042 +42.380000,11.370477,-721.252000,243.684842 +42.400000,11.629615,-567.932000,232.700758 +42.420000,11.028216,-590.832000,222.291017 +42.440000,10.470309,-484.161000,215.259725 +42.460000,9.554311,-340.368000,209.362008 +42.480000,8.747174,-455.798000,202.898850 +42.500000,8.912932,-484.100000,194.606517 +42.520000,9.077626,-513.128000,185.361125 +42.540000,9.082094,-392.156000,178.267883 +42.560000,8.714050,-421.270000,171.929650 +42.580000,8.327330,-449.194000,165.341067 +42.600000,8.066029,-332.763000,159.999792 +42.620000,7.783647,-445.770000,153.494317 +42.640000,7.869743,-407.287000,146.829392 +42.660000,7.857312,-360.375000,141.053242 +42.680000,7.560989,-300.738000,135.855342 +42.700000,7.195412,-283.020000,130.768017 +42.720000,7.307375,-233.715000,125.412242 +42.740000,7.185924,-280.297000,120.181842 +42.760000,6.784196,-245.147000,115.941183 +42.780000,6.658770,-180.358000,112.281625 +42.800000,6.279070,-181.427000,109.162017 +42.820000,5.913775,-164.080000,106.272467 +42.840000,5.787995,-193.859000,102.356358 +42.860000,5.477696,-164.086000,99.475608 +42.880000,5.280599,-196.026000,95.942292 +42.900000,5.349318,-194.946000,92.917192 +42.920000,5.298938,-98.229000,90.562158 +42.940000,4.888097,-67.755000,88.482342 +42.960000,4.778103,-199.151000,85.543967 +42.980000,4.780112,-154.522000,82.970175 +43.000000,4.449252,-53.796000,81.810975 +43.020000,4.418659,-52.575000,79.785733 +43.040000,4.358149,-115.417000,77.723667 +43.060000,4.230132,-130.297000,75.654233 +43.080000,4.073687,-87.438000,74.195458 +43.100000,3.647652,-87.609000,72.835508 +43.120000,3.623495,-122.894000,70.810317 +43.140000,3.733226,-78.765000,69.414967 +43.160000,3.608857,-99.475000,67.271775 +43.180000,3.620384,-122.387000,64.928800 +43.200000,3.467697,-8.673000,64.526783 +43.220000,3.370251,-41.296000,63.579325 +43.240000,3.305429,21.838000,63.094558 +43.260000,3.316798,-9.729000,62.147142 +43.280000,3.424573,-82.128000,60.779817 +43.300000,3.372452,-82.128000,59.402217 +43.320000,3.499486,31.549000,59.592958 +43.340000,3.221024,-40.209000,59.330050 +43.360000,3.037934,-107.135000,58.700167 +43.380000,3.162367,31.549000,58.963075 +43.400000,3.073183,-7.611000,58.636742 +43.420000,3.154895,-31.542000,58.636742 +43.440000,3.031223,0.000000,58.636742 +43.460000,2.907358,31.542000,58.899592 +43.480000,3.224112,-75.585000,58.795583 +43.500000,3.183687,63.085000,58.795583 +43.520000,3.044488,-0.000000,58.269875 +43.540000,3.079123,-0.000000,58.269875 +43.560000,2.998701,-7.611000,58.732158 +43.580000,3.176738,7.617000,58.269867 +43.600000,3.009743,63.092000,58.732158 +43.620000,2.887286,-76.641000,57.567717 +43.640000,3.055024,63.085000,58.093425 +43.660000,3.173911,-0.000000,57.504283 +43.680000,3.111112,-7.611000,57.336692 +43.700000,3.181570,-0.000000,56.811033 +43.720000,3.211518,0.000000,56.697917 +43.740000,2.970807,-0.000000,56.172408 +43.760000,3.149513,-63.061000,56.172408 +43.780000,2.344727,0.000000,55.909658 +43.800000,5.768815,31.530000,56.172408 +43.820000,13.616703,84.252000,56.548283 +43.840000,17.950902,557.128000,62.912608 +43.860000,19.545281,1073.864000,79.669292 +43.880000,18.954928,1168.255000,98.646842 +43.900000,18.798393,945.880000,115.256992 +43.920000,18.064702,800.573000,128.905308 +43.940000,18.568358,610.095000,139.249592 +43.960000,19.354363,476.464000,146.481175 +43.980000,20.320093,664.251000,156.239417 +44.000000,20.407831,723.938000,168.851617 +44.020000,20.280082,793.908000,181.805250 +44.040000,20.701234,565.197000,192.186608 +44.060000,20.830729,599.694000,202.458408 +44.080000,20.929694,681.781000,212.874158 +44.100000,21.211217,512.078000,223.020075 +44.120000,21.421348,447.290000,231.437942 +44.140000,21.732153,440.502000,239.123683 +44.160000,21.632290,558.166000,248.044267 +44.180000,21.826596,386.743000,254.277067 +44.200000,21.761794,406.237000,261.047383 +44.220000,21.656361,378.479000,267.170125 +44.240000,21.588282,265.661000,272.414358 +44.260000,21.101440,204.846000,277.060550 +44.280000,21.435721,170.812000,280.305167 +44.300000,21.428452,112.939000,282.668233 +44.320000,21.301616,149.206000,284.905775 +44.340000,21.063331,74.523000,286.255350 +44.360000,20.882902,74.707000,286.711083 +44.380000,20.929890,-32.934000,286.711083 +44.400000,21.021799,0.000000,286.985533 +44.420000,20.869562,0.000000,286.985533 +44.440000,20.666779,0.000000,286.985533 +44.460000,20.616368,0.000000,286.985533 +44.480000,20.709787,20.910000,286.362975 +44.500000,20.756934,-32.934000,286.088525 +44.520000,20.496957,32.934000,286.362975 +44.540000,20.389563,-32.934000,286.088525 +44.560000,20.601757,0.000000,286.362975 +44.580000,20.474103,-12.915000,286.255350 +44.600000,20.228590,32.934000,286.255350 +44.620000,20.411019,20.007000,285.634317 +44.640000,20.385879,32.922000,285.634317 +44.660000,20.106908,32.922000,285.634317 +44.680000,20.186089,-0.000000,285.359967 +44.700000,20.281141,32.922000,285.634317 +44.720000,20.258013,-0.000000,285.121117 +44.740000,20.041434,52.929000,285.562192 +44.760000,19.968478,-74.536000,284.941058 +44.780000,20.328435,-140.515000,283.662375 +44.800000,20.206384,65.832000,284.210975 +44.820000,20.096458,19.995000,283.554542 +44.840000,19.908196,-12.915000,282.942467 +44.860000,19.752453,-0.000000,282.668217 +44.880000,19.788627,-39.489000,282.222667 +44.900000,19.814928,-72.399000,280.741867 +44.920000,19.817352,65.808000,281.447933 +44.940000,19.734233,-14.160000,280.187158 +44.960000,19.572703,51.794000,280.142300 +44.980000,19.421183,-0.000000,279.594108 +45.000000,19.316491,0.000000,280.142300 +45.020000,19.262699,-57.165000,278.999833 +45.040000,19.360074,-15.039000,278.482358 +45.060000,19.353499,-104.211000,277.887975 +45.080000,19.289343,18.896000,278.045442 +45.100000,19.297106,-15.051000,277.334392 +45.120000,19.263336,-47.900000,276.483875 +45.140000,19.226577,-69.213000,275.907100 +45.160000,19.271745,0.000000,276.055617 +45.180000,19.058155,-32.861000,275.781775 +45.200000,18.830299,-84.252000,274.651417 +45.220000,19.225823,-32.849000,273.800900 +45.240000,19.218841,0.000000,273.949317 +45.260000,18.972665,-0.000000,272.982425 +45.280000,19.287735,-0.000000,272.688142 +45.300000,17.828142,-0.000000,272.688142 +45.320000,13.760586,-83.178000,271.994992 +45.340000,11.735604,-412.597000,267.170175 +45.360000,11.293080,-749.755000,255.877458 +45.380000,11.345119,-800.854000,242.868533 +45.400000,11.578331,-592.980000,232.626742 +45.420000,11.261331,-558.276000,222.291358 +45.440000,10.572981,-308.923000,215.260067 +45.460000,9.693044,-266.912000,209.974483 +45.480000,8.988756,-508.679000,202.188283 +45.500000,9.016485,-512.066000,193.913600 +45.520000,9.247736,-510.998000,185.352667 +45.540000,8.901861,-392.156000,178.268175 +45.560000,8.666222,-337.005000,171.930042 +45.580000,8.519340,-334.875000,165.609658 +45.600000,8.047609,-306.073000,160.000125 +45.620000,7.846570,-379.394000,153.077883 +45.640000,7.937136,-346.728000,146.481317 +45.660000,7.962748,-329.400000,141.221725 +45.680000,7.607408,-291.314000,136.201033 +45.700000,7.163160,-301.025000,131.321892 +45.720000,6.851683,-320.898000,126.231208 +45.740000,6.642759,-281.353000,121.549517 +45.760000,6.805486,-264.605000,116.891175 +45.780000,6.674511,-244.079000,113.223075 +45.800000,6.199023,-256.469000,109.734725 +45.820000,5.802625,-216.619000,106.681658 +45.840000,5.783613,-233.764000,103.127033 +45.860000,5.596455,-131.396000,100.158900 +45.880000,5.387988,-210.638000,96.891750 +45.900000,5.411597,-195.831000,93.737608 +45.920000,5.304084,-166.381000,91.246925 +45.940000,5.099371,-131.201000,88.911625 +45.960000,4.899338,-121.734000,86.628717 +45.980000,4.969223,-113.458000,84.404350 +46.000000,4.844174,-86.547000,82.141683 +46.020000,4.350178,-118.218000,80.224325 +46.040000,4.173958,-118.029000,78.685942 +46.060000,3.982078,-86.383000,76.740450 +46.080000,4.013532,-119.250000,75.281767 +46.100000,3.853118,-42.889000,74.195758 +46.120000,3.804659,-88.488000,71.933708 +46.140000,3.860440,-77.697000,70.547258 +46.160000,3.656645,-77.874000,69.808333 +46.180000,3.308370,-10.791000,69.062033 +46.200000,3.252455,-158.758000,67.090050 +46.220000,3.466403,-87.615000,65.876783 +46.240000,3.556731,-102.728000,64.336317 +46.260000,3.421082,-31.573000,64.264042 +46.280000,3.365223,-112.628000,63.507408 +46.300000,3.232526,21.826000,63.094867 +46.320000,3.361308,-50.567000,62.410517 +46.340000,3.244361,-81.945000,61.464683 +46.360000,3.296193,-82.128000,60.780283 +46.380000,3.447119,31.549000,61.043192 +46.400000,3.432285,0.000000,61.043192 +46.420000,3.335200,-74.694000,60.157833 +46.440000,3.298585,0.000000,60.349883 +46.460000,3.163390,22.863000,60.277608 +46.480000,3.281248,-8.673000,60.277608 +46.500000,3.272775,-73.455000,59.665483 +46.520000,3.178711,-0.000000,59.402683 +46.540000,3.272578,-31.536000,59.402683 +46.560000,3.323614,0.000000,59.665483 +46.580000,3.014520,0.000000,59.665483 +46.600000,2.990651,-0.000000,59.665483 +46.620000,3.121575,-31.536000,59.402683 +46.640000,2.959692,-31.536000,59.402683 +46.660000,2.952979,63.085000,60.191192 +46.680000,2.956291,-63.085000,59.665483 +46.700000,2.946717,-0.000000,59.665483 +46.720000,3.028597,-8.666000,60.118975 +46.740000,3.025968,-63.067000,58.963433 +46.760000,3.301216,-7.617000,58.899958 +46.780000,3.058394,-12.500000,58.795792 +46.800000,3.395007,-7.617000,58.206708 +46.820000,9.966199,63.067000,58.732267 +46.840000,17.348236,249.566000,60.349900 +46.860000,19.013603,903.820000,72.724258 +46.880000,20.203815,1162.371000,91.381275 +46.900000,19.247681,1129.370000,110.512183 +46.920000,18.760180,857.147000,125.272058 +46.940000,18.457989,717.358000,137.533250 +46.960000,18.988927,484.960000,145.815000 +46.980000,20.033184,538.842000,154.446992 +47.000000,20.728331,673.144000,165.609958 +47.020000,20.738031,794.946000,178.979500 +47.040000,20.463830,681.628000,191.033275 +47.060000,20.675543,631.890000,201.017650 +47.080000,21.063597,683.935000,211.695283 +47.100000,21.200779,582.336000,221.543908 +47.120000,21.199270,541.272000,229.997275 +47.140000,21.645689,423.400000,237.568575 +47.160000,21.823751,560.754000,246.139833 +47.180000,21.611982,434.887000,254.004608 +47.200000,21.262270,423.547000,261.081425 +47.220000,21.351987,361.145000,267.025942 +47.240000,21.640999,264.782000,271.437658 +47.260000,21.397803,300.671000,276.181408 +47.280000,21.349083,241.967000,280.305542 +47.300000,21.326287,219.299000,283.555050 +47.320000,21.265274,149.023000,285.360258 +47.340000,21.094688,88.500000,287.723425 +47.360000,20.824795,0.000000,288.462350 +47.380000,21.296066,0.000000,288.462350 +47.400000,20.912242,0.000000,288.462350 +47.420000,20.565152,-0.000000,288.187700 +47.440000,20.769045,-64.782000,287.822200 +47.460000,20.626783,-0.000000,287.448767 +47.480000,20.454608,0.000000,287.723417 +47.500000,20.348422,20.031000,286.985908 +47.520000,20.515485,-32.946000,286.711358 +47.540000,20.552717,62.670000,286.711358 +47.560000,20.342638,-12.036000,286.363358 +47.580000,20.251606,-0.000000,286.363358 +47.600000,20.322295,-32.946000,286.088808 +47.620000,20.271625,-12.915000,286.255733 +47.640000,20.342070,-61.596000,285.742433 +47.660000,20.283921,-32.946000,285.360258 +47.680000,20.189612,-12.915000,285.634808 +47.700000,20.151450,0.000000,285.634808 +47.720000,19.967911,32.946000,285.634808 +47.740000,20.057644,32.946000,285.634808 +47.760000,20.194216,-12.915000,284.739425 +47.780000,20.187469,32.934000,284.906150 +47.800000,20.023898,-41.601000,284.392750 +47.820000,20.164526,-28.674000,283.771725 +47.840000,20.077969,32.910000,283.662675 +47.860000,19.887000,-60.534000,283.050600 +47.880000,19.800057,-32.922000,282.668525 +47.900000,19.717979,32.922000,282.942875 +47.920000,19.630101,-105.297000,281.453225 +47.940000,19.715066,-46.875000,280.625800 +47.960000,19.810939,32.897000,280.899942 +47.980000,19.598262,-0.000000,280.305567 +48.000000,19.641514,-32.910000,279.913317 +48.020000,19.505513,-90.063000,279.437042 +48.040000,19.303751,-32.897000,279.320367 +48.060000,19.205489,0.000000,279.476617 +48.080000,19.381872,17.846000,278.756808 +48.100000,19.419130,32.885000,278.162425 +48.120000,19.173730,17.846000,277.460317 +48.140000,19.178768,-69.226000,276.883433 +48.160000,19.185776,32.873000,276.758208 +48.180000,18.935201,-15.039000,276.056000 +48.200000,18.840171,98.608000,276.603892 +48.220000,18.840557,-53.979000,276.027117 +48.240000,18.763959,-15.051000,275.901692 +48.260000,18.797058,-18.518000,274.622808 +48.280000,19.398888,-15.039000,273.804025 +48.300000,17.983720,-80.944000,272.688517 +48.320000,13.902986,-67.077000,271.995367 +48.340000,11.674796,-330.468000,267.854958 +48.360000,11.124822,-761.242000,256.988475 +48.380000,11.262757,-749.450000,244.375775 +48.400000,11.490654,-591.857000,233.057633 +48.420000,11.184016,-590.991000,223.020508 +48.440000,10.678665,-285.961000,216.469008 +48.460000,9.810339,-393.499000,210.326492 +48.480000,9.024487,-432.067000,203.169775 +48.500000,8.683408,-509.985000,195.868350 +48.520000,8.933209,-512.036000,185.803508 +48.540000,8.938461,-456.726000,178.710567 +48.560000,8.410290,-305.822000,172.623742 +48.580000,8.305416,-339.123000,166.026050 +48.600000,8.017332,-287.219000,160.425775 +48.620000,7.803463,-407.257000,154.179392 +48.640000,7.903993,-377.307000,147.487958 +48.660000,7.609556,-339.123000,141.321025 +48.680000,7.149033,-320.904000,136.468183 +48.700000,7.087433,-359.271000,131.322217 +48.720000,7.030822,-352.856000,126.542000 +48.740000,6.907812,-247.271000,122.100075 +48.760000,6.698463,-231.634000,117.310758 +48.780000,6.605257,-225.854000,113.375375 +48.800000,6.173570,-257.543000,109.572792 +48.820000,5.933699,-183.557000,106.273183 +48.840000,5.684001,-193.859000,102.194775 +48.860000,5.491526,-226.922000,98.800775 +48.880000,5.353115,-198.315000,95.514500 +48.900000,5.252142,-196.008000,92.369208 +48.920000,4.993873,-83.007000,90.689733 +48.940000,4.780106,-51.464000,89.312025 +48.960000,4.572046,-222.479000,86.364742 +48.980000,4.453516,-153.454000,83.681850 +49.000000,4.439884,-99.475000,82.406067 +49.020000,4.287628,-144.781000,80.488550 +49.040000,4.209663,-118.041000,78.686192 +49.060000,4.118925,-86.376000,76.740758 +49.080000,3.832637,-150.262000,74.759925 +49.100000,3.892305,-87.445000,73.566283 +49.120000,3.932877,-56.866000,72.098700 +49.140000,3.712248,-77.880000,69.898550 +49.160000,3.495049,-110.375000,69.062267 +49.180000,3.283091,-110.369000,67.756942 +49.200000,3.324385,-111.419000,66.343992 +49.220000,3.341269,-81.060000,65.010642 +49.240000,3.151482,-9.735000,64.929517 +49.260000,3.231859,31.579000,64.527500 +49.280000,3.349865,-123.425000,62.147850 +49.300000,3.410674,31.561000,61.727933 +49.320000,3.187735,-31.561000,61.464925 +49.340000,3.156045,94.696000,62.254058 +49.360000,3.032719,-0.000000,61.727942 +49.380000,2.832139,-63.134000,61.727942 +49.400000,3.048917,-0.000000,61.043592 +49.420000,3.138844,54.443000,61.497283 +49.440000,3.077305,-0.000000,60.350283 +49.460000,3.140971,0.000000,60.350283 +49.480000,3.111237,-0.000000,60.087325 +49.500000,3.098425,-31.555000,60.015050 +49.520000,3.116487,-41.906000,59.665833 +49.540000,3.229326,31.549000,59.665833 +49.560000,3.070788,-63.116000,59.665833 +49.580000,2.983914,63.116000,60.191800 +49.600000,2.962624,0.000000,60.191800 +49.620000,2.937956,63.116000,60.191800 +49.640000,3.018388,-63.116000,59.665833 +49.660000,2.759219,0.000000,59.665833 +49.680000,2.813264,63.116000,60.191800 +49.700000,2.553787,-0.000000,60.191800 +49.720000,2.556646,0.000000,60.191800 +49.740000,2.808166,0.000000,60.191800 +49.760000,2.656663,-31.549000,59.402925 +49.780000,2.576321,31.549000,59.665833 +49.800000,3.141302,31.549000,59.593667 +49.820000,9.432999,-0.000000,59.330758 +49.840000,17.284888,196.881000,61.043600 +49.860000,19.490876,903.851000,72.724858 +49.880000,20.647000,1213.299000,92.334175 +49.900000,19.468451,1035.028000,111.196983 +49.920000,19.115076,972.479000,127.466708 +49.940000,18.969290,798.815000,139.784250 +49.960000,19.375986,468.109000,147.958275 +49.980000,20.246031,576.855000,157.210075 +50.000000,20.998118,673.986000,167.457000 +50.020000,20.911236,763.769000,181.103792 +50.040000,20.643131,684.783000,193.644575 +50.060000,20.960452,515.264000,203.872125 +50.080000,20.921991,530.297000,213.909550 +50.100000,21.062532,588.891000,223.759700 +50.120000,21.481484,517.541000,232.472358 +50.140000,21.740338,402.844000,239.817625 +50.160000,21.890234,507.336000,247.910575 +50.180000,21.618637,581.591000,256.826475 +50.200000,21.460035,355.017000,263.484392 +50.220000,21.384946,313.305000,269.097275 +50.240000,21.494890,265.673000,274.075292 +50.260000,21.593640,254.882000,278.882408 +50.280000,21.381542,171.691000,282.330983 +50.300000,21.487646,87.609000,284.285317 +50.320000,21.702003,207.775000,286.363550 +50.340000,21.261351,101.599000,288.462642 +50.360000,20.883500,11.853000,289.200042 +50.380000,21.095548,32.922000,289.200042 +50.400000,20.987120,-32.922000,288.925692 +50.420000,20.694733,21.069000,289.101267 +50.440000,20.498752,21.093000,289.002492 +50.460000,20.697094,32.946000,288.462633 +50.480000,20.683205,-0.000000,288.188083 +50.500000,20.511382,-32.946000,288.188083 +50.520000,20.481873,20.910000,288.362333 +50.540000,20.462783,-0.000000,288.087783 +50.560000,20.374039,0.000000,288.362333 +50.580000,20.422534,-44.982000,288.087783 +50.600000,20.347407,-0.000000,288.087783 +50.620000,20.237170,-64.794000,287.822383 +50.640000,20.233787,-11.853000,287.723608 +50.660000,20.146194,-0.000000,287.723608 +50.680000,20.174378,-32.922000,287.449258 +50.700000,20.190772,0.000000,287.723608 +50.720000,20.185110,32.922000,287.723608 +50.740000,20.401612,-12.915000,286.711750 +50.760000,20.270781,0.000000,286.711750 +50.780000,20.066020,-0.000000,286.363550 +50.800000,20.226649,-61.608000,285.742633 +50.820000,19.908222,0.000000,285.635008 +50.840000,19.827934,32.910000,285.635008 +50.860000,19.823679,7.067000,284.906350 +50.880000,20.017842,52.905000,284.833925 +50.900000,19.984035,-65.820000,283.662975 +50.920000,19.684870,-60.534000,283.050800 +50.940000,19.565591,-0.000000,282.943175 +50.960000,19.423048,-65.808000,282.943175 +50.980000,19.256448,-139.270000,282.330992 +51.000000,19.553065,19.958000,281.620033 +51.020000,19.607975,-71.325000,280.305858 +51.040000,19.624138,-32.897000,280.031717 +51.060000,19.469993,32.897000,280.305858 +51.080000,19.195620,32.897000,280.305858 +51.100000,19.067313,-32.897000,280.031717 +51.120000,18.954012,4.748000,279.476908 +51.140000,19.117743,-38.269000,278.289475 +51.160000,19.155183,-46.850000,277.772208 +51.180000,19.066681,-0.000000,277.460625 +51.200000,19.214094,-32.873000,277.186683 +51.220000,18.855976,-21.289000,276.883850 +51.240000,18.981007,-32.861000,276.484583 +51.260000,18.848054,-47.888000,275.782583 +51.280000,18.945895,-36.364000,275.479550 +51.300000,17.702694,0.000000,275.354225 +51.320000,13.973064,-119.555000,273.382083 +51.340000,12.129855,-331.689000,268.957958 +51.360000,11.322119,-695.617000,259.176267 +51.380000,11.421599,-777.697000,246.012417 +51.400000,11.603430,-572.619000,235.453550 +51.420000,11.168984,-612.597000,225.487025 +51.440000,10.682112,-457.128000,217.734808 +51.460000,9.863340,-334.881000,212.380000 +51.480000,9.035343,-513.104000,205.014892 +51.500000,8.753378,-545.507000,196.472117 +51.520000,9.058761,-542.279000,187.938083 +51.540000,9.123523,-424.609000,180.834767 +51.560000,8.633609,-339.117000,174.470433 +51.580000,8.347337,-418.054000,167.457092 +51.600000,8.229413,-238.360000,162.644783 +51.620000,8.084194,-417.047000,156.359183 +51.640000,7.955161,-405.664000,149.557683 +51.660000,7.998778,-256.616000,143.944133 +51.680000,7.643102,-312.597000,138.520150 +51.700000,7.165222,-245.324000,134.316417 +51.720000,6.822135,-266.729000,129.216383 +51.740000,6.597851,-349.658000,123.894783 +51.760000,6.407418,-360.424000,119.096817 +51.780000,6.460183,-262.481000,114.316500 +51.800000,6.215395,-180.542000,110.931542 +51.820000,5.937204,-214.501000,108.051050 +51.840000,5.558443,-236.975000,104.972800 +51.860000,5.477937,-256.414000,101.416750 +51.880000,5.662314,-213.537000,97.963233 +51.900000,5.501058,-215.502000,94.002875 +51.920000,5.350713,-198.120000,90.983017 +51.940000,5.082255,-150.103000,89.312292 +51.960000,4.815762,-99.481000,87.781233 +51.980000,4.737700,-153.283000,85.225092 +52.000000,4.661217,-66.729000,83.000725 +52.020000,4.559047,-99.304000,80.984433 +52.040000,4.440607,-100.366000,79.478242 +52.060000,4.139002,-86.389000,77.004800 +52.080000,4.054798,-98.840000,75.452483 +52.100000,3.872246,-138.861000,73.566600 +52.120000,3.730174,-153.277000,71.559108 +52.140000,3.718757,-57.061000,70.072300 +52.160000,3.572334,-42.407000,69.062533 +52.180000,3.328020,-47.161000,68.020575 +52.200000,3.239098,-158.764000,65.686450 +52.220000,3.198309,-82.128000,65.192983 +52.240000,3.093595,-111.407000,64.264592 +52.260000,3.210919,-90.808000,63.771017 +52.280000,3.276665,-40.820000,62.492233 +52.300000,3.067083,0.000000,62.411158 +52.320000,2.882365,-0.000000,61.728233 +52.340000,3.078621,-165.319000,59.666117 +52.360000,3.387728,0.000000,59.666117 +52.380000,3.250539,31.549000,59.666117 +52.400000,3.008652,-31.549000,59.403208 +52.420000,2.903792,0.000000,59.666117 +52.440000,3.018270,-0.000000,59.403208 +52.460000,2.929835,0.000000,59.666117 +52.480000,2.764588,-0.000000,59.403208 +52.500000,2.835414,-0.000000,59.403208 +52.520000,2.842570,8.666000,59.666108 +52.540000,3.058290,31.549000,59.666108 +52.560000,2.872470,31.549000,59.666108 +52.580000,2.768046,31.549000,59.593883 +52.600000,2.905067,-31.549000,59.330975 +52.620000,2.759094,-31.549000,59.330975 +52.640000,2.654394,-31.549000,59.330975 +52.660000,2.847115,-0.000000,59.330975 +52.680000,2.635404,-44.036000,58.964008 +52.700000,2.666686,-31.542000,58.701158 +52.720000,2.720754,-0.000000,58.701158 +52.740000,2.591104,-31.542000,58.701158 +52.760000,2.576172,23.925000,58.900533 +52.780000,2.550280,23.925000,58.900533 +52.800000,3.285469,-0.000000,58.637683 +52.820000,9.793581,0.000000,58.637683 +52.840000,17.174292,173.992000,60.087617 +52.860000,19.486471,843.725000,71.295650 +52.880000,20.720493,1218.658000,91.247625 +52.900000,19.547622,1066.790000,110.409550 +52.920000,19.229018,874.469000,126.101483 +52.940000,18.918841,770.263000,139.163458 +52.960000,19.321112,511.053000,148.760825 +52.980000,20.244476,576.916000,157.746108 +53.000000,20.786037,674.084000,168.262458 +53.020000,20.777531,783.520000,181.104042 +53.040000,20.673949,620.349000,193.185842 +53.060000,20.877730,631.005000,203.170217 +53.080000,21.146346,719.561000,213.819825 +53.100000,21.122400,651.501000,224.010808 +53.120000,21.002708,503.369000,232.472617 +53.140000,21.615123,423.144000,239.817883 +53.160000,21.949515,493.640000,247.379825 +53.180000,21.711264,487.255000,255.878350 +53.200000,21.567699,404.956000,262.953642 +53.220000,21.659226,312.219000,268.130842 +53.240000,21.529284,300.976000,273.676483 +53.260000,21.261241,252.941000,278.289708 +53.280000,21.376178,91.918000,281.620283 +53.300000,21.639886,161.059000,284.285575 +53.320000,21.427241,166.198000,286.291583 +53.340000,21.116557,88.513000,288.272883 +53.360000,21.065244,64.794000,288.362600 +53.380000,21.033636,-32.946000,288.188350 +53.400000,20.878593,0.000000,288.188350 +53.420000,20.715764,32.946000,288.462900 +53.440000,20.736324,32.946000,288.462900 +53.460000,20.580637,32.946000,288.462900 +53.480000,20.539546,-0.000000,288.462900 +53.500000,20.542483,-12.036000,288.362600 +53.520000,20.454829,-12.036000,288.362600 +53.540000,20.480887,65.869000,288.911508 +53.560000,20.432181,-64.794000,287.822650 +53.580000,20.201406,0.000000,287.822650 +53.600000,20.038613,65.881000,288.371658 +53.620000,20.192627,-0.000000,287.723875 +53.640000,20.224967,-0.000000,287.723875 +53.660000,20.132597,-9.716000,287.642908 +53.680000,20.075824,-0.000000,287.094000 +53.700000,19.917025,-12.902000,286.986483 +53.720000,19.898880,0.000000,286.986483 +53.740000,19.924783,52.941000,286.805000 +53.760000,19.818352,-127.453000,285.742892 +53.780000,19.852924,12.915000,285.742892 +53.800000,20.013009,-65.856000,285.635267 +53.820000,19.764518,4.248000,285.670667 +53.840000,19.766258,65.832000,285.562942 +53.860000,19.870431,-12.927000,284.285583 +53.880000,19.766402,52.893000,284.104008 +53.900000,19.634957,-0.000000,283.051058 +53.920000,19.558598,12.927000,283.599558 +53.940000,19.311217,0.000000,283.491833 +53.960000,19.163515,0.000000,282.943433 +53.980000,19.249540,-12.915000,282.223633 +54.000000,19.455778,-86.376000,280.626358 +54.020000,19.703669,-14.160000,279.914083 +54.040000,19.616978,-0.000000,279.321133 +54.060000,19.435753,32.861000,279.594975 +54.080000,19.129486,18.725000,279.477175 +54.100000,19.005770,-14.135000,279.477175 +54.120000,19.151255,-15.039000,278.757375 +54.140000,19.234345,-48.071000,277.889058 +54.160000,19.105051,-70.263000,277.186958 +54.180000,19.033553,-36.340000,276.884125 +54.200000,19.002320,-0.000000,276.884125 +54.220000,18.972739,0.000000,277.306483 +54.240000,18.886409,-69.213000,276.056600 +54.260000,18.894501,-69.213000,275.479825 +54.280000,18.830783,-69.226000,274.777725 +54.300000,18.878968,-36.364000,274.075625 +54.320000,15.982877,-15.039000,273.676558 +54.340000,11.723476,-167.431000,271.588150 +54.360000,10.859869,-621.252000,262.953817 +54.380000,11.081718,-918.249000,248.739758 +54.400000,11.349969,-632.934000,237.163025 +54.420000,11.006317,-611.523000,227.062733 +54.440000,10.597244,-502.294000,217.835400 +54.460000,9.717855,-334.875000,212.109700 +54.480000,8.754256,-395.355000,205.996525 +54.500000,8.543022,-453.839000,198.677350 +54.520000,8.948952,-599.511000,188.190042 +54.540000,8.915500,-424.621000,180.402017 +54.560000,8.310888,-273.590000,174.574692 +54.580000,8.143269,-418.121000,167.577983 +54.600000,8.150817,-340.234000,161.934017 +54.620000,7.790222,-341.259000,155.753050 +54.640000,7.648311,-349.969000,149.337600 +54.660000,7.710695,-397.546000,142.041367 +54.680000,7.649760,-320.935000,137.002308 +54.700000,7.332740,-334.094000,131.471408 +54.720000,7.088239,-251.678000,126.542625 +54.740000,6.951253,-232.684000,121.956042 +54.760000,6.456924,-295.440000,117.045517 +54.780000,6.378384,-258.605000,112.958458 +54.800000,6.076277,-206.207000,110.001108 +54.820000,5.731054,-225.671000,106.170750 +54.840000,5.635434,-224.609000,102.717492 +54.860000,5.392094,-164.074000,99.212050 +54.880000,5.347994,-261.859000,95.250367 +54.900000,5.364457,-181.597000,92.225275 +54.920000,4.983712,-82.122000,90.563450 +54.940000,4.491093,-166.778000,88.480383 +54.960000,4.359351,-136.962000,86.502750 +54.980000,4.522788,-122.637000,83.821183 +55.000000,4.466984,-99.475000,81.695642 +55.020000,4.232531,-20.910000,80.314883 +55.040000,3.917598,-147.100000,78.252617 +55.060000,4.012166,-24.139000,76.803958 +55.080000,3.897462,-87.445000,74.822867 +55.100000,3.906030,-150.885000,72.836733 +55.120000,3.994926,-100.549000,71.248558 +55.140000,3.849606,-209.075000,68.767183 +55.160000,3.582522,-78.771000,68.547508 +55.180000,3.404808,-79.827000,66.688950 +55.200000,3.446418,-8.673000,65.877700 +55.220000,3.413098,-48.248000,64.528067 +55.240000,3.257382,-48.443000,63.176908 +55.260000,3.345434,-113.690000,62.148417 +55.280000,2.912324,21.997000,61.728500 +55.300000,2.947584,-113.684000,60.781133 +55.320000,3.132962,0.000000,61.044092 +55.340000,3.079624,-31.555000,60.781133 +55.360000,3.080234,-74.517000,60.350842 +55.380000,3.138612,0.000000,60.278567 +55.400000,3.433397,-84.259000,58.964283 +55.420000,3.557476,31.536000,58.900858 +55.440000,3.465836,-0.000000,58.900858 +55.460000,3.220850,-31.536000,58.638058 +55.480000,3.080447,0.000000,58.900858 +55.500000,3.318365,-31.536000,58.638058 +55.520000,3.066710,0.000000,58.900858 +55.540000,2.928621,31.536000,58.900858 +55.560000,3.009332,-0.000000,58.638058 +55.580000,3.066139,-31.536000,58.638058 +55.600000,3.058598,-31.536000,58.638058 +55.620000,3.019542,-75.567000,58.008333 +55.640000,3.000590,-0.000000,58.008333 +55.660000,2.857660,-31.530000,58.008333 +55.680000,2.849591,-0.000000,58.008333 +55.700000,2.871761,-31.530000,58.008333 +55.720000,2.809793,0.000000,58.008333 +55.740000,2.749266,31.530000,58.271083 +55.760000,2.751311,-0.000000,58.008333 +55.780000,2.753834,0.000000,58.008333 +55.800000,3.068361,23.919000,58.207658 +55.820000,9.104705,31.542000,58.207658 +55.840000,16.203980,158.770000,59.594167 +55.860000,17.914530,780.291000,69.416292 +55.880000,19.311700,1169.244000,87.204983 +55.900000,18.183097,1065.759000,105.486533 +55.920000,17.804583,836.114000,120.600308 +55.940000,17.826404,641.613000,132.141742 +55.960000,18.314548,462.854000,141.144675 +55.980000,19.477297,455.633000,148.884175 +56.000000,20.297221,780.657000,160.001308 +56.020000,20.164164,759.484000,172.355933 +56.040000,20.261688,647.210000,184.373692 +56.060000,20.527029,512.060000,194.608058 +56.080000,20.900610,600.579000,204.583633 +56.100000,21.075550,611.505000,214.990475 +56.120000,20.922788,551.904000,224.748617 +56.140000,21.382873,503.393000,232.744617 +56.160000,21.730879,484.985000,240.774600 +56.180000,21.565391,491.540000,248.859108 +56.200000,21.602973,415.600000,255.878650 +56.220000,21.459173,438.964000,263.075192 +56.240000,21.425315,329.577000,268.404467 +56.260000,21.208589,284.863000,273.676775 +56.280000,21.148664,238.757000,277.772733 +56.300000,21.266593,85.327000,280.306400 +56.320000,21.388601,131.140000,282.439267 +56.340000,21.120486,149.206000,284.906908 +56.360000,20.807056,74.511000,286.364117 +56.380000,20.932536,41.784000,286.712317 +56.400000,20.813888,-0.000000,286.986767 +56.420000,20.713344,-75.585000,286.464408 +56.440000,20.724506,-19.995000,286.297783 +56.460000,20.545502,32.910000,286.364108 +56.480000,20.637144,-32.910000,286.089858 +56.500000,20.675576,-32.934000,285.982133 +56.520000,20.445210,-32.922000,285.468833 +56.540000,20.445407,0.000000,285.468833 +56.560000,20.178562,0.000000,285.468833 +56.580000,20.255969,32.922000,285.743183 +56.600000,20.222169,-0.000000,285.468833 +56.620000,20.223307,20.007000,285.635558 +56.640000,20.233226,-0.000000,285.361308 +56.660000,20.273293,0.000000,285.635558 +56.680000,20.220098,-0.000000,285.361308 +56.700000,19.905824,-48.669000,284.848008 +56.720000,19.828662,-28.686000,284.393608 +56.740000,19.972850,32.910000,284.285883 +56.760000,20.099366,-0.000000,283.663533 +56.780000,19.978567,-0.000000,283.663533 +56.800000,19.704848,-0.000000,283.663533 +56.820000,19.427050,-0.000000,283.663533 +56.840000,19.323672,-73.449000,282.943733 +56.860000,19.749844,-66.064000,282.276625 +56.880000,19.797786,-86.376000,281.449100 +56.900000,19.882353,-0.000000,280.306425 +56.920000,19.757323,-14.160000,280.736617 +56.940000,19.547675,-5.395000,280.143467 +56.960000,19.551589,-65.771000,279.595375 +56.980000,19.513559,32.885000,279.595375 +57.000000,19.251063,-90.051000,278.727058 +57.020000,19.219171,-38.269000,278.290050 +57.040000,19.443051,-46.850000,277.772783 +57.060000,19.302853,17.846000,277.461200 +57.080000,19.210549,-102.087000,276.610475 +57.100000,19.091413,0.000000,276.758992 +57.120000,18.996276,0.000000,276.758992 +57.140000,18.837595,-32.861000,275.908375 +57.160000,18.810707,-69.226000,275.480108 +57.180000,19.016291,-69.201000,274.778108 +57.200000,18.962921,-102.062000,273.802167 +57.220000,19.054180,-68.151000,273.108917 +57.240000,18.831976,32.849000,273.382658 +57.260000,18.651233,32.836000,273.257333 +57.280000,18.549590,-0.000000,272.689408 +57.300000,18.386188,-17.956000,272.131967 +57.320000,15.624002,16.723000,271.861983 +57.340000,11.618709,-166.369000,269.782325 +57.360000,10.931433,-553.125000,261.877667 +57.380000,10.805139,-794.043000,248.859175 +57.400000,11.099268,-618.701000,236.733125 +57.420000,10.832613,-667.663000,225.758908 +57.440000,10.690615,-584.466000,215.927983 +57.460000,10.047804,-340.386000,209.634100 +57.480000,9.145095,-271.167000,204.511425 +57.500000,8.716663,-545.507000,196.472700 +57.520000,8.808130,-565.216000,187.477900 +57.540000,8.827439,-424.633000,179.691300 +57.560000,8.499902,-455.615000,172.356000 +57.580000,8.262913,-421.264000,165.610917 +57.600000,8.129176,-332.763000,160.001392 +57.620000,7.966873,-413.647000,153.763608 +57.640000,7.608950,-339.306000,148.145283 +57.660000,7.465952,-417.016000,141.321867 +57.680000,7.484782,-332.580000,135.749267 +57.700000,7.211762,-255.950000,131.589683 +57.720000,6.787896,-320.898000,126.809217 +57.740000,6.655154,-263.549000,122.100975 +57.760000,6.490548,-293.823000,117.454683 +57.780000,6.317332,-245.141000,113.746550 +57.800000,6.128633,-257.537000,109.573742 +57.820000,5.902287,-183.551000,106.274083 +57.840000,5.766106,-164.080000,102.871283 +57.860000,5.511503,-131.219000,100.008283 +57.880000,5.478703,-229.034000,96.208650 +57.900000,5.462136,-181.176000,92.768875 +57.920000,5.191774,-98.229000,90.563792 +57.940000,4.773349,-84.252000,88.346500 +57.960000,4.705228,-131.182000,86.238867 +57.980000,4.737524,-168.511000,83.821483 +58.000000,4.613795,-131.158000,81.548592 +58.020000,4.493475,-98.229000,80.274142 +58.040000,4.283221,-87.609000,78.073533 +58.060000,4.125633,-87.438000,76.276825 +58.080000,4.132211,-87.438000,74.818100 +58.100000,3.970598,-151.336000,72.935992 +58.120000,3.821719,-57.055000,71.459458 +58.140000,3.975806,-47.149000,69.416625 +58.160000,3.774546,-21.594000,68.324200 +58.180000,3.402399,-110.552000,67.010075 +58.200000,3.471828,-81.066000,65.274808 +58.220000,3.608948,-16.644000,65.054983 +58.240000,3.260597,-72.387000,63.844108 +58.260000,3.217651,-82.135000,63.019275 +58.280000,3.275841,0.000000,62.411875 +58.300000,3.190667,-31.573000,61.465842 +58.320000,3.286283,-113.696000,60.781483 +58.340000,3.005959,-31.561000,60.781483 +58.360000,3.038263,-8.673000,60.709208 +58.380000,3.290737,-0.000000,60.351292 +58.400000,3.299216,-8.679000,60.278967 +58.420000,3.275341,-0.000000,60.015958 +58.440000,3.277270,-73.455000,59.666842 +58.460000,3.167323,-8.666000,59.594625 +58.480000,3.102435,0.000000,59.666842 +58.500000,2.983234,31.555000,59.594617 +58.520000,2.894017,-8.666000,59.594617 +58.540000,2.968146,0.000000,59.666833 +58.560000,2.972989,-0.000000,59.594617 +58.580000,2.951941,-0.000000,59.594617 +58.600000,2.793511,-0.000000,59.594617 +58.620000,2.995235,0.000000,59.666833 +58.640000,3.038191,0.000000,59.594617 +58.660000,2.654856,-0.000000,59.331658 +58.680000,2.813275,0.000000,59.594617 +58.700000,2.841431,-0.000000,59.594617 +58.720000,2.684726,-8.666000,59.594617 +58.740000,2.762004,-0.000000,59.594617 +58.760000,2.805711,-31.555000,59.331658 +58.780000,2.710165,31.555000,59.594617 +58.800000,2.814168,-75.585000,58.964742 +58.820000,2.800243,-44.030000,58.964742 +58.840000,2.710366,-31.555000,58.701783 +58.860000,2.726524,0.000000,58.964742 +58.880000,2.558787,-31.555000,58.701783 +58.900000,2.559816,-39.160000,58.638408 +58.920000,2.616576,0.000000,58.901317 +58.940000,2.644889,31.549000,58.901317 +58.960000,2.798856,-44.024000,58.271542 +58.980000,2.697448,0.000000,58.271542 +59.000000,2.484467,0.000000,58.271542 +59.020000,2.440767,-7.617000,58.208067 +59.040000,2.517541,31.542000,58.208067 +59.060000,2.639248,0.000000,58.208067 +59.080000,2.688818,-0.000000,57.306633 +59.100000,2.644705,-39.147000,57.243208 +59.120000,2.740796,-44.049000,56.876133 +59.140000,2.957667,23.919000,56.812708 +59.160000,2.874550,-0.000000,56.549958 +59.180000,2.742703,-76.641000,56.174033 +59.200000,2.735139,0.000000,56.174033 +59.220000,2.831617,-0.000000,55.847908 +59.240000,2.855803,0.000000,56.110608 +59.260000,2.677395,0.000000,56.110608 +59.280000,2.593247,31.524000,56.110608 +59.300000,2.717052,-46.356000,55.461608 +59.320000,2.753317,-37.896000,55.145808 +59.340000,2.723262,-31.524000,55.145808 +59.360000,2.705117,-109.399000,54.496850 +59.380000,2.642952,0.000000,54.759500 +59.400000,2.693278,-0.000000,54.496850 +59.420000,2.646442,0.000000,54.759500 +59.440000,2.558517,-0.000000,54.496850 +59.460000,2.420508,-37.890000,54.443750 +59.480000,2.690240,-77.874000,54.057450 +59.500000,2.983357,-0.000000,53.346500 +59.520000,2.951291,-31.512000,53.083900 +59.540000,2.886937,-5.310000,53.039650 +59.560000,2.776197,-111.511000,52.372992 +59.580000,2.732575,-31.506000,52.372992 +59.600000,2.762891,0.000000,52.635542 +59.620000,2.707192,-31.506000,52.372992 +59.640000,2.621567,-0.000000,52.372992 +59.660000,2.771162,-31.506000,52.372992 +59.680000,2.758149,31.506000,52.635542 +59.700000,2.656780,-31.506000,52.372992 +59.720000,2.579737,-80.889000,51.915692 +59.740000,2.574239,-0.000000,51.653192 +59.760000,2.497344,0.000000,51.915692 +59.780000,2.469434,-0.000000,51.653192 +59.800000,2.437537,-0.000000,51.653192 +59.820000,2.360414,-31.500000,51.653192 +59.840000,2.473160,31.500000,51.915692 +59.860000,2.593460,-0.000000,51.915692 +59.880000,2.366521,-0.000000,51.915692 +59.900000,2.071180,-111.499000,50.986533 +59.920000,2.277058,-85.485000,50.940808 +59.940000,2.358764,0.000000,50.940808 +59.960000,2.472086,0.000000,51.203258 +59.980000,2.263737,31.494000,51.203258 diff --git a/raspberry-dataserver/svpi.py b/raspberry-dataserver/svpi.py index 8cf28f413b9b7769c0c6f6b833db5410fe2f5669..14bd19913f65e760f3d4dd4e0eca00734d199f04 100755 --- a/raspberry-dataserver/svpi.py +++ b/raspberry-dataserver/svpi.py @@ -10,6 +10,7 @@ from collections import deque import commsFormat import threading import commsConstants +from commsConstants import alarm_codes from typing import List, Dict import logging logging.basicConfig(level=logging.INFO, @@ -22,7 +23,6 @@ class svpi(): # dump file to variable self._bytestore = bytearray(self._input.read()) self._pos = 0 # position inside bytestore - self._currentAlarm = None # received queue and observers to be notified on update self._payloadrecv = deque(maxlen = 16) self._observers = [] @@ -51,46 +51,12 @@ class svpi(): def getAlarms(self) -> List[str]: # give/cancel a random alarm a twentieth of the time - #alarms = { - # 0: "manual", - # 1: "gas supply", - # 2: "apnea", - # 3: "expired minute volume", - # 4: "upper pressure limit", - # 5: "power failure", - #} if np.random.randint(0, 20) == 0: - if self._currentAlarm is None: - # send alarm - alarm = np.random.randint(0, 6) - self._currentAlarm = alarm - return bytearray((0xA0,0x01,alarm,0x00,0x00,0x00)) - else: - # stop previous alarm - alarm = self._currentAlarm - self._currentAlarm = None - return bytearray((0xA0,0x02,alarm,0x00,0x00,0x00)) + # send alarm + alarm = 1 + np.random.randint(0, len(alarm_codes)) + return bytearray((0xA0,alarm,0x00,0x00,0x00,0x00)) return None - def getThresholds(self) -> List[float]: - # All thresholds 32 bit floats - thresholds: List[float] = np.random.uniform(0.0, 1000.0, 3).tolist() - return thresholds - - def setMode(self, mode: str) -> bool: - # setting a mode - just print it - if mode in ("PRVC", "SIMV-PC", "CPAP"): - logging.info(f"Setting mode {mode}") - return True - else: - logging.error(f"Requested mode {mode} does not exist") - return False - - def setThresholds(self, thresholds: List[float]) -> str: - # setting thresholds - just print them - logging.info(f"Setting thresholds {thresholds}") - return thresholds - # callback to dependants to read the received payload @property def payloadrecv(self):