diff --git a/data/Books.csv b/data/Books.csv deleted file mode 100644 index c9334d3..0000000 --- a/data/Books.csv +++ /dev/null @@ -1,121 +0,0 @@ -Name,Author,Publication Year,Publisher,ISBN,Availability -Cryptography and Network Security. [Principles and Practice] (8th Ed.),Stallings William,2023,Pearson Education,9789357059718,1 -The 48 Laws of Power,Greene Robert,1998,Profile Books Ltd,9781861972781,1 -Shriman Yogi,Desai Ranjeet,2023,Mehta Publication,9788177666403,1 -Partner,Kale V P,2023,Mehta Publication,9788177664294,1 -Think and Grow Rich. [Unleash the secret to success],Hill Napoleon,2014,India Book Distributors,9788192910918,1 -SUBTLE ART F NOT GIVING A FUCK. [A counterintuitive Approch to Living a Good Life ],MANSON MARK,2016,Harper Collins Publications,9780062641540,1 -Secret of the Nagas. [Book 2 of the shiva Trilogy],Amish,2022,Harper Collins Publications,9789356290600,1 -The Poppy War,Kuang R F,2018,Harper Voyager,9780008239848,1 -The hard things about hard things,Horowitz Ben,2018,Harper Collins Publication,9780062273208,0 -Word Power Made Easy. [The Complete Handbook for building a superior Vocabulary],LEWIS NORMAN,1978,Penguin Random House,9780143424680,1 -Certificate Physical and Human Geography,Leong Goh Cheng,2024,Oxford University Press,9789354975660,1 -SSC Reasoning,Aggarwal R S,2023,S Chand Publications,9789355017284,1 -How to Prepare for Quantitative Aptitude for CAT. (10th Ed.),Sharma A K,2023,Mcgraw Hill,9789355320852,1 -Through the Broken Glass. [An Autobiography],Seshan T N,2023,Rupa Publications India Pvt. Ltd,9789357021968,1 -1984,Orwell George,2022,Golden Minds Publication,9789357201674,1 -Chemical Engineering. (3rd Ed.),Made Easy Publications GATE 2024,2023,Made Easy Publication,9789395548878,0 -Daivatanchi Satyakatha,Null,2023,Vishwakarma Publications,9789393757432,1 -How to win Friends and Influence People,Del Karnegi,2023,Vishwakarma Publications,9789393757456,1 -The Empress of Indraprastha Part 2 Building on Emprie,Raje Sonali,2023,Vishwakarma Publications,9789395481267,1 -Principles of Mass Transfer and Separation Processes,Dutta Binay K,2023,PHI Learning Pvt Ltd,9788120329904,29 -Fundamentals of Python. [First Programs] (2nd Ed.),Lambert Kenneth A,2023,Cengage Learning India Pvt Ltd,9789353502898,19 -Artificial Intelligence. (2nd Ed.),Kaushik Saroj,2023,Cengage Learning India Pvt Ltd,9789355730425,24 -Operating Systems. [Concept building and Problem solving Approach],Singh Manish Kumar. Kumar Sachin & Pal Saibal K,2022,Cengage Learning India Pvt Ltd,9789355733542,19 -Web Design. [Introductory] (6 th Ed.),Campbell J T,2021,Cengage Learning India Pvt Ltd,9789386650320,19 -Cryptography Network Security and Cyber Laws,Menezes Bernard L & Kumar Ravinder,2023,Cengage Learning India Pvt Ltd,9789386858948,9 -Product Design and Development. (7th Ed.),Ulrich Karl T; Eppinger Steven D & Yang M C,2023,Null,9789390113231,4 -Software Engineering. [Concepts and Practices] (2nd Ed.),Suman Ugrasen,2022,Cengage Learning India Pvt Ltd,9789390555475,4 -Software Engineering. [Concepts and Practices] (2nd Ed.),Suman Ugrasen,2022,Cengage Learning India Pvt Ltd,9789390555475,14 -Machine Learning with R. (4th Ed.),Lantz Brett,2023,Packet Publication,9781801071321,4 -Natural Langurage Processing and Information Retrieval,Siddiqui Tanveer & Tiwary U S,2023,Oxford University Press,9780195692327,9 -Computer Science. [A Structured Programming Approach Using C ] (3rd Ed.),Forouzan Behrouz A,2022,Cengage Learning India Pvt Ltd,9788131503638,19 -Fundamentals of Data Structures in C. (2nd Ed.),Horowitz Ellis; Sahni S & Anderson Freed Susan,2023,University Press,9788173716058,19 -Data Structures and Algorithm Made Easy,Karumanchi Narasimha,2022,Career Monk Publication,9788193245279,4 -Principles of Information Systems. (14th Ed.),Stair Ralph M & Reynolds George W,2023,Cengage Learning India Pvt Ltd,9789355733771,19 -Principles of Information Security. (7th Ed.),Whitman Michael E & Mattord Hebert J,2023,Cengage Learning India Pvt Ltd,9789355738905,19 -Cyber Security and Cyber Laws,Basta Alfred; Basta Nadine; Brown Mary & Kumar Ravinder,2018,Cengage Learning India Pvt Ltd,9789387511675,19 -Cryptography Network Security and Cyber Laws,Menezes Bernard & Kumar Ravinder,2023,Cengage Learning India Pvt Ltd,9789386858948,19 -Atomic Habits,Clear James,2018,Pengiun Random House,9780735211292,2 -Mechanical Engineering,Made Easy Publications GATE 2024,2023,Made Easy Publications,9788119100019,2 -ATOMIC HABITS (Marathi),CLEAR JAMES,2023,Manjul Publishing House P ltd,9789390085408,2 -Introduction to Indian Knowledge System,Mahadevan B & Nagendra Pavana R N,2023,PHI Learning,9789391818203,24 -Traditional Knowledge System in India,Jha Amit,2023,Atlantic Publishers & Distributors,9788126912230,24 -Linear Algebra. (4th),Poole David,2023,Cengage learning,9788131530245,29 -Probability and Statistics for Engineering and Sciences. (9th Ed.),Devore J L,2023,Cengage,9789353506247,29 -Discrete Mathematics wieh Applications. [Metric Version] (5th Ed.),Epp S S,2023,Cengage,9789355731029,29 -Enterpreneurship. (2nd Ed.),Batra Safal,2023,Cengage,9789355735676,19 -Enterprise Cloud Computing,Shroff Gautam,2022,Cambridge University Press,9781107648890,19 -"Engineering Design, An Introduction. (2nd)",Karsnitz John R; Obrien Stephen & Hutchinson John,2021,Cengage Learning India Pvt Ltd,9788131530740,59 -Soft Skills for Everyone. (2nd),Butterfield jeff,2023,Cengage Learning India Pvt Ltd,9789353501051,9 -Quantitative Aptitude and Reasoing,Saraf Shyam & Swarup Abhilasha,2020,Cengage Learning India Pvt Ltd,9789353501525,59 -Self Development and Professional Excellence,John Peter A,2020,Cengage Learning India Pvt Ltd,9789353501624,9 -"Entrepreneurship. [Theory, Process, Practice]",kuratko Donald F,2023,Cengage Learning India Pvt Ltd,9789355734006,9 -Enviranmental Science. (16th),Miller G Tayler,2023,Cengage Learning India Pvt Ltd,9789355738899,9 -Machine Learning with Python for Everyone,Fenner Mark E,2023,Pearson Education,9789353944902,14 -"System Design Interview. [An Insider's Guide, Vol.1]",Xu Alex,2023,Shroff Publishers and Distributors,9789355427199,9 -Concepts of Programming Languages,Sebesta Robert W,2023,Pearson Education,9789356067417,19 -CLOULD COMPUTING. [CONCEPTS TECHNOLOGY AND ARCHITECHTURE],ERL THOMAS; MAHOOD ZAIGHAM & PUTTINI RICARDO,2024,Pearson Education,9789332535923,14 -Fuzzy Sets and Fuzzy Logic:theory and Applications,KLIR GEORGE J & YUAN BO,2023,Prentice Hall of India,9789332549425,9 -CLOUD COMPUTING DESIGN PATTERNS,ERL THOMAS; COPE ROBERT & NASERPOUR AMIN,2016,Pearson Education,9789332557307,9 -MACHINE LEARNING,DUTT SAIKAT; CHANDRAMOULI S & DAS AMIT KUMAR,2024,Pearson Education,9789353066697,9 -DEEP LEARNING,DAS AMITKUMAR; GOSWAMI S & MITRA PABITRA,2022,Pearson Education,9789354493874,9 -DEEP LEARNING. [CORE CONCEPTS METHODA AND APPLICATIONS],GOPAL M,2022,Pearson Education,9789356061972,18 -Learning Deep Learning,Ekman Magnus,2023,Pearson Education,9789356063976,9 -BUILDING BLOCKCHAIN APPS,YUAN MICHAEL JUNTAO,2020,Pearson Education,9789390168385,9 -Cryptography and Network Security. [Principles and Practices] (8th Ed.),Stallings William,2024,Pearson Education,9789357059718,24 -Engineering Design Process. (2 nd Ed.),Haik Yousef & Shahin Tamer,2023,Cengage Learning India Pvt Ltd,9788131529041,59 -[Mechanical Engineering],"Made Easy Publications, GATE 2024 ",2023,Made Easy Publication,9788119100019,24 -Let Us C,Kanetkar Yashavant P,2023,BPB Publications,9789355512765,9 -Mrutyunjay,Sawant Shivaji,2023,Mehata Publishing House,9789357201674,59 -[Computer Science and IT] (17th Ed.),Made Easy Publications GATE 2024,2023,Made Easy Publication,9789395548984,2 -Aagantuk,Vaidya Vivek,2023,Vishwakaram Publications,9789395481625,2 -Amazing Child Saylee,Agavane Manisha,2024,Vishwakarma Publications,9789393757548,2 -Beneath Divided Skies,Sharma natasha,2024,Vishwakarma Publications,9789395481533,2 -Bhagwatgeeta Ani Kuran Madhil Karmyog Parichay,Vakil Asim,2024,Vishwakarma Publications,9789395481151,2 -Chhatrapati Shri Shivarai,Tapkir Sandip Bhanudas,2023,Vishwakarma Publications,9789393757586,2 -Chhatrapati Shree Shivarai (Hindi Anuwad),Tapkir Sandeep,2023,Vishwkarma Publications,9789393757418,2 -Communication Skills Simplified Through Stories And Exercises,Joshi Nitin,2023,Vishwakarma Publications,9789395481243,2 -Cupid at Corporate ,Singh Meenakshi,2024,Vishwakarma Publications,9789395481618,2 -Daivatanchi Satyakatha,Rana Ashok,2023,Vishwakarma Publications,9789393757432,2 -The Iconic Iconociast,Lal Subodh; Fahmida Riaz,2023,Vishwakarma Publications,9789395481106,2 -How to Stop Worring and Start living. [Anuwad DR. Jundare Vaishali ],Karnegi Del,2024,Vishwakarma Publications,9789395481465,2 -How to win Friends and Influence People,Del Karnegi,2023,Vishwakarma Publications,9789393757456,2 -Husband by Proxy,Mehta Purva A,2024,Vishwakarma Publications,9789395481403,2 -Ichchapatra Kalachi Garaj Vyavasthapatra Mrityupatra Yabaddal Sarva kahi,Puranik Akanksha,2023,Vishwakarma Publications,9789395481175,2 -IF THEN ELSE,Ranganathan Sandhya,2023,Vishwakarma Publications,9789395481083,2 -Jaliyanwala Baug 13 April 1919 Bharatiya Swatantryacha Trigar Point,Sonavane Manohar,2023,Vishwakarma Publications,9789395481144,2 -Jewels From The Treasure Trove,Kundu Anamika,2023,Vishwakarma Publications,9789395481953,2 -Kabeer Vichar,Banakar Vijay,2024,Vishwakarma Publications,9789393757658,2 -Karheche Pani (Sankshipt),Atre Aacharya,2023,Vishwakarma University,9789393757678,2 -Keep Moving,Lifeschool,2023,Vishwakarma Publications,9789389624311,2 -Keep Moving 2,Lifesschool,2023,Vishwakarma Publications,9788194317777,2 -Kiwiyo Safar New zealandchi (Marathi),Lonkar Vijay,2023,Null,9789395481110,2 -Letters To My Mother,Pareek Vikkas Arun,2023,Vishwakarma Publications,9789393757036,2 -Lokkaletil Gan (Marathi),Dekhane Ramchandra,2023,Vishwakarma Publications,9789395481809,2 -Lover By Command and other Spy stories. [Counter operations by India's Best],Saraf V K,2023,Vishwakarma Publications,9789395481397,2 -Lt Colonel Purohit. [Vishvasghatacha Bali],Mishra Smita,2023,Vishwakarma Publications,9789395481298,2 -Madam Commissioner. [The Extraordinary Life of an Indian Police Chief],Borwankar Meera,2023,Vishwakarma Publications,9789361137679,2 -Maharashtrachi Phule Sanskruti arthat Bahujan Sanskruti,Shende S R,2023,Vishwakarma Publications,9789395481168,2 -Malawani Mulakhatil Itihasache Paharekari,Tapkir Sandeep Bhanudas,2023,Vishwakarma Publications,9789390869312,2 -Marga Yashacha Marga Sukhacha,Ghodekar Sudhakar & Salunkhe Sanjay,2023,Vishwakarma Publications,9789393757517,2 -Not Before You,Gwalani Lata,2024,Vishwakarma Publications,9789395481502,2 -PanchayatRaj,joshi Smita,2024,Vishwakarma Publications,9789395481489,2 -Phoenix in Flames,Singh Rachna,2023,Vishwakarma Publications,9789395481601,2 -Pranayama. [AN ART OF BREATHING KNOWLEDGE AND SCIENCE],Karajgaonkar Giridhar,2024,Vishwakarma Publications,9789395481977,2 -Anuwad Prerak Utprerak,Chandramouli Venkatesan & Kale Neha,2023,Vishwakarma Publications,9789390869633,2 -Raising. [Inspiring Stories of Growth & Resilience],Pathak Preeti,2023,Vishwakarma Publications,9789395481472,2 -Rangadya Durgvaibhavacha Khajina,Tapkir Sandeep Bhanudas,2023,Vishwakarma Publications,9789390869541,2 -Satyache Prayog athava Aatmakatha,Gandhi Mahatma,2024,Vishwakarma Publications,9789393757647,2 -SHINING DARKNESS,Sharangpani Shrinivas,2024,Vishwakarma Publications,9789395481199,2 -Shrikrushana Bhagwatgeeta Vayvasthapan Ani Vyaktimattwa vikas,Thakur Dadaji,2023,Vishwakarma Publications,9789395481458,2 -Shunyatoon Suryakade,Datar Aarati,2023,Vishwakarma Publications,9789395481182,2 -Story of Ordinary,Bhalla Deepika,2023,Vishwakarma Publications,9789393757999,2 -Swami Vivekananda ani Mahatma Gandhi,Patil Vishwas,2024,Vishwakarma Publications,9789395481571,2 -10 Sutras to Surf the Corporate Tide Called Office Politics,Ghosh Indranil,2023,Vishwakarma Publications,9789395481656,2 -Adventures of Little Kanya The Moscow Mosaic,Sane Ashwini R,2024,Vishwakarma Publications,9789395481427,2 -Art of Beetfulness. [Aajachya Digital Yugat Shant Rahane],Nandan Nilekani; Bhojawani Tanuj & Anuwad -- Nandapurkar; Fadake Suchita,2024,Vishwakarma Publications,9789395481427,2 -Art of Public Speaking,Karnegi Del & Anuwad- Panase Shruti,2024,Vishwakarma Publications,9789395481212,2 -The Empress of Indraprastha Part 2 Building on Emprie,Raje Sonali,2023,Vishwakarma Publications,9789395481267,2 -The Eye of the Fish,Nair Samyuktha,2024,Vishwakarma Publications,9789395481939,2 -The Making of Star,Khandekar Kohali & Khandekar Vaneeta,2023,Vishwakarma Publications,9789393757302,2 diff --git a/data/Users.csv b/data/Users.csv index c6a79c6..8f1083c 100644 --- a/data/Users.csv +++ b/data/Users.csv @@ -1,2 +1,3 @@ -Student_Name,Student_PRN,Student_Email,Student_Whatsapp_no,Student_pass,Branch,Semester,ssid,Modbus_IP,Modbus_Port -测试用户,11111111,test@example.com,NULL,0000,测试,III,zhizhan-2,10.10.100.254,8899 +User,User_pass,Wifi_SSID,Modbus_IP,Modbus_Port,NFC,Reserve +测试用户,0000,zhizhan-2,10.10.100.254,8899,0000,0000 +正式用户,0000,USR-DR404_3EB0,10.10.100.254,8899,0000,0000 diff --git a/data/all_book_transactions.csv b/data/all_book_transactions.csv deleted file mode 100644 index a700f3b..0000000 --- a/data/all_book_transactions.csv +++ /dev/null @@ -1,3 +0,0 @@ -User,User_No,Book_Name,ISBN,Date,Due_Date,Return_Date -12444444,9607111115,Shriman Yogi,9788177666403,2025-02-06 18:41:57.020884,2025-02-16 18:41:57.020884,06/02/2025 -12444444,9607111115,The hard things about hard things,9780062273208,2025-02-05 14:58:13.566729,2025-02-15 14:58:13.566729,Not Returned diff --git a/data/book_positions.csv b/data/book_positions.csv deleted file mode 100644 index 5dfa129..0000000 --- a/data/book_positions.csv +++ /dev/null @@ -1,7 +0,0 @@ -Name,Pos -Cryptography and Network Security. [Principles and Practice] (8th Ed.),2L23 -The 48 Laws of Power,1L13 -Shriman Yogi,1L53 -Partner,1L43 -Think and Grow Rich. [Unleash the secret to success],1L23 -SUBTLE ART F NOT GIVING A FUCK. [A counterintuitive Approch to Living a Good Life ],1L33 \ No newline at end of file diff --git a/data/borrowed_books.csv b/data/borrowed_books.csv deleted file mode 100644 index f773486..0000000 --- a/data/borrowed_books.csv +++ /dev/null @@ -1,2 +0,0 @@ -User,User_No,Book_Name,ISBN,Date,Due_Date,Renew_status -12444444,9607111115,The hard things about hard things,9780062273208,2025-02-05 14:58:13.566729,2025-02-15 14:58:13.566729,Not Renewed diff --git a/kv/app.kv b/kv/app.kv index b8a1334..48d570c 100644 --- a/kv/app.kv +++ b/kv/app.kv @@ -10,28 +10,6 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 HistoryScreen: # 历史记录屏幕 name: 'history' # 显示用户操作历史 - SignUpScreen: # 注册屏幕 - name: 'signup' # 用户注册界面,创建新账号 - OtpScreen: # 验证码屏幕 - name: 'otp' # 用于验证码验证的界面 - ResetPassScreen: # 重置密码屏幕 - name: 'reset_pass' # 重置密码界面,设置新密码 - ForgetPassScreen: # 忘记密码屏幕 - name: 'forgot_pass' # 忘记密码入口,用于启动密码找回流程 - RecommendScreen: # 推荐屏幕 - name: 'recommend' # 显示推荐内容 - SearchBookScreen: # 搜索书籍屏幕 - name: 'searchBook' # 用于搜索书籍的界面 - ProfileEditScreen: # 编辑个人资料屏幕 - name: 'profile_edit' # 用于修改用户个人信息的界面 - NotificationScreen: # 通知屏幕 - name: 'notification' # 显示系统通知和消息的界面 - BorrowBookScreen: # 借书屏幕 - name: 'borrow_book' # 处理借书操作的界面 - ReturnBookScreen: # 还书屏幕 - name: 'return_book' # 处理还书操作的界面 - RenewBookScreen: # 续借书籍屏幕 - name: 'renew_book' # 处理书籍续借操作的界面 ModifyCurrentParamScreen: # 修改参数屏幕 name: 'modify_current_param' # 用于修改系统参数的界面 @@ -127,8 +105,6 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 # rounded_rectangle: self.x, self.y, self.width, self.height, 5,5,5,5,100 - - : MDFloatLayout: @@ -348,7 +324,6 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 on_release: root.manager.transition.direction = "left" nav_drawer.set_state('close') - # app.data_load() root.manager.current = "home" DrawerClickableItem: @@ -360,7 +335,7 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 on_release: root.manager.transition.direction = "left" nav_drawer.set_state('close') - root.manager.current = "recommend" + root.manager.current = "home" DrawerClickableItem: icon: 'shield-lock-outline' @@ -372,7 +347,7 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 root.manager.transition.direction = "left" nav_drawer.set_state('close') app.clear_text() - root.manager.current = "borrow_book" + root.manager.current = "home" DrawerClickableItem: icon: 'cog-outline' @@ -383,8 +358,7 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 on_release: root.manager.transition.direction = "left" nav_drawer.set_state('close') - app.return_book("Return") - root.manager.current = "return_book" + root.manager.current = "home" DrawerClickableItem: icon: 'alert-circle-outline' @@ -397,8 +371,7 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 on_release: root.manager.transition.direction = "left" nav_drawer.set_state('close') - app.return_book("Renew") - root.manager.current = "renew_book" + root.manager.current = "home" MDNavigationDrawerDivider: MDLabel: @@ -418,8 +391,8 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 on_touch_up: app.change_cursor(False) on_release: root.manager.transition.direction = "left" - nav_drawer.set_state('close') - # app.book_history() + # nav_drawer.set_state('close') + root.manager.current = "history" DrawerClickableItem: @@ -516,52 +489,6 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 pos_hint: {'center_x': 0.5,'center_y': 0.70} color: rgba(135, 133, 193, 255) - # MDTextField: - # id: username - # hint_text: "Enter PRN" - # font_name: "MPoppins" - # helper_text: "PRN must be 8 digits" - # helper_text_mode: "on_focus" - # icon_right: "dialpad" - # icon_color: app.theme_cls.primary_color - # pos_hint: {"center_x": 0.5, "center_y": 0.63} - # size_hint_x: None - # width: dp(335) - # on_touch_down: app.change_cursor(True) - # on_touch_up: app.change_cursor(False) - - # MDRelativeLayout: - # size: self.width, self.height - - # MDTextField: - # id : password - # font_name: "MPoppins" - # font_size: "14sp" - # hint_text: "Enter Password" - # helper_text: "must contain at least one 'a' , 'A' , '@' & '0'" - # helper_text_mode: "on_focus" - # pos_hint: {"center_x": 0.5, "center_y": 0.53} - # size_hint_x: None - # width: dp(335) - # password:True - # on_focus: app.focus_text_field(icon, self.focus, "password") - # on_touch_down: app.change_cursor(True) - # on_touch_up: app.change_cursor(False) - - # MDIconButton: - # id: icon - # icon: 'eye-off' - # theme_icon_color: "Custom" - # icon_color: rgba(162, 169, 188, 255) - # size_hint: None, None - # size: dp(24), dp(24) - # pos: password.x + password.width - self.width+dp(4), password.center_y - self.height / 2+dp(5) - # on_touch_down: app.change_cursor(True) - # on_touch_up: app.change_cursor(False) - # on_release: - # app.toggle_password_visibility(password, self) - # password.focus=True - Button: text: "wifi认证登录" font_name: "BPoppins" @@ -584,799 +511,6 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 pos: self.pos radius: [5] - # MDTextButton: - # text: "忘记密码" - # pos_hint: {'center_x': 0.5, 'center_y': 0.31} - # color: rgba(68,78,132,255) - # font_name: "BPoppins" - # font_size: '13sp' - # on_touch_down: app.change_cursor(True) - # on_touch_up: app.change_cursor(False) - # on_release: - # root.manager.transition.direction= "down" - # root.manager.current="forgot_pass" - # MDLabel: - # text: "or" - # color: rgba(52, 0, 231, 255) - # pos_hint: {'center_y': 0.25} - # font_name: "BPoppins" - # font_size: '13sp' - # halign: 'center' - - # MDFloatLayout: - # md_bg_color: rgba(178, 178, 178, 255) - # size_hint: 0.35, 0.002 - # pos_hint: {'center_x': 0.27, 'center_y': .248} - # MDFloatLayout: - # md_bg_color: rgba(178, 178, 178, 255) - # size_hint: 0.35, 0.002 - # pos_hint: {'center_x': 0.73, 'center_y': .248} - - # MDTextButton: - # id: prn_mode - # text: "验证邮箱" - # font_name: 'BPoppins' - # font_size: '13sp' - # color: rgba(135, 133, 193, 255) - # pos_hint: {'center_x': 0.5, 'center_y': 0.19} - # on_touch_down: app.change_cursor(True) - # on_touch_up: app.change_cursor(False) - # on_release: - # app.login_mode(username, self) - - # MDGridLayout: - # cols: 1 - # size_hint: 0.2, 0.07 - # pos_hint: {'center_x': 0.5, 'center_y': 0.15} - # Image: - # source: 'assets/google.png' - - - # MDTextButton: - # text: "Don't have an account? Sign up" - # font_name: 'BPoppins' - # halign: 'center' - # font_size: '11sp' - # color: rgba(52, 0, 231, 255) - # pos_hint: {'center_x': 0.5, 'center_y': 0.05} - # on_touch_down: app.change_cursor(True) - # on_touch_up: app.change_cursor(False) - # on_release: - # root.manager.transition.direction = "left" - # root.manager.current="signup" - -# : -# name: "signup" -# MDFloatLayout: -# mg_bd_color: 1,1,1,1 -# MDIconButton: -# icon: "arrow-left" -# pos_hint: {'center_y': 0.95} -# user_font_size: "30sp" -# theme_text_color: "Custom" -# text_color: rgba(26,24,58,255) -# on_touch_down: app.change_cursor(True) -# on_touch_up: app.change_cursor(False) -# on_release: -# root.manager.transition.direction= 'right' -# root.manager.current= "main" -# MDLabel: -# text: "H i!" -# font_name: "RPac" -# font_size: "26sp" -# size_hint_x: None -# width: dp(350) -# pos_hint: {'center_x': 0.5,'center_y': 0.9} -# color: rgba(0, 0, 59, 255) - -# MDLabel: -# text: "Create a new account" -# font_name: "BPoppins" -# font_size: "20sp" -# size_hint_x: None -# width: dp(350) -# pos_hint: {'center_x': 0.5,'center_y': 0.85} -# color: app.theme_cls.primary_color - - -# ScrollView: -# size_hint: 1, None -# height: self.parent.height - dp(250) -# pos_hint: {'top':0.81} -# MDList: -# padding: "12dp", "10dp", "12dp", "3dp" -# spacing: "10dp" -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDLabel: -# text: "Name" -# color: rgba(0, 0, 0, 255) -# font_name: "BPoppins" -# font_size: '15sp' -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} - -# MDRelativeLayout: -# size_hint_y: None -# height: "60dp" -# MDTextField: -# id: signup_name -# hint_text: "Enter Name*" -# font_name: "MPoppins" -# font_size: "15sp" -# helper_text: "Provide your fullname" -# helper_text_mode: "on_focus" -# icon_right: "alphabetical" -# icon_color: app.theme_cls.primary_color -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} -# on_touch_down: app.change_cursor(True) -# on_touch_up: app.change_cursor(False) -# canvas.before: -# Color: -# rgb: rgba(127, 127, 127, 255) -# Line: -# width: 0.5 -# rounded_rectangle: self.x-5, self.y+20, self.width+10, self.height-25, 10,10,10,10,100 -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDLabel: -# text: "PRN" -# color: rgba(0, 0, 0, 255) -# font_name: "BPoppins" -# font_size: '15sp' -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} - -# MDRelativeLayout: -# size_hint_y: None -# height: "60dp" -# MDTextField: -# id: signup_prn -# hint_text: "Provide your PRN*" -# font_name: "MPoppins" -# font_size: "15sp" -# helper_text: "PRN of 8 digits starting with 1 2 ......only*" -# helper_text_mode: "on_focus" -# icon_right: "dialpad" -# input_filter: 'int' -# required_length: 8 -# icon_color: app.theme_cls.primary_color -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} -# on_touch_down: app.change_cursor(True) -# on_touch_up: app.change_cursor(False) -# canvas.before: -# Color: -# rgb: rgba(127, 127, 127, 255) -# Line: -# width: 0.5 -# rounded_rectangle: self.x-5, self.y+20, self.width+10, self.height-25, 10,10,10,10,100 -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDLabel: -# text: "Email" -# color: rgba(0, 0, 0, 255) -# font_name: "BPoppins" -# font_size: '15sp' -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} - -# MDRelativeLayout: -# size_hint_y: None -# height: "60dp" -# MDTextField: -# id: signup_email -# hint_text: "email address*" -# font_name: "MPoppins" -# font_size: "15sp" -# helper_text: "email test*" -# helper_text_mode: "on_focus" -# icon_right: "email-arrow-left-outline" -# min_text_length: 11 -# icon_color: app.theme_cls.primary_color -# size_hint_x: None -# width: 335 -# pos_hint: {"center_x": 0.5, "center_y": 0.5} -# on_touch_down: app.change_cursor(True) -# on_touch_up: app.change_cursor(False) -# canvas.before: -# Color: -# rgb: rgba(127, 127, 127, 255) -# Line: -# width: 0.5 -# rounded_rectangle: self.x-5, self.y+20, self.width+10, self.height-25, 10,10,10,10,100 - -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDLabel: -# text: "电话" -# color: rgba(0, 0, 0, 255) -# font_name: "BPoppins" -# font_size: '15sp' -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} - - -# MDRelativeLayout: -# size_hint_y: None -# height: "60dp" -# MDTextField: -# id: signup_no -# hint_text: "Enter WhatsApp Number*" -# font_name: "MPoppins" -# font_size: "15sp" -# helper_text: "Provide your Whatsapp no. only*" -# helper_text_mode: "on_focus" -# icon_right: "whatsapp" -# icon_color: app.theme_cls.primary_color -# input_filter: 'int' -# max_text_length: 10 -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} -# on_touch_down: app.change_cursor(True) -# on_touch_up: app.change_cursor(False) -# canvas.before: -# Color: -# rgb: rgba(127, 127, 127, 255) -# Line: -# width: 0.5 -# rounded_rectangle: self.x-5, self.y+20, self.width+10, self.height-25, 10,10,10,10,100 - - -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDLabel: -# text: "Password" -# color: rgba(0, 0, 0, 255) -# font_name: "BPoppins" -# font_size: '15sp' -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} -# spacing: "10dp" - -# MDRelativeLayout: -# size_hint_y: None -# height: "60dp" -# MDRelativeLayout: -# size: self.width, self.height -# MDTextField: -# id : signup_pass -# font_name: "MPoppins" -# font_size: "15sp" -# hint_text: "Create Password*" -# helper_text: "must contain 8 char* with at least one 'a' , 'A' , '@' & '0'" -# helper_text_mode: "on_focus" -# password:True -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} -# on_focus: app.focus_text_field(icon, self.focus, "sign_pass") -# on_touch_down: app.change_cursor(True) -# on_touch_up: app.change_cursor(False) -# canvas.before: -# Color: -# rgb: rgba(127, 127, 127, 255) -# Line: -# width: dp(0.5) -# rounded_rectangle: self.x-5, self.y+20, self.width+10, self.height-25, 10,10,10,10,100 - -# MDIconButton: -# id: icon -# icon: 'eye-off' -# theme_icon_color: "Custom" -# icon_color: rgba(217, 217, 217, 255) -# size_hint: None, None -# size: dp(24), dp(24) -# pos: signup_pass.x + signup_pass.width - self.width+dp(4), signup_pass.center_y - self.height / 2+dp(5) -# on_touch_down: app.change_cursor(True) -# on_touch_up: app.change_cursor(False) -# on_release: -# app.toggle_password_visibility(signup_pass, self) -# signup_pass.focus=True - -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDLabel: -# text: "Branch" -# color: rgba(0, 0, 0, 255) -# font_name: "BPoppins" -# font_size: '15sp' -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} - - -# MDRelativeLayout: -# size_hint_y: None -# height: "60dp" -# MDTextField: -# id: signup_branch -# hint_text: "Branch*" -# font_name: "MPoppins" -# font_size: "15sp" -# helper_text: "Provide your Branch" -# helper_text_mode: "on_focus" -# icon_right: "source-branch" -# min_text_length: 11 -# icon_color: app.theme_cls.primary_color -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} -# on_touch_down: app.change_cursor(True) -# on_touch_up: app.change_cursor(False) -# canvas.before: -# Color: -# rgb: rgba(127, 127, 127, 255) -# Line: -# width: dp(0.5) -# rounded_rectangle: self.x-5, self.y+20, self.width+10, self.height-25, 10,10,10,10,100 - -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDRelativeLayout: -# size_hint_y: None -# height: "5dp" -# MDLabel: -# text: "Semester" -# color: rgba(0, 0, 0, 255) -# font_name: "BPoppins" -# font_size: '15sp' -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} - - -# MDRelativeLayout: -# size_hint_y: None -# height: "60dp" -# MDTextField: -# id: signup_sem -# hint_text: "Semester*" -# font_name: "MPoppins" -# font_size: "15sp" -# helper_text: "Provide your Branch" -# helper_text_mode: "on_focus" -# icon_right: "roman-numeral-2" -# min_text_length: 11 -# icon_color: app.theme_cls.primary_color -# size_hint_x: None -# width: dp(335) -# pos_hint: {"center_x": 0.5, "center_y": 0.5} -# on_touch_down: app.change_cursor(True) -# on_touch_up: app.change_cursor(False) -# canvas.before: -# Color: -# rgb: rgba(127, 127, 127, 255) -# Line: -# width: dp(0.5) -# rounded_rectangle: self.x-5, self.y+20, self.width+10, self.height-25, 10,10,10,10,100 - -# MDRelativeLayout: -# size_hint_y: None -# height: "65dp" -# Button: -# text: "Get OTP" -# font_name: "BPoppins" -# size_hint: None, None -# width: dp(300) -# height: dp(59) -# pos_hint: {'center_x': 0.5, 'center_y': 1} -# background_color: 0,0,0,0 -# on_touch_down: app.change_cursor(True) -# on_touch_up: app.change_cursor(False) -# on_release: -# root.manager.transition.direction = "up" -# app.otp_button_fun(False) -# app.on_start() -# app.check_signup(signup_name.text, signup_prn.text, signup_email.text, signup_no.text, signup_pass.text, signup_branch.text, signup_sem.text) -# canvas.before: -# Color: -# rgb: rgba(52, 0, 231, 255) -# RoundedRectangle: -# size: self.size -# pos: self.pos -# radius: [10] - -: - - MDFloatLayout: - anchor_x: 'center' - anchor_y: 'center' - MDIconButton: - icon: "arrow-left" - pos_hint: {'center_y': 0.95} - user_font_size: "30sp" - theme_text_color: "Custom" - text_color: rgba(26,24,58,255) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - root.manager.transition.direction= 'up' - root.manager.current= "login" - app.on_press_back_arrow() - - MDLabel: - text: "Forget Your Password?" - font_name: "BPoppins" - font_size: "26sp" - pos_hint: {'center_x': 0.55,'center_y': 0.85} - color: rgba(0, 0, 59, 255) - - - MDLabel: - text: "That's Okay. It happens!" - font_name: "MPoppins" - font_size: "18sp" - pos_hint: {'center_x': 0.55,'center_y': 0.8} - color: rgba(135, 133, 193, 255) - - MDLabel: - text: "Provide your Whatsapp No. for reset Password " - font_name: "MPoppins" - font_size: "13sp" - size_hint:0.91 , 0.8 - pos_hint: {'center_x': 0.55,'center_y': 0.7} - color: rgba(135, 133, 193, 255) - - - MDTextField: - id: forgotPass_no - hint_text: "Enter WhatsApp Number" - font_name: "MPoppins" - helper_text: "or click on for login through username" - helper_text_mode: "on_focus" - icon_right: "dialpad" - input_filter: 'int' - min_text_length: 10 - max_text_length:10 - icon_color: app.theme_cls.primary_color - pos_hint: {"center_x": 0.5, "center_y": 0.6} - size_hint_x: None - width: dp(335) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - - Button: - text: "Get OTP" - font_name: "BPoppins" - size_hint: None, 0.065 - width: dp(350) - pos_hint: {'center_x': 0.5, 'center_y': 0.45} - background_color: 0,0,0,0 - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - app.on_start() - root.manager.transition.direction = "up" - app.otp_button_fun("True") - # app.verify_no() - canvas.before: - Color: - rgb: rgba(52, 0, 231, 255) - RoundedRectangle: - size: self.size - pos: self.pos - radius: [5] - -: - MDFloatLayout: - mg_bd_color: 1,1,1,1 - MDIconButton: - id : back_button - icon: "arrow-left" - pos_hint: {'center_y': 0.95} - user_font_size: "30sp" - theme_text_color: "Custom" - text_color: rgba(26,24,58,255) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - app.otp_back_arrow_fun() - root.manager.transition.direction= 'down' - - - MDLabel: - text: "V e r i f i n g Y o u...!" - font_name: "BPoppins" - font_size: "26sp" - pos_hint: {'center_x': 0.55,'center_y': 0.75} - - color: rgba(0, 0, 59, 255) - - - - - AnchorLayout: - anchor_x: 'center' - anchor_y: 'center' - - BoxLayout: - orientation: "vertical" - size_hint: None, None - size: self.minimum_size - MDLabel: - text: "One time password (OTP) has been shared on your Whatsapp number. Please check and enter here.." - font_name: "MPoppins" - font_size: "13sp" - size_hint_x: .85 - pos_hint: {'center_x': 0.5,'center_y': 1} - color: rgba(135, 133, 193, 255) - - MDBoxLayout: - orientation: 'horizontal' - spacing: dp(35) - padding: dp(50) - size_hint: None, None - size: self.minimum_size - - MDTextField: - id: d1 - hint_text: "" - font_name: "MPoppins" - font_size: "25sp" - pos_hint: {"center_x": 0.2, "center_y": 0.6} - size_hint_x: None - width: dp(37.5) - multiline: False - max_text_length: 1 - input_filter: 'int' - halign : 'center' - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - padding: 10 - spacing: 10 - canvas.before: - Color: - rgb: rgba(127, 127, 127, 255) - Line: - width: 0.5 - rounded_rectangle: self.x-12, self.y+20, self.width+25, self.height-25, 10,10,10,10,100 - MDTextField: - id: d2 - hint_text: "" - font_name: "MPoppins" - font_size: "25sp" - pos_hint: {"center_x": 0.4, "center_y": 0.6} - size_hint_x: None - width: dp(37.5) - multiline: False - max_text_length: 1 - input_filter: 'int' - halign : 'center' - on_touch_down: app.change_cursor(True) - padding: 10 - spacing: 10 - on_touch_up: app.change_cursor(False) - canvas.before: - Color: - rgb: rgba(127, 127, 127, 255) - Line: - width: 0.5 - rounded_rectangle: self.x-12, self.y+20, self.width+25, self.height-25, 10,10,10,10,100 - MDTextField: - id: d3 - hint_text: "" - font_name: "MPoppins" - font_size: "25sp" - pos_hint: {"center_x": 0.6, "center_y": 0.6} - size_hint_x: None - width: dp(37.5) - multiline: False - max_text_length: 1 - input_filter: 'int' - halign : 'center' - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - padding: 10 - spacing: 10 - canvas.before: - Color: - rgb: rgba(127, 127, 127, 255) - Line: - width: 0.5 - rounded_rectangle: self.x-12, self.y+20, self.width+25, self.height-25, 10,10,10,10,100 - - MDTextField: - id: d4 - hint_text: "" - font_name: "MPoppins" - font_size: "26sp" - pos_hint: {"center_x": 0.8, "center_y": 0.6} - size_hint_x: None - width: dp(37.5) - multiline: False - max_text_length: 1 - input_filter: 'int' - halign : 'center' - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - padding: 10 - spacing: 10 - canvas.before: - Color: - rgb: rgba(127, 127, 127, 255) - Line: - width: 0.5 - rounded_rectangle: self.x-12, self.y+20, self.width+25, self.height-25, 10,10,10,10,100 - - Button: - id: otp_button - text: "SignUp" - font_name: "BPoppins" - size_hint: 0.66, 0.065 - pos_hint: {'center_x': 0.5, 'center_y': 0.07} - background_color: 0,0,0,0 - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - root.manager.transition.direction = "up" - app.on_start() - app.verify_otp(d1.text, d2.text,d3.text,d4.text, self.text) - - canvas.before: - Color: - rgb: rgba(52, 0, 231, 255) - RoundedRectangle: - size: self.size - pos: self.pos - radius: [5] - - -: - MDFloatLayout: - md_bg_color: 1,1,1,1 - - - MDIconButton: - icon: "arrow-left" - pos_hint: {'center_y': 0.95} - user_font_size: "30sp" - theme_text_color: "Custom" - text_color: rgba(26,24,58,255) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - root.manager.transition.direction= 'down' - root.manager.current= "main" - app.on_press_back_arrow() - - MDLabel: - text: "Reset Password!" - font_name: "BPoppins" - font_size: "26sp" - pos_hint: {'center_x': 0.6,'center_y': 0.85} - color: rgba(0, 0, 59, 255) - - MDRelativeLayout: - size: self.width, self.height - MDTextField: - id : new_pass - font_name: "MPoppins" - font_size: "15sp" - hint_text: "New Password" - helper_text: "must contain 8 char* with at least one 'a' , 'A' , '@' & '0'" - helper_text_mode: "on_focus" - pos_hint: {"center_x": 0.5, "center_y": 0.63} - size_hint_x: None - min_text_length: 8 - width: dp(335) - password:True - on_focus: app.focus_text_field(icon, self.focus, "sign_pass") - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - canvas.before: - Color: - rgb: rgba(127, 127, 127, 255) - Line: - width: dp(0.5) - rounded_rectangle: self.x-5, self.y+20, self.width+10, self.height-25, 10,10,10,10,100 - - MDIconButton: - id: icon - icon: 'eye-off' - theme_icon_color: "Custom" - icon_color: rgba(210, 210, 210, 255) - size_hint: None, None - size: dp(24), dp(24) - pos: new_pass.x + new_pass.width - self.width + dp(4), new_pass.center_y - self.height / 2 + dp(5) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - app.toggle_password_visibility(new_pass, self) - new_pass.focus=True - MDRelativeLayout: - size: self.width, self.height - MDTextField: - id : new_pass1 - font_name: "MPoppins" - font_size: "15sp" - hint_text: "Re-enter Password" - helper_text: "must contain 8 char* with at least one 'a' , 'A' , '@' & '0'" - helper_text_mode: "on_focus" - pos_hint: {"center_x": 0.5, "center_y": 0.53} - size_hint_x: None - min_text_length: 8 - width: dp(335) - password:True - on_focus: app.focus_text_field(icon1, self.focus) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - canvas.before: - Color: - rgb: rgba(127, 127, 127, 255) - Line: - width: dp(0.5) - rounded_rectangle: self.x-5, self.y+20, self.width+10, self.height-25, 10,10,10,10,100 - - - MDIconButton: - id: icon1 - icon: 'eye-off' - theme_icon_color: "Custom" - icon_color: rgba(210, 210, 210, 255) - size_hint: None, None - size: dp(24), dp(24) - pos: new_pass1.x + new_pass1.width - self.width+dp(4), new_pass1.center_y - self.height / 2+dp(5) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - app.toggle_password_visibility(new_pass1, self) - new_pass1.focus=True - - Button: - text: "Change Password" - font_name: "BPoppins" - size_hint:None, None - width: dp(300) - height: dp(59) - pos_hint: {'center_x': 0.5, 'center_y': 0.37} - background_color: 0,0,0,0 - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - root.manager.transition.direction = "up" - app.reset_password() - app.on_start() - - canvas.before: - Color: - rgb: rgba(52, 0, 231, 255) - RoundedRectangle: - size: self.size - pos: self.pos - radius: [5] - : MDFloatLayout: @@ -1393,33 +527,12 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 md_bg_color: [1,1,1,1] spacing: "2dp" MDLabel: - id: profile_name + id: profile_user_name text: "" halign: 'center' Widget: - # MDBottomAppBar: - # height: "62dp" - # elevation: 10 - # MDActionBottomAppBarButton: - # icon: "home" - # pos_hint:{'center_x':0.15, 'center_y': 0.5} - # on_press: root.manager.current = 'home' - # MDActionBottomAppBarButton: - # icon: "tools" - # pos_hint:{'center_x':0.38, 'center_y': 0.5} - # on_press: root.manager.current = 'borrow_book' - # MDActionBottomAppBarButton: - # icon: "thumb-up-outline" - # pos_hint:{'center_x':0.61, 'center_y': 0.5} - # on_press: root.manager.current = 'recommend' - # MDActionBottomAppBarButton: - # icon: "history" - # pos_hint:{'center_x':0.85, 'center_y': 0.5} - # on_press: - # root.manager.current = 'history' - # app.book_history() MDIconButton: icon: "arrow-left" @@ -1468,12 +581,12 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 MDList: spacing: "0dp" OneLineIconListItem: - text: profile_name.text + text: profile_user_name.text IconLeftWidget: icon: "account-outline" OneLineIconListItem: - id : profile_email + id : profile_user_pass text: "" IconLeftWidget: icon: "email-outline" @@ -1483,7 +596,7 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 IconLeftWidget: icon: "dialpad" OneLineIconListItem: - id : profile_number + id : profile_wifi_ssid text: "" IconLeftWidget: icon: "phone-outline" @@ -1591,157 +704,6 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 spacing: "50dp" -: - MDFloatLayout: - md_bg_color: 1,1,1,1 - - MDBottomAppBar: - height: "62dp" - elevation: 10 - MDActionBottomAppBarButton: - icon: "home" - pos_hint:{'center_x':0.15, 'center_y': 0.5} - on_press: root.manager.current = 'home' - MDActionBottomAppBarButton: - icon: "tools" - pos_hint:{'center_x':0.38, 'center_y': 0.5} - on_press: root.manager.current = 'borrow_book' - MDActionBottomAppBarButton: - icon: "thumb-up-outline" - pos_hint:{'center_x':0.61, 'center_y': 0.5} - on_press: root.manager.current = 'recommend' - MDActionBottomAppBarButton: - icon: "history" - pos_hint:{'center_x':0.85, 'center_y': 0.5} - on_press: - root.manager.current = 'history' - # app.book_history() - - - MDIconButton: - icon: "arrow-left" - pos_hint: {'center_y': 0.95} - user_font_size: "30sp" - theme_text_color: "Custom" - text_color: rgba(26,24,58,255) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - root.manager.transition.direction= 'right' - app.clear_text() - root.manager.current= "home" - app.on_press_back_arrow() - - MDLabel: - text: "Discover Your Next Adventure!" - font_name: "BPoppins" - font_size: "24sp" - size_hint_x: None - width: dp(400) - padding:"12dp" - pos_hint: {'center_x': 0.5,'center_y': 0.87} - color: rgba(0, 0, 59, 255) - - MDTextField: - id: book_input - hint_text: 'Enter a Title...' - font_name: "MPoppins" - font_size: "15sp" - helper_text_mode: "on_focus" - icon_right: "search" - icon_color: app.theme_cls.primary_color - pos_hint: {"center_x": 0.5, "center_y": 0.77} - size_hint_x: None - width: dp(335) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - - MDRaisedButton: - text: "Get Recommendations" - pos_hint: {"center_x": 0.5, "center_y": 0.67} - on_release: app.get_recommendations() - - MDLabel: - id: rec_label - text: "" - halign: "center" - pos_hint: {"center_x": 0.5, "center_y": 0.4} - - MDBoxLayout: - id : rec_grid - orientation:'vertical' - pos_hint: {'center_x': 0.5, 'center_y': 0.367} - size_hint:(1,0.53) - -: - MDFloatLayout: - md_bg_color: 1,1,1,1 - MDBottomAppBar: - height: "62dp" - elevation: 10 - MDActionBottomAppBarButton: - icon: "home" - pos_hint:{'center_x':0.15, 'center_y': 0.5} - on_press: root.manager.current = 'home' - MDActionBottomAppBarButton: - icon: "tools" - pos_hint:{'center_x':0.38, 'center_y': 0.5} - on_press: root.manager.current = 'borrow_book' - MDActionBottomAppBarButton: - icon: "thumb-up-outline" - pos_hint:{'center_x':0.61, 'center_y': 0.5} - on_press: root.manager.current = 'recommend' - MDActionBottomAppBarButton: - icon: "history" - pos_hint:{'center_x':0.85, 'center_y': 0.5} - on_press: - root.manager.current = 'history' - # app.book_history() - - - MDIconButton: - icon: "arrow-left" - pos_hint: {'center_y': 0.95} - user_font_size: "30sp" - theme_text_color: "Custom" - text_color: rgba(26,24,58,255) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - root.manager.transition.direction= 'right' - app.clear_text() - root.manager.current= "home" - app.on_press_back_arrow() - MDLabel: - text: "Discover Your Next Adventure!" - font_name: "BPoppins" - font_size: "24sp" - size_hint_x: None - width: 400 - padding:"12dp" - pos_hint: {'center_x': 0.5,'center_y': 0.87} - color: rgba(0, 0, 59, 255) - - MDTextField: - id: search_field - hint_text: 'Search...' - font_name: "MPoppins" - font_size: "15sp" - helper_text_mode: "on_focus" - icon_right: "search" - icon_color: app.theme_cls.primary_color - pos_hint: {"center_x": 0.5, "center_y": 0.77} - size_hint_x: None - width: dp(335) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - - MDBoxLayout: - id : search_grid - orientation:'vertical' - pos_hint: {'center_x': 0.5, 'center_y': 0.415} - size_hint:(1,0.62) - : MDFloatLayout: md_bg_color: 1,1,1,1 @@ -2025,319 +987,6 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 app.otp_button_fun("1") root.manager.current="otp" -: - MDFloatLayout: - md_bg_color: 1,1,1,1 - MDBottomAppBar: - height: "62dp" - elevation: 10 - MDActionBottomAppBarButton: - icon: "home" - pos_hint:{'center_x':0.15, 'center_y': 0.5} - on_press: root.manager.current = 'home' - MDActionBottomAppBarButton: - icon: "tools" - pos_hint:{'center_x':0.38, 'center_y': 0.5} - on_press: root.manager.current = 'borrow_book' - MDActionBottomAppBarButton: - icon: "thumb-up-outline" - pos_hint:{'center_x':0.61, 'center_y': 0.5} - on_press: root.manager.current = 'recommend' - MDActionBottomAppBarButton: - icon: "history" - pos_hint:{'center_x':0.85, 'center_y': 0.5} - on_press: - root.manager.current = 'history' - # app.book_history() - - MDIconButton: - icon: "arrow-left" - pos_hint: {'center_y': 0.95} - user_font_size: "30sp" - theme_text_color: "Custom" - text_color: rgba(26,24,58,255) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - root.manager.transition.direction= 'right' - root.manager.current= "home" - app.on_press_back_arrow() - MDTextButton: - id : profile_edit - text: "All Notifications" - font_name: "RPac" - font_size: "18sp" - pos_hint: {'center_x': 0.62,'center_y': 0.95} - color: rgba(1,1,1, 255) - background_color: rgba(0,0,0,255) - -: - MDFloatLayout: - orientation: 'vertical' - md_bd_color: 1,1,1,1 - anchor_x: 'center' - anchor_y: 'center' - MDBottomAppBar: - height: "62dp" - elevation: 10 - MDActionBottomAppBarButton: - icon: "home" - pos_hint:{'center_x':0.15, 'center_y': 0.5} - on_press: root.manager.current = 'home' - MDActionBottomAppBarButton: - icon: "tools" - pos_hint:{'center_x':0.38, 'center_y': 0.5} - on_press: root.manager.current = 'borrow_book' - MDActionBottomAppBarButton: - icon: "thumb-up-outline" - pos_hint:{'center_x':0.61, 'center_y': 0.5} - on_press: root.manager.current = 'recommend' - MDActionBottomAppBarButton: - icon: "history" - pos_hint:{'center_x':0.85, 'center_y': 0.5} - on_press: - root.manager.current = 'history' - # app.book_history() - - - - MDIconButton: - icon: "arrow-left" - pos_hint: {'center_y': 0.95} - theme_text_color: "Custom" - text_color: rgba(26,24,58,255) - size_hint_x: None - width: dp(500) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - root.manager.transition.direction= 'right' - root.manager.current= "home" - app.on_press_back_arrow() - - MDLabel: - text: "Want to read Book?" - font_name: "BPoppins" - font_size: "26sp" - size_hint_x: None - width: dp(400) - padding:"12dp" - pos_hint: {'center_x': 0.5,'center_y': 0.85} - color: rgba(0, 0, 59, 255) - - - MDLabel: - text: "That's Good. Then borrow it!" - font_name: "MPoppins" - font_size: "18sp" - size_hint_x: None - width: dp(400) - padding:"12dp" - pos_hint: {'center_x': 0.5,'center_y': 0.8} - color: rgba(135, 133, 193, 255) - - MDLabel: - text: "Provide ISBN number of Book and get book for 10 days! " - font_name: "MPoppins" - font_size: "13sp" - size_hint_y: 0.8 - size_hint_x: None - width: dp(400) - padding:"12dp" - pos_hint: {'center_x': 0.5,'center_y': 0.65} - color: rgba(135, 133, 193, 255) - - - MDTextField: - id: isbn - text : "" - hint_text: "ISBN number" - font_name: "MPoppins" - font_size: "15sp" - helper_text_mode: "on_focus" - icon_right: "book" - icon_color: app.theme_cls.primary_color - max_text_length: 13 - pos_hint: {"center_x": 0.5, "center_y": 0.55} - size_hint_x: None - width: dp(350) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - canvas.before: - Color: - rgb: rgba(127, 127, 127, 255) - Line: - width: dp(0.5) - rounded_rectangle: self.x-5, self.y+20, self.width+10, self.height-25, 10,10,10,10,100 - Button: - text: "Get Book" - font_name: "BPoppins" - size_hint_y: 0.065 - size_hint_x: None - width: dp(350) - pos_hint: {'center_x': 0.5, 'center_y': 0.4} - background_color: 0,0,0,0 - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: app.get_book(isbn.text) - canvas.before: - Color: - rgb: rgba(52, 0, 231, 255) - RoundedRectangle: - size: self.size - pos: self.pos - radius: [10] - - - -: - MDFloatLayout: - orientation: 'vertical' - md_bd_color: 1,1,1,1 - anchor_x: 'center' - anchor_y: 'center' - MDBottomAppBar: - height: "62dp" - elevation: 10 - MDActionBottomAppBarButton: - icon: "home" - pos_hint:{'center_x':0.15, 'center_y': 0.5} - on_release: - root.manager.transition.direction= 'right' - root.manager.current= "home" - MDActionBottomAppBarButton: - icon: "tools" - pos_hint:{'center_x':0.38, 'center_y': 0.5} - on_press: root.manager.current = 'borrow_book' - MDActionBottomAppBarButton: - icon: "thumb-up-outline" - pos_hint:{'center_x':0.61, 'center_y': 0.5} - on_press: root.manager.current = 'recommend' - MDActionBottomAppBarButton: - icon: "history" - pos_hint:{'center_x':0.85, 'center_y': 0.5} - on_press: - root.manager.current = 'history' - # app.book_history() - - - - MDIconButton: - icon: "arrow-left" - pos_hint: {'center_y': 0.95} - theme_text_color: "Custom" - text_color: rgba(26,24,58,255) - size_hint_x: None - width: dp(500) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - root.manager.transition.direction= 'right' - root.manager.current= "home" - - MDLabel: - text: "Done reading the Book?" - font_name: "BPoppins" - font_size: "24sp" - size_hint_x: None - width: dp(400) - padding:"12dp" - pos_hint: {'center_x': 0.5,'center_y': 0.9} - color: rgba(0, 0, 59, 255) - - - MDLabel: - text: "Return, recharge, and read on!" - font_name: "MPoppins" - font_size: "18sp" - size_hint_x: None - width: dp(400) - padding:"12dp" - pos_hint: {'center_x': 0.5,'center_y': 0.85} - color: rgba(135, 133, 193, 255) - - ScrollView: - size_hint: 1, None - height: self.parent.height - dp(150) - pos_hint: {'top':0.81} - MDList: - id : image_label_grid - padding: "1dp", "50dp", "12dp", "30dp" - spacing: "50dp" - - -: - MDFloatLayout: - orientation: 'vertical' - md_bd_color: 1,1,1,1 - anchor_x: 'center' - anchor_y: 'center' - MDBottomAppBar: - height: "62dp" - elevation: 10 - MDActionBottomAppBarButton: - icon: "home" - pos_hint:{'center_x':0.15, 'center_y': 0.5} - on_press: root.manager.current = 'home' - MDActionBottomAppBarButton: - icon: "tools" - pos_hint:{'center_x':0.38, 'center_y': 0.5} - on_press: root.manager.current = 'borrow_book' - MDActionBottomAppBarButton: - icon: "thumb-up-outline" - pos_hint:{'center_x':0.61, 'center_y': 0.5} - on_press: root.manager.current = 'recommend' - MDActionBottomAppBarButton: - icon: "history" - pos_hint:{'center_x':0.85, 'center_y': 0.5} - on_press: - root.manager.current = 'history' - # app.book_history() - - - - MDIconButton: - icon: "arrow-left" - pos_hint: {'center_y': 0.95} - theme_text_color: "Custom" - text_color: rgba(26,24,58,255) - size_hint_x: None - width: dp(500) - on_touch_down: app.change_cursor(True) - on_touch_up: app.change_cursor(False) - on_release: - root.manager.transition.direction= 'right' - root.manager.current= "home" - - MDLabel: - text: "Keep the Story Alive!" - font_name: "BPoppins" - font_size: "24sp" - size_hint_x: None - width: dp(400) - padding:"12dp" - pos_hint: {'center_x': 0.5,'center_y': 0.9} - color: rgba(0, 0, 59, 255) - - - MDLabel: - text: "Keep reading, keep growing.!" - font_name: "MPoppins" - font_size: "18sp" - size_hint_x: None - width: dp(400) - padding:"12dp" - pos_hint: {'center_x': 0.5,'center_y': 0.85} - color: rgba(135, 133, 193, 255) - - ScrollView: - size_hint: 1, None - height: self.parent.height - dp(150) - pos_hint: {'top':0.81} - MDList: - id : renew_grid - padding: "1dp", "50dp", "12dp", "30dp" - spacing: "50dp" : MDFloatLayout: # 使用浮动布局,可以自由控制子组件的位置 @@ -2402,122 +1051,97 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 padding: "20dp", "40dp", "12dp", "17dp" spacing: "50dp" - MDLabel: - text: "测试" - font_name: "BPoppins" - font_size: "24sp" - pos_hint: {'center_x': 0.45} - halign: 'center' - bold: True - color: rgba(0, 0, 0, 255) - MDLabel: - text: "曲线" - font_name: "BPoppins" - font_size: "24sp" - size_hint_x: None - width: dp(400) - padding: "12dp" - pos_hint: {'center_x': 0.5, 'center_y': 0.9} - color: rgba(0, 0, 59, 255) + # MDLabel: + # text: "测试" + # font_name: "BPoppins" + # font_size: "24sp" + # pos_hint: {'center_x': 0.45} + # halign: 'center' + # bold: True + # color: rgba(0, 0, 0, 255) + # MDLabel: + # text: "曲线" + # font_name: "BPoppins" + # font_size: "24sp" + # size_hint_x: None + # width: dp(400) + # padding: "12dp" + # pos_hint: {'center_x': 0.5, 'center_y': 0.9} + # color: rgba(0, 0, 59, 255) - MDLabel: - id: register_label - text: "[u]通信超时: [/u]" # 下划线样式提示可点击 - font_name: "MPoppins" - font_size: "18sp" + BoxLayout: + orientation: 'horizontal' size_hint_x: None width: dp(400) - padding: "12dp" pos_hint: {'center_x': 0.5, 'center_y': 0.85} - color: (135/255, 133/255, 193/255, 1) - markup: True # 启用标记以显示下划线 - on_touch_down: - # if self.collide_point(*args[1].pos): - app.show_modify_dialog("register_label", " ") # 与if同层级缩进 - MDLabel: - id: register_label - text: "[u]通信超时: [/u]" # 下划线样式提示可点击 - font_name: "MPoppins" - font_size: "18sp" - size_hint_x: None - width: dp(400) - padding: "12dp" - pos_hint: {'center_x': 0.5, 'center_y': 0.85} - color: (135/255, 133/255, 193/255, 1) - markup: True # 启用标记以显示下划线 - on_touch_down: - # if self.collide_point(*args[1].pos): - app.show_modify_dialog("register_label", " ") # 与if同层级缩进 - MDLabel: - id: register_label - text: "[u]通信超时: [/u]" # 下划线样式提示可点击 - font_name: "MPoppins" - font_size: "18sp" - size_hint_x: None - width: dp(400) - padding: "12dp" - pos_hint: {'center_x': 0.5, 'center_y': 0.85} - color: (135/255, 133/255, 193/255, 1) - markup: True # 启用标记以显示下划线 - on_touch_down: - # if self.collide_point(*args[1].pos): - app.show_modify_dialog("register_label", " ") # 与if同层级缩进 - MDLabel: - id: register_label - text: "[u]通信超时: [/u]" # 下划线样式提示可点击 - font_name: "MPoppins" - font_size: "18sp" - size_hint_x: None - width: dp(400) - padding: "12dp" - pos_hint: {'center_x': 0.5, 'center_y': 0.85} - color: (135/255, 133/255, 193/255, 1) - markup: True # 启用标记以显示下划线 - on_touch_down: - # if self.collide_point(*args[1].pos): - app.show_modify_dialog("register_label", " ") # 与if同层级缩进 - MDLabel: - id: register_label - text: "[u]通信超时: [/u]" # 下划线样式提示可点击 - font_name: "MPoppins" - font_size: "18sp" - size_hint_x: None - width: dp(400) - padding: "12dp" - pos_hint: {'center_x': 0.5, 'center_y': 0.85} - color: (135/255, 133/255, 193/255, 1) - markup: True # 启用标记以显示下划线 - on_touch_down: - # if self.collide_point(*args[1].pos): - app.show_modify_dialog("register_label", " ") # 与if同层级缩进 - MDLabel: - id: register_label - text: "[u]通信超时: [/u]" # 下划线样式提示可点击 - font_name: "MPoppins" - font_size: "18sp" - size_hint_x: None - width: dp(400) - padding: "12dp" - pos_hint: {'center_x': 0.5, 'center_y': 0.85} - color: (135/255, 133/255, 193/255, 1) - markup: True # 启用标记以显示下划线 - on_touch_down: - # if self.collide_point(*args[1].pos): - app.show_modify_dialog("register_label", " ") # 与if同层级缩进 - MDLabel: - id: register_label - text: "[u]通信超时: [/u]" # 下划线样式提示可点击 - font_name: "MPoppins" - font_size: "18sp" - size_hint_x: None - width: dp(400) - padding: "12dp" - pos_hint: {'center_x': 0.5, 'center_y': 0.85} - color: (135/255, 133/255, 193/255, 1) - markup: True # 启用标记以显示下划线 - on_touch_down: - # if self.collide_point(*args[1].pos): - app.show_modify_dialog("register_label", " ") # 与if同层级缩进 + spacing: dp(10) + + MDLabel: + text: "寄存器 0:" + font_name: "MPoppins" + font_size: "18sp" + color: (135/255, 133/255, 193/255, 1) + size_hint_x: None + width: dp(120) + halign: "left" + + MDTextField: + id: register_value_field_0 + comm_address: 0 + text: "" + font_name: "MPoppins" + font_size: "18sp" + size_hint_x: None + width: dp(120) + halign: "right" + input_filter: "int" + on_focus:if not self.focus: app.update_register_display(0) + on_text_validate: app.modify_register(self, self.text) + + MDLabel: + text: "寄存器 1:" + font_name: "MPoppins" + font_size: "18sp" + color: (135/255, 133/255, 193/255, 1) + size_hint_x: None + width: dp(120) + halign: "left" + + MDTextField: + id: register_value_field_1 + comm_address: 1 + text: "" + font_name: "MPoppins" + font_size: "18sp" + size_hint_x: None + width: dp(120) + halign: "right" + input_filter: "int" + on_focus:if not self.focus: app.update_register_display(0) + on_text_validate: app.modify_register(self, self.text) + + MDLabel: + text: "寄存器 2:" + font_name: "MPoppins" + font_size: "18sp" + color: (135/255, 133/255, 193/255, 1) + size_hint_x: None + width: dp(120) + halign: "left" + + MDTextField: + id: register_value_field_2 + comm_address: 2 + text: "" + font_name: "MPoppins" + font_size: "18sp" + size_hint_x: None + width: dp(120) + halign: "right" + input_filter: "int" + on_focus:if not self.focus: app.update_register_display(0) + on_text_validate: app.modify_register(self, self.text) + # CurveWidget: # size_hint_y: None # height: dp(300) @@ -2567,7 +1191,7 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 app.on_press_back_arrow() MDLabel: - text: "Reading Chronicle" + text: "测试" font_name: "BPoppins" font_size: "24sp" size_hint_x: None @@ -2578,7 +1202,7 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 MDLabel: - text: "Reflecting on Read and Returned" + text: "测试" font_name: "MPoppins" font_size: "18sp" size_hint_x: None @@ -2711,7 +1335,7 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 app.on_press_back_arrow() MDLabel: - text: "Reading Chronicle" + text: "测试" font_name: "BPoppins" font_size: "24sp" size_hint_x: None @@ -2722,7 +1346,7 @@ ScreenManager: # 屏幕管理器,用于管理应用中所有的屏幕及其 MDLabel: - text: "Reflecting on Read and Returned" + text: "测试" font_name: "MPoppins" font_size: "18sp" size_hint_x: None diff --git a/main.py b/main.py index ee15973..0f643e7 100644 --- a/main.py +++ b/main.py @@ -15,7 +15,7 @@ from kivy.lang import Builder from kivy.uix.screenmanager import ScreenManager, Screen from kivymd.uix.datatables import MDDataTable import random - +import threading import csv from kivymd.uix.textfield import MDTextField from kivymd.uix.boxlayout import MDBoxLayout @@ -31,9 +31,14 @@ from kivy.uix.widget import Widget from kivy.graphics import Color, Rectangle from kivy_garden.graph import Graph, LinePlot -from modbus_tk.modbus_tcp import TcpMaster +import modbus_tk import modbus_tk.defines as cst import socket +from modbus_client import ModbusClient +import re +from threading import Thread +from functools import partial +from collections import defaultdict from random import randint from kivymd.theming import ThemeManager @@ -45,10 +50,6 @@ LabelBase.register(name="RCro", fn_regular="fonts/Chinese/msyh.ttf") LabelBase.register(name="RPac", fn_regular="fonts/Chinese/msyh.ttf") - -def get_books(): - pass - class MainScreen(Screen): pass class HomeScreen(Screen): @@ -80,42 +81,17 @@ class AboutScreen(Screen): about = ObjectProperty(None) -class SignUpScreen(Screen): - signup = ObjectProperty(None) -class ForgetPassScreen(Screen): - forget_Password = ObjectProperty(None) -class OtpScreen(Screen): - otp = ObjectProperty(None) -class ResetPassScreen(Screen): - reset_pass = ObjectProperty(None) -class SearchBookScreen(Screen): - search_book = ObjectProperty(None) -class NotificationScreen(Screen): - notifications = ObjectProperty(None) -class RecommendScreen(Screen): - recommendation = ObjectProperty(None) -class BorrowBookScreen(Screen): - borrow_book = ObjectProperty(None) -class ReturnBookScreen(Screen): - return_book = ObjectProperty(None) -class RenewBookScreen(Screen): - renew_book = ObjectProperty(None) - - - - # Window.size = (dp(360), dp(680)) class app(MDApp): wifi_status_text = StringProperty("") def __init__(self): super().__init__() - self.signup_sem = None self.signup_branch = None self.user_name = None - self.book_pos_name = None - self.book_pos = None - self.rec_label = None + + + self.rec_grid = None self.recommend_screen = None self.book_input = None @@ -142,14 +118,14 @@ class app(MDApp): self.edit_email = None self.edit_prn = None self.edit_name = None - self.edit_number = None + self.edit_wifi_ssid = None self.edit_branch = None self.profile_semester = None self.profile_branch = None - self.profile_number = None + self.profile_wifi_ssid = None self.profile_prn = None - self.profile_email = None - self.profile_name = None + self.profile_user_pass = None + self.profile_user_name = None self.user_no = None self.user_email = None self.user_prn = None @@ -166,7 +142,7 @@ class app(MDApp): self.password = None self.username = None - self.modbus_master = None # Modbus连接对象 + self.modbus_master = ModbusClient() # Modbus连接对象 self.modbus_ip = None # Modbus服务器IP self.modbus_port = None # Modbus服务器端口 @@ -204,23 +180,9 @@ class app(MDApp): screen_manager.add_widget(ControlCommandScreen(name="control_command")) screen_manager.add_widget(AboutScreen(name="about")) - screen_manager.add_widget(SignUpScreen(name="signup")) - screen_manager.add_widget(ForgetPassScreen(name="forgot_pass")) - screen_manager.add_widget(OtpScreen(name="otp")) - screen_manager.add_widget(ResetPassScreen(name="reset_pass")) - screen_manager.add_widget(NotificationScreen(name="notification")) - screen_manager.add_widget(SearchBookScreen(name="searchBook")) - screen_manager.add_widget(RecommendScreen(name="recommend")) - screen_manager.add_widget(BorrowBookScreen(name="borrow_book")) - screen_manager.add_widget(ReturnBookScreen(name="return_book")) - screen_manager.add_widget(RenewBookScreen(name="renew_book")) + # 添加其他屏幕 - Clock.schedule_once(self.update_wifi_status, 2) - - - # Clock.schedule_interval(self.update_register_display, 1) - return screen_manager #############################################ALL INPUT TEXT############################################################ @@ -228,79 +190,27 @@ class app(MDApp): # 从根窗口中获取名为"login"的屏幕(登录界面) login_screen = self.root.get_screen("login") - # 通过界面ID获取登录界面中的用户名输入框组件 - # self.username = login_screen.ids.username - # 通过界面ID获取登录界面中的密码输入框组件 - # self.password = login_screen.ids.password + # 从根窗口中获取名为"home"的屏幕(主界面) home_screen = self.root.get_screen("home") # 通过界面ID获取主界面中的用户信息组件 self.user = home_screen.ids.user - # 通过界面ID获取主界面中的书架位置名称组件 - self.book_pos_name = home_screen.ids.book_pos_name - # 通过界面ID获取主界面中的书架位置组件 - self.book_pos = home_screen.ids.book_pos - - # 从根窗口中获取名为"forgot_pass"的屏幕(忘记密码界面) - forgot_pass_screen = self.root.get_screen("forgot_pass") - # 通过界面ID获取忘记密码界面中的手机号输入框组件 - self.mobile_no = forgot_pass_screen.ids.forgotPass_no - - # 从根窗口中获取名为"reset_pass"的屏幕(重置密码界面) - reset_pass_screen = self.root.get_screen("reset_pass") - # 通过界面ID获取重置密码界面中的新密码输入框组件 - self.new_pass = reset_pass_screen.ids.new_pass - # 通过界面ID获取重置密码界面中的确认新密码输入框组件 - self.new_pass1 = reset_pass_screen.ids.new_pass1 - - # 从根窗口中获取名为"otp"的屏幕(验证码界面) - otp_screen = self.root.get_screen("otp") - # 通过界面ID获取验证码界面中的"验证"按钮组件 - self.otp_button = otp_screen.ids.otp_button - # 通过界面ID获取验证码界面中的"返回"按钮组件 - self.back_button = otp_screen.ids.back_button - # 通过界面ID获取验证码界面中的第一个数字输入框组件 - self.d1 = otp_screen.ids.d1 - # 通过界面ID获取验证码界面中的第二个数字输入框组件 - self.d2 = otp_screen.ids.d2 - # 通过界面ID获取验证码界面中的第三个数字输入框组件 - self.d3 = otp_screen.ids.d3 - # 通过界面ID获取验证码界面中的第四个数字输入框组件 - self.d4 = otp_screen.ids.d4 - - # 从根窗口中获取名为"signup"的屏幕(注册界面) - # signup_screen = self.root.get_screen("signup") - # 通过界面ID获取注册界面中的用户名输入框组件 - # self.user_name = signup_screen.ids.signup_name - # 通过界面ID获取注册界面中的PRN(可能是学号/身份标识)输入框组件 - # self.user_prn = signup_screen.ids.signup_prn - # 通过界面ID获取注册界面中的邮箱输入框组件 - # self.user_email = signup_screen.ids.signup_email - # 通过界面ID获取注册界面中的手机号输入框组件 - # self.user_no = signup_screen.ids.signup_no - # 通过界面ID获取注册界面中的密码输入框组件 - # self.user_pass = signup_screen.ids.signup_pass - # 通过界面ID获取注册界面中的所属部门/专业选择组件 - # self.signup_branch = signup_screen.ids.signup_branch - # 通过界面ID获取注册界面中的年级/学期选择组件 - # self.signup_sem = signup_screen.ids.signup_sem # 从根窗口中获取名为"profile"的屏幕(个人资料界面) profile_screen = self.root.get_screen("profile") # 通过界面ID获取个人资料界面中的姓名展示组件 - self.profile_name = profile_screen.ids.profile_name + self.profile_user_name = profile_screen.ids.profile_user_name # 通过界面ID获取个人资料界面中的邮箱展示组件 - self.profile_email = profile_screen.ids.profile_email + self.profile_user_pass = profile_screen.ids.profile_user_pass # 通过界面ID获取个人资料界面中的PRN(身份标识)展示组件 self.profile_prn = profile_screen.ids.profile_prn # 通过界面ID获取个人资料界面中的手机号展示组件 - self.profile_number = profile_screen.ids.profile_number + self.profile_wifi_ssid = profile_screen.ids.profile_wifi_ssid # 通过界面ID获取个人资料界面中的所属部门/专业展示组件 self.profile_branch = profile_screen.ids.profile_branch # 通过界面ID获取个人资料界面中的年级/学期展示组件 self.profile_semester = profile_screen.ids.profile_semester - # 从根窗口中获取名为"profile_edit"的屏幕(个人资料编辑界面) self.profile_edit_screen = self.root.get_screen("profile_edit") # 通过界面ID获取资料编辑界面中的姓名编辑输入框组件 @@ -310,50 +220,16 @@ class app(MDApp): # 通过界面ID获取资料编辑界面中的PRN(身份标识)编辑输入框组件 self.edit_prn = self.profile_edit_screen.ids.edit_prn # 通过界面ID获取资料编辑界面中的手机号编辑输入框组件 - self.edit_number = self.profile_edit_screen.ids.edit_no + self.edit_wifi_ssid = self.profile_edit_screen.ids.edit_no # 通过界面ID获取资料编辑界面中的所属部门/专业编辑选择组件 self.edit_branch = self.profile_edit_screen.ids.edit_branch # 通过界面ID获取资料编辑界面中的年级/学期编辑选择组件 self.edit_semester = self.profile_edit_screen.ids.edit_sem - # 从根窗口中获取名为"borrow_book"的屏幕(借书界面) - borrow_screen = self.root.get_screen("borrow_book") - # 通过界面ID获取借书界面中的ISBN(图书编号)输入框组件 - self.isbn = borrow_screen.ids.isbn - - # 从根窗口中获取名为"return_book"的屏幕(还书界面) - return_book_screen = self.root.get_screen("return_book") - # 通过界面ID获取还书界面中的图片与标签网格布局组件 - self.image_label_grid = return_book_screen.ids.image_label_grid - - # 从根窗口中获取名为"renew_book"的屏幕(图书续借界面) - renew_book_screen = self.root.get_screen("renew_book") - # 通过界面ID获取续借界面中的网格布局组件 - self.renew_grid = renew_book_screen.ids.renew_grid - - # 从根窗口中获取名为"history"的屏幕(借阅历史界面) - history_screen = self.root.get_screen("history") - # 通过界面ID获取借阅历史界面中的网格布局组件 - self.history_grid = history_screen.ids.history_grid - - # 从根窗口中获取名为"searchBook"的屏幕(图书搜索界面) - search_book_screen = self.root.get_screen("searchBook") - # 通过界面ID获取图书搜索界面中的搜索输入框组件 - self.search_field = search_book_screen.ids.search_field - # 通过界面ID获取图书搜索界面中的搜索结果网格布局组件 - self.search_grid = search_book_screen.ids.search_grid - - # 从根窗口中获取名为"recommend"的屏幕(图书推荐界面) - self.recommend_screen = self.root.get_screen("recommend") - # 通过界面ID获取推荐界面中的图书输入框组件 - self.book_input = self.recommend_screen.ids.book_input - # 通过界面ID获取推荐界面中的推荐结果网格布局组件 - self.rec_grid = self.recommend_screen.ids.rec_grid - # 通过界面ID获取推荐界面中的推荐信息标签组件 - self.rec_label = self.recommend_screen.ids.rec_label self.root.bind(current=self.on_screen_changed) self.register_update_event = None + self.wifi_update_event = None def on_screen_changed(self, instance, value): """屏幕切换时启动/停止刷新""" @@ -366,79 +242,15 @@ class app(MDApp): if self.register_update_event: self.register_update_event.cancel() self.register_update_event = None - - # def update_register_display(self, dt): - # """更新原标签的显示内容""" - # # 仅在目标屏幕时更新 - # if self.root.current != "real_time_curve": - # return - # # 读取值并更新到原标签 - # value = self.read_modbus_register() - # real_time_screen = self.root.get_screen("real_time_curve") - # real_time_screen.ids.register_label.text = f"寄存器 0: {value}" # 直接更新原标签 - - def write_modbus_register(self, slave_id=1, address=0, value=None): - """ - 写入Modbus保持寄存器(单个寄存器) - :param slave_id: 从机ID(默认1) - :param address: 寄存器地址(默认0) - :param value: 要写入的值(必须为整数,16位范围内:0-65535) - :return: 操作结果字符串 - """ - # 检查Modbus连接是否初始化 - if not self.modbus_master: - return "错误:Modbus未连接,请先初始化连接" - # 检查写入值是否有效 - if value is None: - return "错误:未指定要写入的值" - try: - # 转换为整数并检查范围(Modbus保持寄存器通常为16位无符号整数) - write_value = int(value) - if not (0 <= write_value <= 65535): - return "错误:值必须在0-65535范围内(16位无符号整数)" - except ValueError: - return "错误:写入值必须为整数" - - try: - # 使用正确的写入函数:WRITE_SINGLE_REGISTER(写入单个寄存器) - self.modbus_master.execute( - slave=slave_id, - function_code=cst.WRITE_SINGLE_REGISTER, - starting_address=address, - output_value=write_value # 注意参数名是output_value - ) - return f"成功:从机ID={slave_id},寄存器地址={address},写入值={write_value}" - except Exception as e: - # 捕获异常并返回错误信息 - error_msg = f"失败:从机ID={slave_id},寄存器地址={address},错误信息:{str(e)}" - print(error_msg) - return error_msg + if value == "login": + if not self.wifi_update_event: + self.wifi_update_event = Clock.schedule_interval(self.update_wifi_status, 1) + else: + if self.wifi_update_event: + self.wifi_update_event.cancel() + self.wifi_update_event = None - def modify_register(self, input_text): - """处理修改请求,修改后更新原标签""" - if not input_text: - self.show_dialog("错误", "请输入值") - return - - try: - value = int(input_text) - # 这里假设写入 从机ID=1,地址=0 的寄存器 - # 若需要动态指定,可从界面控件中获取(例如:self.ids.slave_id.text) - result = self.write_modbus_register( - slave_id=1, - address=0, - value=value - ) - self.show_dialog("操作结果", result) - # 若成功,立即刷新显示 - if "成功" in result: - self.update_register_display(0) # 0是dt参数占位符 - except ValueError: - self.show_dialog("错误", "请输入有效整数") - - def show_dialog(self, title, message): - self.dialog1(message,title) #############################################@Frequently used functions################################################## @staticmethod @@ -467,70 +279,14 @@ class app(MDApp): icon_button.icon = "eye-off" def clear_text(self): - """清空界面中所有输入框和文本组件的内容""" - # 清空图书搜索框内容 - self.search_field.text = "" - # 清空图书推荐输入框内容 - self.book_input.text = "" - # 清空登录界面的用户名输入框内容 - # self.username.text = "" - # 清空登录界面的密码输入框内容 - # self.password.text = "" - # 清空忘记密码界面的手机号输入框内容 - self.mobile_no.text = "" - # 清空验证码界面的第一个输入框内容 - self.d1.text = "" - # 清空验证码界面的第二个输入框内容 - self.d2.text = "" - # 清空验证码界面的第三个输入框内容 - self.d3.text = "" - # 清空验证码界面的第四个输入框内容 - self.d4.text = "" - # 清空书架位置名称文本内容 - self.book_pos_name.text = "" - # 重置书架位置说明文本为示例内容 - self.book_pos.text = "测试内容示例" - # 再次清空手机号输入框(可能是为了确保完全清空) - self.mobile_no.text = "" - # 清空借书界面的ISBN输入框内容 - self.isbn.text = '' + pass def on_press_back_arrow(self): - # self.username.text = "" - # self.password.text = "" - self.mobile_no.text = "" - self.d1.text = "" - self.d2.text = "" - self.d3.text = "" - self.d4.text = "" + pass + - def focus_text_field(self, icon_button, focus, page): - if focus: - icon_button.icon_color = self.theme_cls.primary_color - elif page == "password": - icon_button.icon_color = 162 / 255, 169 / 255, 188 / 255, 1 - elif page == "sign_pass": - icon_button.icon_color = 217 / 255, 217 / 255, 217 / 255, 1 - else: - pass - def otp_button_fun(self, obj): - if obj == "True": - self.otp_button.text = "Reset Password" - elif obj == "1": - self.otp_button.text = "Edit Credentials" - elif obj == "2": - self.otp_button.text = "Verify OTP" - else: - self.otp_button.text = "Sign Up" - def otp_back_arrow_fun(self): - if self.otp_button.text == "Sign Up": - self.root.current = 'signup' - elif self.otp_button.text == "Reset Password": - self.root.current = 'reset_pass' - elif self.otp_button.text == "Verify OTP": - self.root.current = 'borrow_book' ############################################@DIALOG BOX most used functions############################################## # MDDialog box function 'dialog' @@ -638,70 +394,148 @@ class app(MDApp): self.dialog2.open() def confirm_modify(self, label_id): - """确认修改并更新标签""" - new_value = self.modify_input.text - if new_value: # 确保输入不为空 - # 根据标签ID获取对应的标签并更新 - screen = self.root.get_screen("real_time_curve") - if label_id == "register_label" and hasattr(screen.ids, label_id): - screen.ids[label_id].text = f"通信超时: {new_value}" # 更新标签显示 - self.modify_register(new_value) # 调用原有的修改方法 - self.dialog2.dismiss() # 关闭对话框 - - def read_modbus_registers(self, slave_id, address, count): - """ - 通用的Modbus保持寄存器读取函数 - :param slave_id: 从机ID(动态传入,如1、2、3等) - :param address: 寄存器地址 - :param count: 读取的寄存器数量 - :return: 读取结果或None(失败时) - """ - if not self.modbus_master: - print("Modbus未初始化,请先连接") - return None - + """确认修改并更新标签,增强鲁棒性""" try: - # 动态传入slave_id,替代固定的1 - result = self.modbus_master.execute( - slave=slave_id, - function_code=cst.READ_HOLDING_REGISTERS, - starting_address=address, - quantity_of_x=count - ) - print(f"从机ID {slave_id} 读取成功:{result}") - if result: - register_value = result[0] # 提取元组中的第一个元素(即0) - print(f"寄存器值:{register_value}") - return result + new_value = self.modify_input.text + if not new_value: + self.show_dialog("错误", "请输入新值") + return + + screen = self.root.get_screen("real_time_curve") + label = screen.ids.get(label_id, None) + if label: + label.text = f"通信超时: {new_value}" + # 调用原有的修改方法,增加异常捕获 + try: + self.modify_register(new_value) + except Exception as e: + self.show_dialog("错误", f"寄存器修改失败:{e}") + else: + self.show_dialog("错误", "未找到目标标签") except Exception as e: - print(f"从机ID {slave_id} 读取失败:{e}") - return None + self.show_dialog("错误", f"操作异常:{e}") + finally: + if self.dialog2: + self.dialog2.dismiss() + + def read_modbus_registers(self, slave_id=1, address=0, count=1): + """ + 通用的Modbus保持寄存器读取函数(优化版) + :param slave_id: 从机ID + :param address: 寄存器地址 + :param count: 读取数量 + :return: {'success': bool, 'data': list, 'msg': str} + """ + return self.modbus_master.read_holding_registers(slave_id, address, count) + + def modify_register(self, field_widget, input_text): + """ + 用户主动修改时,写入指定寄存器并刷新显示 + :param field_widget: MDTextField控件对象 + :param input_text: 用户输入的值 + """ + address = getattr(field_widget, 'comm_address', None) + slave_id = 1 # 可根据实际情况动态获取 + if address is None: + self.show_dialog("错误", "未设置通讯地址") + return + if not input_text: + self.show_dialog("错误", "请输入值") + return + try: + value = int(input_text) + result = self.write_modbus_register(slave_id=slave_id, address=address, value=value) + # self.show_dialog("操作结果", result) + self.update_register_display(0) + except ValueError: + self.show_dialog("错误", "请输入有效整数") + + def write_modbus_register(self, slave_id=1, address=0, value=None): + """ + 通用写入Modbus保持寄存器(单个寄存器),低耦合版 + :param slave_id: 从机ID + :param address: 寄存器地址 + :param value: 要写入的值(整数,0-65535) + :return: {'success': bool, 'msg': str} + """ + return self.modbus_master.write_single_register(slave_id, address, value) + + def show_dialog(self, title, message): + self.dialog1(message,title) def update_register_display(self, dt): - """定时更新寄存器值显示""" - register_value = self.read_modbus_registers(slave_id=1, address=0, count=1) + real_time_screen = self.root.get_screen("real_time_curve") + widgets = [w for w in real_time_screen.ids.values() + if isinstance(w, MDTextField) and hasattr(w, 'comm_address')] - # 获取显示标签并更新文本 - real_time_screen = self.root.get_screen("real_time_curve") # 根据实际屏幕名称调整 - if hasattr(real_time_screen.ids, 'register_label'): + # 收集未聚焦的寄存器地址 + addr_widget_map = {} + for w in widgets: + if not w.focus: + addr = getattr(w, 'comm_address', None) + if addr is not None: + addr_widget_map[addr] = w - if register_value is not None: - real_time_screen.ids.register_label.text = f"寄存器 0: {register_value[0]}" + if not addr_widget_map: + return + + # 分组连续地址段(例如 [1,2,3,10,11,12] -> [[1,2,3], [10,11,12]]) + sorted_addresses = sorted(addr_widget_map.keys()) + grouped_ranges = [] + group = [sorted_addresses[0]] + + for addr in sorted_addresses[1:]: + if addr == group[-1] + 1: + group.append(addr) else: - real_time_screen.ids.register_label.text = "寄存器 0: 读取失败或超时" + grouped_ranges.append(group) + group = [addr] + grouped_ranges.append(group) + + # 开启线程异步读取每段 + for group in grouped_ranges: + start = group[0] + count = group[-1] - start + 1 + thread = Thread(target=self._read_and_update_range, args=(start, count, group, addr_widget_map)) + thread.start() + + def _read_and_update_range(self, start, count, group, addr_widget_map): + try: + result = self.read_modbus_registers(slave_id=1, address=start, count=count) + except Exception as e: + result = {'success': False, 'error': str(e)} + + # 在主线程中更新 UI + Clock.schedule_once(partial(self._update_widgets_with_data, start, group, addr_widget_map, result), 0) + + def _update_widgets_with_data(self, start, group, addr_widget_map, result, dt): + if result.get('success') and result.get('data'): + data = result['data'] + for addr in group: + widget = addr_widget_map.get(addr) + index = addr - start + if widget and 0 <= index < len(data): + new_value = str(data[index]) + if widget.text != new_value: + widget.text = new_value + elif widget: + widget.text = "索引错误" + else: + for addr in group: + widget = addr_widget_map.get(addr) + if widget: + widget.text = f"失败: {result.get('error', '读取失败')}" ###################################LoginPageWork-Start################################################# def update_wifi_status(self, dt): - self.check_wifi() - Clock.schedule_once(self.update_wifi_status, 1) # 1秒刷新一次 + # 只有当前屏幕为 login 时才更新 + if self.root.current != "login": + return - def check_wifi(self): if platform != 'android': - login_screen = self.root.get_screen("login") # 根据实际屏幕名称调整 - if hasattr(login_screen.ids, 'wifi_status_text'): - self.wifi_status_text = '非Android设备' - return + self.wifi_status_text = '非Android设备' + return try: from jnius import autoclass, cast @@ -718,7 +552,7 @@ class app(MDApp): if not wifi_manager.isWifiEnabled(): self.wifi_status_text = 'WiFi 未启用' - return # 这里直接返回,不再继续取SSID等信息 + return wifi_info = wifi_manager.getConnectionInfo() if wifi_info is None: @@ -726,10 +560,7 @@ class app(MDApp): return ssid = wifi_info.getSSID() - if ssid: - ssid_display = ssid.strip('"') - else: - ssid_display = "SSID Unknown" + ssid_display = ssid.strip('"') if ssid else "SSID Unknown" ip_int = wifi_info.getIpAddress() ip_str = Formatter.formatIpAddress(ip_int) if ip_int != 0 else "0.0.0.0" @@ -757,215 +588,230 @@ class app(MDApp): activity = PythonActivity.mActivity wifi_service = activity.getSystemService(Context.WIFI_SERVICE) wifi_info = wifi_service.getConnectionInfo() + # 获取当前连接的WiFi名称并处理引号和大小写 wifi_id = wifi_info.getSSID().strip('"').lower() else: - wifi_id = "zhizhan-2" # 非 Android 用模拟 WiFi + # 非Android平台使用模拟WiFi + wifi_id = "zhizhan-2" except Exception as e: self.dialog1(f"获取WiFi信息失败:{e}") return try: with open("data/Users.csv", "r", encoding="utf-8") as file: - csv_reader = csv.reader(file) - for line in csv_reader: - - if len(line) < 8: - continue - - # 假设SSID存储在第8列(索引7) - csv_ssid = line[7].strip().lower() - - # 更精确匹配SSID,且忽略大小写 - if wifi_id == csv_ssid or wifi_id in map(str.lower, line): - name, prn, email, number, password, branch, semester,csv_ssid = line[:8] + # 使用DictReader读取CSV,通过列名访问数据 + csv_reader = csv.DictReader(file) + + for row in csv_reader: + # 获取CSV中存储的WiFi SSID并处理大小写 + csv_ssid = row['Wifi_SSID'].strip().lower() + + # 精确匹配WiFi SSID + if wifi_id == csv_ssid: + # 通过列名获取用户信息 + name = row['User'] + prn = row['Reserve'] # 根据实际列名调整 + email = row['Reserve'] # 根据实际列名调整 + number = row['Reserve'] # 根据实际列名调整 + password = row['User_pass'] + branch = row['Reserve'] # 根据实际列名调整 + semester = row['Reserve'] # 根据实际列名调整 + # 更新界面显示的用户信息 self.root.current = "home" self.user.text = f"[b]Hey! {name}[/b]" - self.profile_name.text = self.edit_name.text = name - self.profile_email.text = self.edit_email.text = email + self.profile_user_name.text = self.edit_name.text = name + self.profile_user_pass.text = self.edit_email.text = email self.profile_prn.text = self.edit_prn.text = prn - self.profile_number.text = self.edit_number.text = number + self.profile_wifi_ssid.text = row['Wifi_SSID'] self.profile_semester.text = self.edit_semester.text = semester self.profile_branch.text = self.edit_branch.text = branch + # 连接Modbus设备 self.connect_modbus() self.dialog1(f"欢迎你,{name}!\n认证成功!") - return except Exception as e: self.dialog1(f"读取用户信息失败:{e}") return + # 认证失败提示 self.dialog1("认证失败,请检查网络或确保手机权限打开定位和连接到目标WiFi") - # 添加Modbus连接函数 + def connect_modbus(self): - try: - # 从CSV文件读取Modbus配置 + def _connect_in_background(): modbus_ip = None - modbus_port = 502 # 默认端口 - - # 获取当前连接的WiFi SSID - if platform == "android": - from jnius import autoclass - PythonActivity = autoclass('org.kivy.android.PythonActivity') - Context = autoclass('android.content.Context') - activity = PythonActivity.mActivity - wifi_service = activity.getSystemService(Context.WIFI_SERVICE) - wifi_info = wifi_service.getConnectionInfo() - current_wifi_id = wifi_info.getSSID().strip('"').lower() - else: - current_wifi_id = "zhizhan-2" # 非Android环境模拟WiFi - - # 读取CSV文件查找匹配的Modbus配置 - with open("data/Users.csv", "r", encoding="utf-8") as file: - csv_reader = csv.reader(file) - headers = next(csv_reader) # 获取表头 - - for line in csv_reader: - if len(line) < 10: # 确保有足够的字段 - continue - - # 匹配当前连接的WiFi SSID - csv_ssid = line[7].strip().lower() - if current_wifi_id == csv_ssid or current_wifi_id in map(str.lower, line): - modbus_ip = line[8] - modbus_port = int(line[9]) if line[9] else 502 - break # 找到匹配项则退出循环 - - if not modbus_ip: - # self.dialog1("未找到与当前WiFi匹配的Modbus配置") - return + modbus_port = 502 + master = None - # 断开现有连接(如果存在) - if hasattr(self, 'modbus_master') and self.modbus_master: - self.modbus_master.close() + try: + # 获取当前WiFi SSID(保持不变) + if platform == "android": + from jnius import autoclass + PythonActivity = autoclass('org.kivy.android.PythonActivity') + Context = autoclass('android.content.Context') + activity = PythonActivity.mActivity + wifi_service = activity.getSystemService(Context.WIFI_SERVICE) + wifi_info = wifi_service.getConnectionInfo() + current_wifi_id = wifi_info.getSSID().strip('"').lower() + else: + current_wifi_id = "zhizhan-2" - # 创建新连接 - self.modbus_master = TcpMaster(host=modbus_ip, port=modbus_port) - self.modbus_master.set_timeout(5.0) # 设置超时时间 - - # 测试连接(读取一个保持寄存器) - self.modbus_master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 1) - print(f"Modbus连接成功\nIP: {modbus_ip}\n端口: {modbus_port}") - - except FileNotFoundError: - self.dialog1("配置文件user.csv未找到") - except socket.error as e: - self.dialog1(f"Modbus连接失败: 网络错误\n{e}") - self.modbus_master = None - except Exception as e: - self.dialog1(f"Modbus连接失败: {e}") - self.modbus_master = None + # 读取CSV配置(保持不变) + with open("data/Users.csv", "r", encoding="utf-8") as file: + csv_reader = csv.DictReader(file) + for row in csv_reader: + csv_ssid = row['Wifi_SSID'].strip().lower() + if current_wifi_id == csv_ssid: + modbus_ip = row['Modbus_IP'] + modbus_port = int(row['Modbus_Port']) if row['Modbus_Port'] else 502 + break + if not modbus_ip: + Clock.schedule_once(lambda dt: self.dialog1("未找到匹配的Modbus配置")) + return + + # 断开现有连接(保持不变) + self.modbus_master.disconnect() + + # 创建新连接并测试(保持不变) + connect_result = self.modbus_master.connect(modbus_ip, modbus_port) + if not connect_result['success']: + Clock.schedule_once(lambda dt: self.dialog1(connect_result['msg'])) + return + print(f"Modbus连接成功 (modbus-tk)\nIP: {modbus_ip}\n端口: {modbus_port}") + Clock.schedule_once(lambda dt: self.dialog1(f"Modbus连接成功\nIP: {modbus_ip}\n端口: {modbus_port}")) + + except FileNotFoundError as e: + # 修复:将异常信息转为字符串或通过默认参数传递 + err_msg = "配置文件 Users.csv 未找到" + Clock.schedule_once(lambda dt, msg=err_msg: self.dialog1(msg)) + except modbus_tk.modbus.ModbusError as e: + # 修复:使用默认参数传递异常信息 + err_msg = f"Modbus协议错误: {e}\n从站地址: {e.slave}\n功能码: {e.function_code}" + Clock.schedule_once(lambda dt, msg=err_msg: self.dialog1(msg)) + self.modbus_master = None + except socket.error as e: + # 修复:提前格式化错误信息 + err_msg = f"网络连接失败: {e}" + Clock.schedule_once(lambda dt, msg=err_msg: self.dialog1(msg)) + self.modbus_master = None + except Exception as e: + # 修复:捕获所有其他异常 + err_msg = f"连接失败: {str(e)}" + Clock.schedule_once(lambda dt, msg=err_msg: self.dialog1(msg)) + self.modbus_master = None + + threading.Thread(target=_connect_in_background, daemon=True).start() ###############################################SIGNUP Page Functions##################################################### # signup Verification function "check_signup" - def check_signup(self, name, prn, email, num, password, branch, sem, ssid, modbus_ip, modbus_port): - if name == "" or prn == "" or email == "" or num == "" or password == "" or branch == "" or sem == "": - check = "Enter all required fields" - return self.dialog1(check) - else: - status = "None" - with open('data/Users.csv', "r") as file: - csv_reader = csv.reader(file, delimiter=',') - for line in csv_reader: - try: - if line[3] == num: - status = "num" - break - if line[1] == prn: - status = "prn" - break - if line[2] == email: - status = "email" - break - else: - status = False - except IndexError: - pass - if status == "num": - check = "Number already registered Please enter a new number" - return self.dialog1(check) - elif status == "prn": - check = "PRN already registered Please enter a PRN" - return self.dialog1(check) - elif status == "email": - check = "Email already registered Please enter a new email" - return self.dialog1(check) - else: - self.root.current = "otp" - self.send_otp(num) - # 保存注册信息时包含Modbus信息 - self.signup_modbus_ip = modbus_ip - self.signup_modbus_port = modbus_port - check = "One Time Password has been shared on your registered Whatsapp No. Successful!." - self.dialog1(check) + # def check_signup(self, name, prn, email, num, password, branch, sem, Wifi_SSID, modbus_ip, modbus_port): + # if name == "" or prn == "" or email == "" or num == "" or password == "" or branch == "" or sem == "": + # check = "Enter all required fields" + # return self.dialog1(check) + # else: + # status = "None" + # with open('data/Users.csv', "r") as file: + # csv_reader = csv.reader(file, delimiter=',') + # for line in csv_reader: + # try: + # if line[3] == num: + # status = "num" + # break + # if line[1] == prn: + # status = "prn" + # break + # if line[2] == email: + # status = "email" + # break + # else: + # status = False + # except IndexError: + # pass + # if status == "num": + # check = "Number already registered Please enter a new number" + # return self.dialog1(check) + # elif status == "prn": + # check = "PRN already registered Please enter a PRN" + # return self.dialog1(check) + # elif status == "email": + # check = "Email already registered Please enter a new email" + # return self.dialog1(check) + # else: + # self.root.current = "otp" + # self.send_otp(num) + # # 保存注册信息时包含Modbus信息 + # self.signup_modbus_ip = modbus_ip + # self.signup_modbus_port = modbus_port + # check = "One Time Password has been shared on your registered Whatsapp No. Successful!." + # self.dialog1(check) ##################################################FORGOT PassWord Page################################################## - # FORGOT PASSWORD page mobile number verification function 'verify_no' - def verify_no(self): - status = False - if self.mobile_no.text == "": - check = "Please enter your Mobile Number." - return self.dialog1(check) - else: - with open('data/Users.csv', "r", encoding="utf-8") as file: - csv_reader = csv.reader(file, delimiter=",") - for line in csv_reader: - try: - if line[3] == self.mobile_no.text: - status = True - break - else: - status = False - except IndexError: - pass - except Exception as e: - print(e) + # # FORGOT PASSWORD page mobile number verification function 'verify_no' + # def verify_no(self): + # status = False + # if self.mobile_no.text == "": + # check = "Please enter your Mobile Number." + # return self.dialog1(check) + # else: + # with open('data/Users.csv', "r", encoding="utf-8") as file: + # csv_reader = csv.reader(file, delimiter=",") + # for line in csv_reader: + # try: + # if line[3] == self.mobile_no.text: + # status = True + # break + # else: + # status = False + # except IndexError: + # pass + # except Exception as e: + # print(e) - if status: - check = "One Time Password has been shared on your registered Whatsapp No. Successful!." - self.root.current = "otp" - self.send_otp(self.mobile_no.text) - return self.dialog1(check) - else: - check = "Enter Registered Mobile Number." - self.dialog1(check) + # if status: + # check = "One Time Password has been shared on your registered Whatsapp No. Successful!." + # self.root.current = "otp" + # self.send_otp(self.mobile_no.text) + # return self.dialog1(check) + # else: + # check = "Enter Registered Mobile Number." + # self.dialog1(check) - def reset_password(self): - if self.new_pass.text == "" or self.new_pass1.text == "": - check = "Please enter your new password" - return self.dialog1(check) + # def reset_password(self): + # if self.new_pass.text == "" or self.new_pass1.text == "": + # check = "Please enter your new password" + # return self.dialog1(check) - elif not self.new_pass.text == self.new_pass1.text: - check = "Password Does Not Match. \nPlease Re-check your password." - return self.dialog1(check) + # elif not self.new_pass.text == self.new_pass1.text: + # check = "Password Does Not Match. \nPlease Re-check your password." + # return self.dialog1(check) - else: - with open('data/Users.csv', "r", encoding="utf-8") as file: - csv_reader = csv.DictReader(file, delimiter=",") - rows = [row for row in csv_reader] + # else: + # with open('data/Users.csv', "r", encoding="utf-8") as file: + # csv_reader = csv.DictReader(file, delimiter=",") + # rows = [row for row in csv_reader] - for row in rows: - if row['Student_Whatsapp_no'] == self.mobile_no.text: - row['Student_pass'] = self.new_pass.text - break + # for row in rows: + # if row['Reserve'] == self.mobile_no.text: + # row['User_pass'] = self.new_pass.text + # break - try: - with open('data/Users.csv', "w", newline='', encoding="utf-8") as file: - headers = ["Student_Name", "Student_PRN", "Student_Email", "Student_Whatsapp_no", "Student_pass", - "Branch", "Semester"] - csv_writer = csv.DictWriter(file, fieldnames=headers) - csv_writer.writeheader() - csv_writer.writerows(rows) - check = "Password Updated Successfully!" - self.root.current = "login" - except Exception as e: - print(e) - check = "Something went wrong please try again." - self.dialog1(check) + # try: + # with open('data/Users.csv', "w", newline='', encoding="utf-8") as file: + # headers = ["User", "Reserve", "Student_Email", "Reserve", "User_pass", + # "Branch", "Semester"] + # csv_writer = csv.DictWriter(file, fieldnames=headers) + # csv_writer.writeheader() + # csv_writer.writerows(rows) + # check = "Password Updated Successfully!" + # self.root.current = "login" + # except Exception as e: + # print(e) + # check = "Something went wrong please try again." + # self.dialog1(check) ###############################################PROFILE & EDIT Profile Page############################################## @@ -979,19 +825,19 @@ class app(MDApp): rows = [row for row in csv_reader] for row in rows: - if row['Student_Whatsapp_no'] == self.profile_number.text: - row['Student_Name'] = self.edit_name.text - row['Student_PRN'] = self.edit_prn.text - row['Student_Email'] = self.edit_email.text - row['Student_Whatsapp_no'] = self.edit_number.text - row['Student_pass'] = self.password.text - row['Branch'] = self.edit_branch.text - row['Semester'] = self.edit_semester.text + if row['Wifi_SSID'] == self.profile_wifi_ssid.text: + row['User'] = self.edit_name.text + row['User_pass'] = self.edit_prn.text + row['Wifi_SSID'] = self.edit_email.text + row['Modbus_IP'] = self.edit_number.text + row['Modbus_Port'] = self.password.text + row['Reserve'] = self.edit_branch.text + row['Reserve'] = self.edit_semester.text break with open('data/Users.csv', newline="", mode="w", encoding="utf-8") as file: - header = ["Student_Name", "Student_PRN", "Student_Email", "Student_Whatsapp_no", "Student_pass", - "Branch", "Semester"] + header = ["User", "User_pass", "Wifi_SSID", "Modbus_IP", "Modbus_Port", + "Reserve", "Reserve"] csv_writer = csv.DictWriter(file, fieldnames=header) csv_writer.writeheader() csv_writer.writerows(rows) @@ -1004,480 +850,6 @@ class app(MDApp): self.profile_edit_screen.ids.edit_no.readonly = True self.profile_edit_screen.ids.edit_private_credential_butn.disabled = False - -#############################################OTP SEND & VERIFY PAGE##################################################### - - def send_otp(self, number): - self.a = random.randint(1000, 9999) - if len(str(number)) == 10: - number1 = "+91" + str(number) - message = f"""Your verification code is {self.a}. It expires in 10 minutes. Don’t share this code with anyone.""" - pywhatkit.sendwhatmsg_instantly(number1, message, wait_time=15, tab_close=True, close_time=3) - elif len(str(number)) != 10: - check = "Please enter a 10 digit number." - return self.dialog1(check) - else: - pass - - def verify_otp(self, d1, d2, d3, d4, otp_button): - entered_otp = str(d1) + str(d2) + str(d3) + str(d4) - if entered_otp == str(self.a): - if otp_button == "Reset Password": - self.root.current = "reset_pass" - check = "Reset your password " - return self.dialog1(check) - - elif otp_button == "Edit Credentials": - self.root.current = "profile_edit" - check = "Edit your credentials " - self.profile_edit_screen.ids.edit_email.readonly = False - self.profile_edit_screen.ids.edit_prn.readonly = False - self.profile_edit_screen.ids.edit_no.readonly = False - self.profile_edit_screen.ids.edit_private_credential_butn.disabled = True - return self.dialog1(check) - - elif otp_button == "Verify OTP": - self.root.current = "home" - self.add_book() - - else: - data = [self.user_name.text, self.user_prn.text, self.user_email.text, self.user_no.text, - self.user_pass.text, self.signup_branch.text, self.signup_sem.text] - - with open('data/Users.csv', encoding="utf-8") as file: - csv_writer = csv.writer(file, delimiter=",") - csv_writer.writerow(data) - - self.root.current = "home" - check = "SignUP Successful" + "\nHello ! " + self.user_name.text - self.user.text = "H e y !" + self.user_name.text - self.verify(True) - return self.dialog1(check) - - elif entered_otp != str(self.a): - check = "Please enter a correct verification code." - self.d1.text = "" - self.d2.text = "" - self.d3.text = "" - self.d4.text = "" - return self.dialog1(check) - - else: - check = "Sorry! Try again later." - self.root.current = "login" - self.d1.text = "" - self.d2.text = "" - self.d3.text = "" - self.d4.text = "" - return self.dialog1(check) - - #######################################################Borrow BOok###################################################### - - def get_book(self, isbn): - self.isbn.text = isbn - if not self.isbn.text: - check = "Please enter a valid ISBN." - return self.dialog1(check) - elif not len(self.isbn.text) == 13: - check = "Please enter a valid ISBN." - return self.dialog1(check) - else: - with open('data/Books.csv', mode="r", encoding="utf-8") as file: - csv_reader = csv.DictReader(file, delimiter=",") - rows = [row for row in csv_reader] - for row in rows: - if row["ISBN"] == self.isbn.text: - if row['Availability'] == "0": - check = "Your book is unavailable. " - return self.dialog1(check) - else: - self.otp_button_fun('2') - self.root.current = "otp" - self.send_otp(self.profile_number.text, ) - - def add_book(self): - with open('data/Books.csv', mode="r", encoding="utf-8") as file: - csv_reader = csv.DictReader(file, delimiter=",") - rows = [row for row in csv_reader] - - for row in rows: - if row['ISBN'] == self.isbn.text: - try: - self.book_name = row['Name'] - a = row['Availability'] - row['Availability'] = str(int(a) - 1) - except KeyError: - pass - - with open('data/Books.csv', newline="", mode="w", encoding="utf-8") as file: - headers = ["Name", "Author", "Publication Year", "Publisher", "ISBN", - "Availability"] - csv_writer = csv.DictWriter(file, fieldnames=headers) - csv_writer.writeheader() - csv_writer.writerows(rows) - - self.date = datetime.now() - self.Due_date = self.date + timedelta(days=10) - - details = [self.profile_prn.text, self.profile_number.text, self.book_name, self.isbn.text, self.date, - self.Due_date, ] - transaction_details = details + ["Not Returned"] - borrow_details = details + ["Not Renewed"] - - files = ['data/borrowed_books.csv', 'data/all_book_transactions.csv'] - for file1 in files: - with open(file1, "a", encoding="utf-8", newline='') as file: - csv_writer = csv.writer(file, delimiter=",") - if file1 == 'data/borrowed_books.csv': - csv_writer.writerow(borrow_details) - elif file1 == 'data/all_book_transactions.csv': - csv_writer.writerow(transaction_details) - - check = "OTP Verified! \nBook Borrowed Successfully!" - return self.dialog1(check) - - def fetch_borrowed_book(self): - with open('data/borrowed_books.csv', mode="r", encoding="utf-8") as file: - csv_reader = csv.DictReader(file, delimiter=",") - rows = [row for row in csv_reader] - self.books.clear() - for row in rows: - if row['User'] == self.profile_prn.text: - book = {'source': 'assets/sample_book_display.jpg', 'btn_text': 'Return Book', 'Book_name': row['Book_Name'], - 'time': row['Due_Date'], 'Renew_status': row['Renew_status']} - self.books += [book] - print(self.books) - self.items = self.books - - def fetch_renewable_books(self): - with open('data/borrowed_books.csv', mode="r", encoding="utf-8") as file: - csv_reader = csv.DictReader(file, delimiter=",") - rows = [row for row in csv_reader] - self.renewable_books.clear() - for row in rows: - a = datetime.strptime(row['Due_Date'], "%Y-%m-%d %H:%M:%S.%f") - a = a.strftime("%d-%m-%Y") - if row['User'] == self.profile_prn.text and row[ - 'Renew_status'] == "Not Renewed" and a == datetime.now().strftime("%d-%m-%Y"): - renew_book = {'source': 'assets/sample_book_display.jpg', 'btn_text': 'Renew Book', 'Book_name': row['Book_Name'], - 'time': row['Due_Date'], 'Renew_status': row['Renew_status']} - self.renewable_books += [renew_book] - print(self.renewable_books) - self.renew = self.renewable_books - - def return_book(self, obj): - if obj == 'Return': - self.fetch_borrowed_book() - self.image_label_grid.clear_widgets() - book_list = self.items - elif obj == 'Renew': - self.fetch_renewable_books() - self.renew_grid.clear_widgets() - book_list = self.renew - - for item in book_list: - box = MDBoxLayout(orientation='vertical', size_hint_y=None, height="125dp") - anchor = AnchorLayout(anchor_x="center", anchor_y="center") - grid = GridLayout(cols=2, spacing=dp(20), size_hint_x=None, size_hint_y=None, size=[dp(320), dp(200)], - padding=dp(0)) - - img = Image(source=item['source'], - size_hint_x=None, - size_hint_y=None, - width=dp(100), - height=dp(125), - allow_stretch=True) - label = MDLabel( - text=item['Book_name'], - font_name="BPoppins", - size_hint_x=None, - size_hint_y=None, - bold=True, - size=[dp(215), dp(70)], - padding=dp(0), - on_touch_down=lambda instance, touch: self.change_cursor(True), - on_touch_up=lambda instance, touch: self.change_cursor(False), - ) - date11 = item['time'] - date22 = "Due Date is " - for i in range(10): - date22 += date11[i] - - label1 = MDLabel( - text=date22, - font_name="BPoppins", - size_hint_x=None, - size_hint_y=None, - size=[dp(215), dp(40)], - padding=dp(0), - on_touch_down=lambda instance, touch: self.change_cursor(True), - on_touch_up=lambda instance, touch: self.change_cursor(False), - ) - - if item['btn_text'] == "Return Book": - btn = Button( - text=item['btn_text'], - font_name="BPoppins", - size_hint=(None, None), - size=(dp(200), dp(30)), - background_color=(0, 0, 1, 1), - on_touch_down=lambda instance, touch: self.change_cursor(True), - on_touch_up=lambda instance, touch: self.change_cursor(False), - on_release=lambda instance, src=item['source'], txt=item['btn_text'], name=item['Book_name'], - time=item['time']: self.remove_book(src, txt, name, time), - ) - elif item['btn_text'] == "Renew Book": - btn = Button( - text=item['btn_text'], - font_name="BPoppins", - size_hint=(None, None), - size=(dp(200), dp(30)), - background_color=(0, 0, 1, 1), - on_touch_down=lambda instance, touch: self.change_cursor(True), - on_touch_up=lambda instance, touch: self.change_cursor(False), - on_release=lambda instance, src=item['source'], txt=item['btn_text'], name=item['Book_name'], - time=item['time']: self.renew_book(src, txt, name, time), - ) - - vertical_box = BoxLayout(orientation='vertical', size_hint_y=None, height=label.height + btn.height) - vertical_box.add_widget(label) - vertical_box.add_widget(label1) - vertical_box.add_widget(btn) - - grid.add_widget(img) - grid.add_widget(vertical_box) - anchor.add_widget(grid) - box.add_widget(anchor) - if btn.text == "Return Book": - self.image_label_grid.add_widget(box) - elif btn.text == "Renew Book": - self.renew_grid.add_widget(box) - - def remove_book(self, source, text, name, time): - with open('data/borrowed_books.csv', mode="r", encoding="utf-8") as file: - csv_reader = csv.reader(file, delimiter=",") - header = next(csv_reader) - rows = list(csv_reader) - - new_rows = [row for row in rows if row[0] != self.profile_prn.text or row[2] != name or row[5] != time] - - with open('data/borrowed_books.csv', mode="w", newline="", encoding="utf-8") as file: - csv_writer = csv.writer(file, delimiter=",") - csv_writer.writerow(header) - csv_writer.writerows(new_rows) - - with open('data/all_book_transactions.csv', mode="r", encoding="utf-8") as file: - csv_reader = csv.DictReader(file, delimiter=",") - rows = [row for row in csv_reader] - - return_date = datetime.now() - return_date = return_date.strftime("%d/%m/%Y") - - for row in rows: - if row['User'] == self.profile_prn.text and row['Book_Name'] == name and row['Due_Date'] == time: - row["Return_Date"] = return_date - - with open('data/all_book_transactions.csv', mode="w", newline="", encoding="utf-8") as file: - headers = ['User', 'User_No', 'Book_Name', 'ISBN', 'Date', 'Due_Date', 'Return_Date', ] - csv_writer = csv.DictWriter(file, fieldnames=headers) - csv_writer.writeheader() - csv_writer.writerows(rows) - - with open('data/Books.csv', mode="r", encoding="utf-8") as file: - csv_reader = csv.DictReader(file, delimiter=",") - rows = [row for row in csv_reader] - - for row in rows: - if row['Name'] == name: - try: - a = row['Availability'] - row['Availability'] = str(int(a) + 1) - except KeyError: - pass - - with open('data/Books.csv', newline="", mode="w", encoding="utf-8") as file: - headers = ["Name", "Author", "Publication Year", "Publisher", "ISBN", - "Availability"] - csv_writer = csv.DictWriter(file, fieldnames=headers) - csv_writer.writeheader() - csv_writer.writerows(rows) - - self.items = [item for item in self.items if - not (item['source'] == source and item['btn_text'] == text and item['Book_name'] == name)] - - check = "Book Returned Successfully!" - self.dialog1(check) - self.return_book("Return") - - def fetch_book_history(self): - with open('data/all_book_transactions.csv', mode="r", encoding="utf-8") as file: - csv_reader = csv.DictReader(file, delimiter=",") - rows = [row for row in csv_reader] - self.books_history.clear() - for row in rows: - if row['User'] == self.profile_prn.text and row['Return_Date'] != 'Not Returned': - book = {'source': 'assets/sample_book_display.jpg', 'text': 'Rate Book', 'Book_name': row['Book_Name'], - 'time': row['Date'], 'Return_Date': row['Return_Date']} - self.books_history += [book] - self.history = self.books_history - - def book_history(self): - self.fetch_book_history() - self.history_grid.clear_widgets() - - for item in self.history: - box = MDBoxLayout(orientation='vertical', size_hint_y=None, height="125.001dp") - anchor = AnchorLayout(anchor_x="center", anchor_y="center") - grid = GridLayout(cols=2, spacing=dp(20), size_hint_x=None, size_hint_y=None, size=[dp(320), dp(200)], - padding=dp(0)) - - img = Image(source=item['source'], size_hint_x=None, size_hint_y=None, width=dp(100), height=dp(125), - allow_stretch=True) - label = MDLabel( - text=item['Book_name'], - font_name="BPoppins", - size_hint_x=None, - size_hint_y=None, - bold=True, - size=[dp(215), dp(60)], - padding=dp(0), - on_touch_down=lambda instance, touch: self.change_cursor(True), - on_touch_up=lambda instance, touch: self.change_cursor(False), - ) - - B_date = datetime.strptime(item['time'], '%Y-%m-%d %H:%M:%S.%f') - B_date = B_date.strftime("%d-%m-%Y") - - formated_B = "" - for i in range(10): - formated_B += B_date[i] - - R_date = datetime.strptime(item['Return_Date'], '%d/%m/%Y') - R_date = R_date.strftime("%d-%m-%Y") - formated_R = "" - for i in range(10): - formated_R += R_date[i] - - date22 = f"""Borrow Date: {formated_B}\nReturn Date: {formated_R}""" - - label1 = MDLabel( - text=date22, - font_name="BPoppins", - size_hint_x=None, - size_hint_y=None, - size=[dp(215), dp(50)], - padding=dp(0), - on_touch_down=lambda instance, touch: self.change_cursor(True), - on_touch_up=lambda instance, touch: self.change_cursor(False), - ) - - btn = Button( - text=item['text'], - font_name="BPoppins", - size_hint=(None, None), - size=(dp(200), dp(30)), - background_color=(0, 0, 1, 1), - on_touch_down=lambda instance, touch: self.change_cursor(True), - on_touch_up=lambda instance, touch: self.change_cursor(False), - ) - vertical_box = BoxLayout(orientation='vertical', size_hint_y=None, height=label.height + btn.height) - vertical_box.add_widget(label) - vertical_box.add_widget(label1) - vertical_box.add_widget(btn) - - grid.add_widget(img) - grid.add_widget(vertical_box) - anchor.add_widget(grid) - box.add_widget(anchor) - self.history_grid.add_widget(box) - - def data_load(self): - self.search_field.bind(text=self.search_books) - self.search_grid.clear_widgets() - self.data_tables = MDDataTable( - pos_hint={'center_x': 0.5, 'center_y': 0.4}, - size_hint=(0.95, 0.5), - use_pagination=True, - padding=dp(0), - rows_num=7, - pagination_menu_pos='auto', - background_color_selected_cell=(0.8, 0.9, 1, 1), - column_data=[ - ("Book Name", dp(80)), - ("Author", dp(50)), - ("Publication Year", dp(30)), - ("Publisher", dp(40)), - ("ISBN", dp(30)), - ("Availability", dp(30)), - ], - row_data=get_books() - ) - self.search_grid.add_widget(self.data_tables) - - def search_books(self, instance, value): - all_data = get_books() - filtered_data = [row for row in all_data if ( - value.lower() in row[0].lower() or value.lower() in row[1].lower() or value.lower() in row[4])] - self.data_tables.row_data = filtered_data - - def get_recommendations(self): - book_title = self.book_input.text - recommendations = self.rec_book(book_title) - if isinstance(recommendations, str): - self.rec_label.text = recommendations - self.rec_grid.clear_widgets() - else: - self.display_rec_table(recommendations) - - @staticmethod - def rec_book(book_title): - book_title_lower = book_title.lower() - if book_title_lower not in df["Name_lower"].values: - return f"{book_title} not in database" - index = df[df['Name_lower'] == book_title_lower].index[0] - - distance, indices = knn.kneighbors(s_matrix[index].reshape(1, -1)) - rec_title = df.iloc[indices.flatten()]["Name"].tolist() - aval = df.iloc[indices.flatten()]["Availability"].tolist() - isbn = df.iloc[indices.flatten()]["ISBN"].tolist() - - recommendation = list(zip(rec_title, isbn, aval)) - - return recommendation - - def display_rec_table(self, recommendations): - self.rec_grid.clear_widgets() - data_tables = MDDataTable( - pos_hint={'center_x': 0.5, 'center_y': 0.2}, - size_hint=(0.95, 0.2), - use_pagination=True, - padding=dp(0), - rows_num=6, - pagination_menu_pos='auto', - background_color_selected_cell=(0.8, 0.9, 1, 1), - column_data=[ - ("Book Name", dp(80)), - ("ISBN", dp(30)), - ("Availability", dp(30)), - ], - row_data=[(title, isbn, availability) for title, isbn, availability in recommendations] - ) - self.rec_grid.add_widget(data_tables) - - def where_is_book(self): - with open('data/book_positions.csv', 'r') as csvfile: - data = csv.reader(csvfile, delimiter=',') - rows = list(data) - a = self.book_pos_name.text.lower() - for row in rows: - if row[0].lower() == a: - pos = str(row[1]) - self.book_pos.text = f"{a.upper()} Book is kept at {row[1]} location. Please Go and Borrow it!!\n({row[1]} means {pos[0]} th row, Left/Right side(L/R), {pos[2]} th shelf, {pos[3]} th shelf step )" - break - else: - self.book_pos.text = "Please check the Spell!" - - if __name__ == '__main__': app().run() diff --git a/modbus_client.py b/modbus_client.py new file mode 100644 index 0000000..3c67cf7 --- /dev/null +++ b/modbus_client.py @@ -0,0 +1,73 @@ +import modbus_tk +import modbus_tk.defines as cst +import modbus_tk.modbus_tcp as modbus_tcp +import socket + +class ModbusClient: + def __init__(self): + self.master = None + + def connect(self, ip, port): + if self.master: + self.master.close() + self.master = None + try: + self.master = modbus_tcp.TcpMaster(host=ip, port=port) + self.master.set_timeout(5.0) + self.master.set_verbose(False) + # Test connection + self.master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 1) + return {'success': True, 'msg': f"Modbus连接成功\nIP: {ip}\n端口: {port}"} + except modbus_tk.modbus.ModbusError as e: + self.master = None + return {'success': False, 'msg': f"Modbus协议错误: {e}\n从站地址: {e.slave}\n功能码: {e.function_code}"} + except socket.error as e: + self.master = None + return {'success': False, 'msg': f"网络连接失败: {e}"} + except Exception as e: + self.master = None + return {'success': False, 'msg': f"连接失败: {str(e)}"} + + def disconnect(self): + if self.master: + self.master.close() + self.master = None + + def read_holding_registers(self, slave_id, address, count): + if not self.master: + return {'success': False, 'data': None, 'msg': "Modbus未初始化,请先连接"} + try: + result = self.master.execute( + slave=slave_id, + function_code=cst.READ_HOLDING_REGISTERS, + starting_address=address, + quantity_of_x=count + ) + if result: + return {'success': True, 'data': list(result), 'msg': "读取成功"} + else: + return {'success': False, 'data': None, 'msg': "读取结果为空"} + except Exception as e: + return {'success': False, 'data': None, 'msg': f"读取失败:{e}"} + + def write_single_register(self, slave_id, address, value): + if not self.master: + return {'success': False, 'msg': "Modbus未连接,请先初始化连接"} + if value is None: + return {'success': False, 'msg': "未指定要写入的值"} + try: + write_value = int(value) + if not (0 <= write_value <= 65535): + return {'success': False, 'msg': "值必须在0-65535范围内(16位无符号整数)"} + except ValueError: + return {'success': False, 'msg': "写入值必须为整数"} + try: + self.master.execute( + slave=slave_id, + function_code=cst.WRITE_SINGLE_REGISTER, + starting_address=address, + output_value=write_value + ) + return {'success': True, 'msg': f"写入成功: 从机ID={slave_id},地址={address},值={write_value}"} + except Exception as e: + return {'success': False, 'msg': f"写入失败: 从机ID={slave_id},地址={address},错误:{e}"} \ No newline at end of file