Coverage for farmbot_sidecar_starter_pack/main.py: 100%

132 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-08-31 13:41 -0700

1""" 

2Farmbot class. 

3""" 

4 

5from .state import State 

6from .functions.api import ApiConnect 

7from .functions.basic_commands import BasicCommands 

8from .functions.broker import BrokerConnect 

9from .functions.camera import Camera 

10from .functions.information import Information 

11from .functions.jobs import JobHandling 

12from .functions.messages import MessageHandling 

13from .functions.movements import MovementControls 

14from .functions.peripherals import Peripherals 

15from .functions.resources import Resources 

16from .functions.tools import ToolControls 

17 

18VERSION = "1.2.0" 

19 

20class Farmbot(): 

21 """Farmbot class.""" 

22 __version__ = VERSION 

23 

24 def __init__(self): 

25 self.state = State() 

26 

27 # Initialize other components without the token initially 

28 self.api = ApiConnect(self.state) 

29 self.basic = BasicCommands(self.state) 

30 self.broker = BrokerConnect(self.state) 

31 self.camera = Camera(self.state) 

32 self.info = Information(self.state) 

33 self.jobs = JobHandling(self.state) 

34 self.messages = MessageHandling(self.state) 

35 self.movements = MovementControls(self.state) 

36 self.peripherals = Peripherals(self.state) 

37 self.resources = Resources(self.state) 

38 self.tools = ToolControls(self.state) 

39 

40 def set_verbosity(self, value): 

41 """Set output verbosity level.""" 

42 self.state.verbosity = value 

43 

44 # api.py 

45 

46 def get_token(self, email, password, server="https://my.farm.bot"): 

47 """Get FarmBot authorization token. Server is 'https://my.farm.bot' by default.""" 

48 return self.api.get_token(email, password, server) 

49 

50 def set_token(self, token): 

51 """Set FarmBot authorization token.""" 

52 self.state.token = token 

53 

54 # basic_commands.py 

55 

56 def wait(self, duration): 

57 """Pauses execution for a certain number of milliseconds.""" 

58 return self.basic.wait(duration) 

59 

60 def e_stop(self): 

61 """Emergency locks (E-stops) the Farmduino microcontroller.""" 

62 return self.basic.e_stop() 

63 

64 def unlock(self): 

65 """Unlocks a locked (E-stopped) device.""" 

66 return self.basic.unlock() 

67 

68 def reboot(self): 

69 """Reboots the FarmBot OS and re-initializes the device.""" 

70 return self.basic.reboot() 

71 

72 def shutdown(self): 

73 """Shuts down the FarmBot OS and turns the device off.""" 

74 return self.basic.shutdown() 

75 

76 # broker.py 

77 

78 def connect_broker(self): 

79 """Establish persistent connection to send messages via message broker.""" 

80 return self.broker.connect() 

81 

82 def disconnect_broker(self): 

83 """Disconnect from the message broker.""" 

84 return self.broker.disconnect() 

85 

86 def listen(self, channel="#", duration=None): 

87 """Listen to a message broker channel for the provided duration in seconds.""" 

88 return self.broker.listen(channel, duration) 

89 

90 # camera.py 

91 

92 def calibrate_camera(self): 

93 """Performs camera calibration. This action will reset camera calibration settings.""" 

94 return self.camera.calibrate_camera() 

95 

96 def take_photo(self): 

97 """Takes photo using the device camera and uploads it to the web app.""" 

98 return self.camera.take_photo() 

99 

100 # information.py 

101 

102 def api_get(self, endpoint, database_id=None): 

103 """Get information about a specific endpoint.""" 

104 return self.info.api_get(endpoint, database_id) 

105 

106 def api_patch(self, endpoint, new_data, database_id=None): 

107 """Change information contained within an endpoint.""" 

108 return self.info.api_patch(endpoint, new_data, database_id) 

109 

110 def api_post(self, endpoint, new_data): 

111 """Create new information contained within an endpoint.""" 

112 return self.info.api_post(endpoint, new_data) 

113 

114 def api_delete(self, endpoint, id=None): 

115 """Delete information contained within an endpoint.""" 

116 return self.info.api_delete(endpoint, id) 

117 

118 def safe_z(self): 

119 """Returns the highest safe point along the z-axis.""" 

120 return self.info.safe_z() 

121 

122 def garden_size(self): 

123 """Returns size of garden bed.""" 

124 return self.info.garden_size() 

125 

126 def group(self, group_id=None): 

127 """Returns all group info or single by id.""" 

128 return self.info.group(group_id) 

129 

130 def curve(self, curve_id=None): 

131 """Returns all curve info or single by id.""" 

132 return self.info.curve(curve_id) 

133 

134 def measure_soil_height(self): 

135 """Use the camera to determine soil height at the current location.""" 

136 return self.info.measure_soil_height() 

137 

138 def read_status(self): 

139 """Returns the FarmBot status tree.""" 

140 return self.info.read_status() 

141 

142 def read_sensor(self, sensor_name): 

143 """Reads the given sensor.""" 

144 return self.info.read_sensor(sensor_name) 

145 

