Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/2.3.0 #5

Merged
merged 9 commits into from
Dec 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions .run/Test.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!--
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<!--
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<!--
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<!--
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName"/>
<option name="externalProjectPath" value="$PROJECT_DIR$"/>
<option name="externalSystemIdString" value="GRADLE"/>
<option name="scriptParameters" value=""/>
<option name="taskDescriptions">
<list/>
</option>
<option name="taskNames">
<list>
<option value=":lib:check"/>
</list>
</option>
<option name="vmOptions"/>
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2"/>
</configuration>
</component>
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
}

val libVersion by extra("2.2.1.2")
val libVersion by extra("2.3.0")

group = "com.pi4j"
version = libVersion
Expand Down
4 changes: 3 additions & 1 deletion example/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ repositories {

dependencies {
// implementation(project(":lib"))
implementation("com.pi4j:pi4j-ktx:2.2.1.2")
implementation("com.pi4j:pi4j-ktx:2.3.0")
implementation("com.pi4j:pi4j-core:2.2.1")
implementation("com.pi4j:pi4j-plugin-raspberrypi:2.2.1")
implementation("com.pi4j:pi4j-plugin-pigpio:2.2.1")
implementation("com.pi4j:pi4j-plugin-linuxfs:2.2.1")
implementation("com.pi4j:pi4j-plugin-mock:2.2.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3")
implementation("org.slf4j:slf4j-api:1.7.32")
implementation("org.slf4j:slf4j-simple:1.7.32")
testImplementation(kotlin("test"))
Expand Down
66 changes: 66 additions & 0 deletions example/src/main/kotlin/CoroutinesExample.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import com.pi4j.io.gpio.digital.DigitalState
import com.pi4j.io.gpio.digital.PullResistance
import com.pi4j.ktx.console
import com.pi4j.ktx.io.digital.digitalInput
import com.pi4j.ktx.io.digital.digitalOutput
import com.pi4j.ktx.io.digital.onLow
import com.pi4j.ktx.io.digital.piGpioProvider
import com.pi4j.ktx.pi4jAsync
import kotlinx.coroutines.delay

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

private const val PIN_BUTTON = 24 // PIN 18 = BCM 24
private const val PIN_LED = 22 // PIN 15 = BCM 22
private var pressCount = 0

/**
* This application blinks a led and counts the number the button is pressed. The blink speed increases with each
* button press, and after 5 presses the application finishes.
*
* This example fully describes the basic usage of Pi4J-Kotlin + Coroutines
*
* @author Muhammad Hashim (mhashim6) (<a href="https://mhashim6.me">https://mhashim6.me</a>)
*/
fun main() {
pi4jAsync {
console {
digitalInput(PIN_BUTTON) {
id("button")
name("Press button")
pull(PullResistance.PULL_DOWN)
debounce(3000L)
piGpioProvider()
}.onLow {
pressCount++
+"Button was pressed for the ${pressCount}th time"
}

digitalOutput(PIN_LED) {
id("led")
name("LED Flasher")
shutdown(DigitalState.LOW)
initial(DigitalState.LOW)
piGpioProvider()
}.run {
while (pressCount < 5) {
+"LED ${state()}"
toggle()
delay(500L / (pressCount + 1))
}
}
}
}
}
85 changes: 85 additions & 0 deletions example/src/main/kotlin/I2CExample.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import com.pi4j.ktx.console
import com.pi4j.ktx.io.i2c
import com.pi4j.ktx.io.linuxFsI2CProvider
import com.pi4j.ktx.io.setPin
import com.pi4j.ktx.pi4j
import com.pi4j.ktx.utils.binStr
import java.lang.Thread.sleep

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


private const val TCA9534_REG_ADDR_OUT_PORT: Int = 0x01
private const val TCA9534_REG_ADDR_CFG: Int = 0x03

/**
* @author Muhammad Hashim (mhashim6) (<a href="https://mhashim6.me">https://mhashim6.me</a>) on 28/12/2022
*/
fun main() {
pi4j {
i2c(1, 0x3f) {
id("TCA9534")
linuxFsI2CProvider()
}.use { tca9534Dev ->
val config = tca9534Dev.readRegister(TCA9534_REG_ADDR_CFG)
check(config >= 0) {
"Failed to read configuration from address 0x${"%02x".format(TCA9534_REG_ADDR_CFG)}"
}

var currentState = tca9534Dev.readRegister(TCA9534_REG_ADDR_OUT_PORT)
if (config != 0x00) {
println(
"TCA9534 is not configured as OUTPUT, setting register 0x${"%02x".format(TCA9534_REG_ADDR_CFG)} to 0x00"
)
currentState = 0x00
tca9534Dev.writeRegister(TCA9534_REG_ADDR_OUT_PORT, currentState)
tca9534Dev.writeRegister(TCA9534_REG_ADDR_CFG, 0x00)
}

tca9534Dev.run {
// bit 8, is pin 1 on the board itself, so set pins in reverse:
console {
currentState = setPin(currentState, 8, TCA9534_REG_ADDR_OUT_PORT)
+"Setting TCA9534 to new state ${currentState.binStr()}"
sleep(500L)
currentState = setPin(currentState, 8, TCA9534_REG_ADDR_OUT_PORT, false)
+"Setting TCA9534 to new state ${currentState.binStr()}"
sleep(500L)
currentState = setPin(currentState, 7, TCA9534_REG_ADDR_OUT_PORT)
+"Setting TCA9534 to new state ${currentState.binStr()}"
sleep(500L)
currentState = setPin(currentState, 7, TCA9534_REG_ADDR_OUT_PORT, false)
+"Setting TCA9534 to new state ${currentState.binStr()}"
sleep(500L)
}
}
}
}

}
1 change: 1 addition & 0 deletions lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies {
compileOnly("org.slf4j:slf4j-api:1.7.32")
testImplementation("org.slf4j:slf4j-api:1.7.32")
compileOnly("org.slf4j:slf4j-simple:1.7.32")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
testImplementation("org.slf4j:slf4j-simple:1.7.32")
testImplementation(kotlin("test"))
}
Expand Down
29 changes: 28 additions & 1 deletion lib/src/main/kotlin/com/pi4j/ktx/Context.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import com.pi4j.context.ContextBuilder
import com.pi4j.io.IO
import com.pi4j.platform.Platform
import com.pi4j.provider.Provider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import java.io.File
import java.io.InputStream
import java.io.Reader
Expand All @@ -33,26 +37,31 @@ import java.util.*
annotation class ContextBuilderMarker

@ContextBuilderMarker
class KontextBuilder: ContextBuilder by ContextBuilder.newInstance() {
class KontextBuilder : ContextBuilder by ContextBuilder.newInstance() {
operator fun Platform.unaryPlus() {
add(this)
}

operator fun Provider<out Provider<*, *, *>, out IO<*, *, *>, out Config<*>>?.unaryPlus() {
add(this)
}

operator fun Properties.unaryPlus() {
add(this)
}

operator fun Pair<String, String>.unaryPlus() {
addProperty(this.first, this.second)
}

operator fun File.unaryPlus() {
addProperties(this)
}

operator fun Reader.unaryPlus() {
addProperties(this)
}

operator fun InputStream.unaryPlus() {
addProperties(this)
}
Expand All @@ -70,6 +79,24 @@ inline fun pi4j(block: Context.() -> Unit): Context {
return context
}

/**
* Coroutine variant of [pi4j]
*
* Creates a new [Context] using [Pi4J.newAutoContext] and uses it in execution.
* Automatically calls [Context.shutdown] after [block] execution
* @param scope within which the coroutines will run
* @param block runs on a [Context] Receiver
*/
fun pi4jAsync(scope: CoroutineScope = CoroutineScope(Dispatchers.IO), block: suspend Context.() -> Unit): Context {
return runBlocking {
pi4j {
scope.async {
block()
}.await()
}
}
}

inline fun buildContext(builder: KontextBuilder.() -> Unit): Context {
return KontextBuilder().run {
builder.invoke(this)
Expand Down
Loading