146 # jobs.py 

147 

148 def get_job(self, job_str=None): 

149 """Retrieves the status or details of the specified job.""" 

150 return self.jobs.get_job(job_str) 

151 

152 def set_job(self, job_str, status_message, value): 

153 """Initiates or modifies job with given parameters.""" 

154 return self.jobs.set_job(job_str, status_message, value) 

155 

156 def complete_job(self, job_str): 

157 """Marks job as completed and triggers any associated actions.""" 

158 return self.jobs.complete_job(job_str) 

159 

160 # messages.py 

161 

162 def log(self, message_str, message_type="info", channel="ticker"): 

163 """Sends new log message via the API.""" 

164 return self.messages.log(message_str, message_type, channel) 

165 

166 def message(self, message_str, message_type="info", channel="ticker"): 

167 """Sends new log message via the message broker.""" 

168 return self.messages.message(message_str, message_type, channel) 

169 

170 def debug(self, message_str): 

171 """Sends debug message used for developer information or troubleshooting.""" 

172 return self.messages.debug(message_str) 

173 

174 def toast(self, message_str): 

175 """Sends a message that pops up on the user interface briefly.""" 

176 return self.messages.toast(message_str) 

177 

178 # movements.py 

179 

180 def move(self, x, y, z): 

181 """Moves to the specified (x, y, z) coordinate.""" 

182 return self.movements.move(x, y, z) 

183 

184 def set_home(self, axis="all"): 

185 """Sets the current position as the home position for a specific axis.""" 

186 return self.movements.set_home(axis) 

187 

188 def find_home(self, axis="all", speed=100): 

189 """Moves the device to the home position for a specified axis.""" 

190 return self.movements.find_home(axis, speed) 

191 

192 def find_axis_length(self, axis="all"): 

193 """Finds the length of a specified axis.""" 

194 return self.movements.find_axis_length(axis) 

195 

196 def get_xyz(self): 

197 """Returns the current (x, y, z) coordinates of the FarmBot.""" 

198 return self.movements.get_xyz() 

199 

200 def check_position(self, user_x, user_y, user_z, tolerance): 

201 """Verifies position of the FarmBot within specified tolerance range.""" 

202 return self.movements.check_position(user_x, user_y, user_z, tolerance) 

203 

204 # peripherals.py 

205 

206 def control_servo(self, pin, angle): 

207 """Set servo angle between 0-100 degrees.""" 

208 return self.peripherals.control_servo(pin, angle) 

209 

210 def control_peripheral(self, peripheral_name, value, mode=None): 

211 """Set peripheral value and mode.""" 

212 return self.peripherals.control_peripheral(peripheral_name, value, mode) 

213 

214 def toggle_peripheral(self, peripheral_name): 

215 """Toggles the state of a specific peripheral between `on` and `off`.""" 

216 return self.peripherals.toggle_peripheral(peripheral_name) 

217 

218 def on(self, pin_number): 

219 """Turns specified pin number `on` (100%).""" 

220 return self.peripherals.on(pin_number) 

221 

222 def off(self, pin_number): 

223 """Turns specified pin number `off` (0%).""" 

224 return self.peripherals.off(pin_number) 

225 

226 # resources.py 

227 

228 def sequence(self, sequence_name): 

229 """Executes a predefined sequence.""" 

230 return self.resources.sequence(sequence_name) 

231 

232 def get_seed_tray_cell(self, tray_name, tray_cell): 

233 """Identifies and returns the location of specified cell in the seed tray.""" 

234 return self.resources.get_seed_tray_cell(tray_name, tray_cell) 

235 

236 def detect_weeds(self): 

237 """Scans the garden to detect weeds.""" 

238 return self.resources.detect_weeds() 

239 

240 def lua(self, code_snippet): 

241 """Executes custom Lua code snippets to perform complex tasks or automations.""" 

242 return self.resources.lua(code_snippet) 

243 

244 def if_statement(self, variable, operator, value, then_sequence_name=None, else_sequence_name=None, named_pin_type=None): 

245 """Performs conditional check and executes actions based on the outcome.""" 

246 return self.resources.if_statement(variable, operator, value, then_sequence_name, else_sequence_name, named_pin_type) 

247 

248 def assertion(self, code, assertion_type, recovery_sequence_name=None): 

249 """Evaluates an expression.""" 

250 return self.resources.assertion(code, assertion_type, recovery_sequence_name) 

251 

252 # tools.py 

253 

254 def mount_tool(self, tool_str): 

255 """Mounts the given tool and pulls it out of assigned slot.""" 

256 return self.tools.mount_tool(tool_str) 

257 

258 def dismount_tool(self): 

259 """Dismounts the currently mounted tool into assigned slot.""" 

260 return self.tools.dismount_tool() 

261 

262 def water(self, plant_id): 

263 """Moves to and waters plant based on age and assigned watering curve.""" 

264 return self.tools.water(plant_id) 

265 

266 def dispense(self, milliliters, tool_name, pin): 

267 """Dispenses user-defined amount of liquid in milliliters.""" 

268 return self.tools.dispense(milliliters, tool_name, pin)